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 uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2432
 2433                        let server_id = self.get_or_insert_language_server(
 2434                            &worktree,
 2435                            delegate.clone(),
 2436                            disposition,
 2437                            &language_name,
 2438                            cx,
 2439                        );
 2440
 2441                        if let Some(state) = self.language_servers.get(&server_id)
 2442                            && let Ok(uri) = uri
 2443                        {
 2444                            state.add_workspace_folder(uri);
 2445                        };
 2446                        server_id
 2447                    }
 2448                })?;
 2449                let server_state = self.language_servers.get(&server_id)?;
 2450                if let LanguageServerState::Running {
 2451                    server, adapter, ..
 2452                } = server_state
 2453                {
 2454                    Some((server.clone(), adapter.clone()))
 2455                } else {
 2456                    None
 2457                }
 2458            })
 2459            .collect::<Vec<_>>();
 2460        for (server, adapter) in servers_and_adapters {
 2461            buffer_handle.update(cx, |buffer, cx| {
 2462                buffer.set_completion_triggers(
 2463                    server.server_id(),
 2464                    server
 2465                        .capabilities()
 2466                        .completion_provider
 2467                        .as_ref()
 2468                        .and_then(|provider| {
 2469                            provider
 2470                                .trigger_characters
 2471                                .as_ref()
 2472                                .map(|characters| characters.iter().cloned().collect())
 2473                        })
 2474                        .unwrap_or_default(),
 2475                    cx,
 2476                );
 2477            });
 2478
 2479            let snapshot = LspBufferSnapshot {
 2480                version: 0,
 2481                snapshot: initial_snapshot.clone(),
 2482            };
 2483
 2484            let mut registered = false;
 2485            self.buffer_snapshots
 2486                .entry(buffer_id)
 2487                .or_default()
 2488                .entry(server.server_id())
 2489                .or_insert_with(|| {
 2490                    registered = true;
 2491                    server.register_buffer(
 2492                        uri.clone(),
 2493                        adapter.language_id(&language.name()),
 2494                        0,
 2495                        initial_snapshot.text(),
 2496                    );
 2497
 2498                    vec![snapshot]
 2499                });
 2500
 2501            self.buffers_opened_in_servers
 2502                .entry(buffer_id)
 2503                .or_default()
 2504                .insert(server.server_id());
 2505            if registered {
 2506                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2507                    language_server_id: server.server_id(),
 2508                    name: None,
 2509                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2510                        proto::RegisteredForBuffer {
 2511                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2512                            buffer_id: buffer_id.to_proto(),
 2513                        },
 2514                    ),
 2515                });
 2516            }
 2517        }
 2518    }
 2519
 2520    fn reuse_existing_language_server<'lang_name>(
 2521        &self,
 2522        server_tree: &LanguageServerTree,
 2523        worktree: &Entity<Worktree>,
 2524        language_name: &'lang_name LanguageName,
 2525        cx: &mut App,
 2526    ) -> Option<(
 2527        Arc<LocalLspAdapterDelegate>,
 2528        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2529    )> {
 2530        if worktree.read(cx).is_visible() {
 2531            return None;
 2532        }
 2533
 2534        let worktree_store = self.worktree_store.read(cx);
 2535        let servers = server_tree
 2536            .instances
 2537            .iter()
 2538            .filter(|(worktree_id, _)| {
 2539                worktree_store
 2540                    .worktree_for_id(**worktree_id, cx)
 2541                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2542            })
 2543            .flat_map(|(worktree_id, servers)| {
 2544                servers
 2545                    .roots
 2546                    .iter()
 2547                    .flat_map(|(_, language_servers)| language_servers)
 2548                    .map(move |(_, (server_node, server_languages))| {
 2549                        (worktree_id, server_node, server_languages)
 2550                    })
 2551                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2552                    .map(|(worktree_id, server_node, _)| {
 2553                        (
 2554                            *worktree_id,
 2555                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2556                        )
 2557                    })
 2558            })
 2559            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2560                acc.entry(worktree_id)
 2561                    .or_insert_with(Vec::new)
 2562                    .push(server_node);
 2563                acc
 2564            })
 2565            .into_values()
 2566            .max_by_key(|servers| servers.len())?;
 2567
 2568        let worktree_id = worktree.read(cx).id();
 2569        let apply = move |tree: &mut LanguageServerTree| {
 2570            for server_node in &servers {
 2571                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2572            }
 2573            servers
 2574        };
 2575
 2576        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2577        Some((delegate, apply))
 2578    }
 2579
 2580    pub(crate) fn unregister_old_buffer_from_language_servers(
 2581        &mut self,
 2582        buffer: &Entity<Buffer>,
 2583        old_file: &File,
 2584        cx: &mut App,
 2585    ) {
 2586        let old_path = match old_file.as_local() {
 2587            Some(local) => local.abs_path(cx),
 2588            None => return,
 2589        };
 2590
 2591        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2592            debug_panic!("{old_path:?} is not parseable as an URI");
 2593            return;
 2594        };
 2595        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2596    }
 2597
 2598    pub(crate) fn unregister_buffer_from_language_servers(
 2599        &mut self,
 2600        buffer: &Entity<Buffer>,
 2601        file_url: &lsp::Uri,
 2602        cx: &mut App,
 2603    ) {
 2604        buffer.update(cx, |buffer, cx| {
 2605            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2606
 2607            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2608                language_server.unregister_buffer(file_url.clone());
 2609            }
 2610        });
 2611    }
 2612
 2613    fn buffer_snapshot_for_lsp_version(
 2614        &mut self,
 2615        buffer: &Entity<Buffer>,
 2616        server_id: LanguageServerId,
 2617        version: Option<i32>,
 2618        cx: &App,
 2619    ) -> Result<TextBufferSnapshot> {
 2620        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2621
 2622        if let Some(version) = version {
 2623            let buffer_id = buffer.read(cx).remote_id();
 2624            let snapshots = if let Some(snapshots) = self
 2625                .buffer_snapshots
 2626                .get_mut(&buffer_id)
 2627                .and_then(|m| m.get_mut(&server_id))
 2628            {
 2629                snapshots
 2630            } else if version == 0 {
 2631                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2632                // We detect this case and treat it as if the version was `None`.
 2633                return Ok(buffer.read(cx).text_snapshot());
 2634            } else {
 2635                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2636            };
 2637
 2638            let found_snapshot = snapshots
 2639                    .binary_search_by_key(&version, |e| e.version)
 2640                    .map(|ix| snapshots[ix].snapshot.clone())
 2641                    .map_err(|_| {
 2642                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2643                    })?;
 2644
 2645            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2646            Ok(found_snapshot)
 2647        } else {
 2648            Ok((buffer.read(cx)).text_snapshot())
 2649        }
 2650    }
 2651
 2652    async fn get_server_code_actions_from_action_kinds(
 2653        lsp_store: &WeakEntity<LspStore>,
 2654        language_server_id: LanguageServerId,
 2655        code_action_kinds: Vec<lsp::CodeActionKind>,
 2656        buffer: &Entity<Buffer>,
 2657        cx: &mut AsyncApp,
 2658    ) -> Result<Vec<CodeAction>> {
 2659        let actions = lsp_store
 2660            .update(cx, move |this, cx| {
 2661                let request = GetCodeActions {
 2662                    range: text::Anchor::MIN..text::Anchor::MAX,
 2663                    kinds: Some(code_action_kinds),
 2664                };
 2665                let server = LanguageServerToQuery::Other(language_server_id);
 2666                this.request_lsp(buffer.clone(), server, request, cx)
 2667            })?
 2668            .await?;
 2669        Ok(actions)
 2670    }
 2671
 2672    pub async fn execute_code_actions_on_server(
 2673        lsp_store: &WeakEntity<LspStore>,
 2674        language_server: &Arc<LanguageServer>,
 2675
 2676        actions: Vec<CodeAction>,
 2677        push_to_history: bool,
 2678        project_transaction: &mut ProjectTransaction,
 2679        cx: &mut AsyncApp,
 2680    ) -> anyhow::Result<()> {
 2681        for mut action in actions {
 2682            Self::try_resolve_code_action(language_server, &mut action)
 2683                .await
 2684                .context("resolving a formatting code action")?;
 2685
 2686            if let Some(edit) = action.lsp_action.edit() {
 2687                if edit.changes.is_none() && edit.document_changes.is_none() {
 2688                    continue;
 2689                }
 2690
 2691                let new = Self::deserialize_workspace_edit(
 2692                    lsp_store.upgrade().context("project dropped")?,
 2693                    edit.clone(),
 2694                    push_to_history,
 2695                    language_server.clone(),
 2696                    cx,
 2697                )
 2698                .await?;
 2699                project_transaction.0.extend(new.0);
 2700            }
 2701
 2702            if let Some(command) = action.lsp_action.command() {
 2703                let server_capabilities = language_server.capabilities();
 2704                let available_commands = server_capabilities
 2705                    .execute_command_provider
 2706                    .as_ref()
 2707                    .map(|options| options.commands.as_slice())
 2708                    .unwrap_or_default();
 2709                if available_commands.contains(&command.command) {
 2710                    lsp_store.update(cx, |lsp_store, _| {
 2711                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2712                            mode.last_workspace_edits_by_language_server
 2713                                .remove(&language_server.server_id());
 2714                        }
 2715                    })?;
 2716
 2717                    language_server
 2718                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2719                            command: command.command.clone(),
 2720                            arguments: command.arguments.clone().unwrap_or_default(),
 2721                            ..Default::default()
 2722                        })
 2723                        .await
 2724                        .into_response()
 2725                        .context("execute command")?;
 2726
 2727                    lsp_store.update(cx, |this, _| {
 2728                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2729                            project_transaction.0.extend(
 2730                                mode.last_workspace_edits_by_language_server
 2731                                    .remove(&language_server.server_id())
 2732                                    .unwrap_or_default()
 2733                                    .0,
 2734                            )
 2735                        }
 2736                    })?;
 2737                } else {
 2738                    log::warn!(
 2739                        "Cannot execute a command {} not listed in the language server capabilities",
 2740                        command.command
 2741                    )
 2742                }
 2743            }
 2744        }
 2745        Ok(())
 2746    }
 2747
 2748    pub async fn deserialize_text_edits(
 2749        this: Entity<LspStore>,
 2750        buffer_to_edit: Entity<Buffer>,
 2751        edits: Vec<lsp::TextEdit>,
 2752        push_to_history: bool,
 2753        _: Arc<CachedLspAdapter>,
 2754        language_server: Arc<LanguageServer>,
 2755        cx: &mut AsyncApp,
 2756    ) -> Result<Option<Transaction>> {
 2757        let edits = this
 2758            .update(cx, |this, cx| {
 2759                this.as_local_mut().unwrap().edits_from_lsp(
 2760                    &buffer_to_edit,
 2761                    edits,
 2762                    language_server.server_id(),
 2763                    None,
 2764                    cx,
 2765                )
 2766            })?
 2767            .await?;
 2768
 2769        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2770            buffer.finalize_last_transaction();
 2771            buffer.start_transaction();
 2772            for (range, text) in edits {
 2773                buffer.edit([(range, text)], None, cx);
 2774            }
 2775
 2776            if buffer.end_transaction(cx).is_some() {
 2777                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2778                if !push_to_history {
 2779                    buffer.forget_transaction(transaction.id);
 2780                }
 2781                Some(transaction)
 2782            } else {
 2783                None
 2784            }
 2785        })?;
 2786
 2787        Ok(transaction)
 2788    }
 2789
 2790    #[allow(clippy::type_complexity)]
 2791    pub(crate) fn edits_from_lsp(
 2792        &mut self,
 2793        buffer: &Entity<Buffer>,
 2794        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2795        server_id: LanguageServerId,
 2796        version: Option<i32>,
 2797        cx: &mut Context<LspStore>,
 2798    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2799        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2800        cx.background_spawn(async move {
 2801            let snapshot = snapshot?;
 2802            let mut lsp_edits = lsp_edits
 2803                .into_iter()
 2804                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2805                .collect::<Vec<_>>();
 2806
 2807            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2808
 2809            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2810            let mut edits = Vec::new();
 2811            while let Some((range, mut new_text)) = lsp_edits.next() {
 2812                // Clip invalid ranges provided by the language server.
 2813                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2814                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2815
 2816                // Combine any LSP edits that are adjacent.
 2817                //
 2818                // Also, combine LSP edits that are separated from each other by only
 2819                // a newline. This is important because for some code actions,
 2820                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2821                // are separated by unchanged newline characters.
 2822                //
 2823                // In order for the diffing logic below to work properly, any edits that
 2824                // cancel each other out must be combined into one.
 2825                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2826                    if next_range.start.0 > range.end {
 2827                        if next_range.start.0.row > range.end.row + 1
 2828                            || next_range.start.0.column > 0
 2829                            || snapshot.clip_point_utf16(
 2830                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2831                                Bias::Left,
 2832                            ) > range.end
 2833                        {
 2834                            break;
 2835                        }
 2836                        new_text.push('\n');
 2837                    }
 2838                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2839                    new_text.push_str(next_text);
 2840                    lsp_edits.next();
 2841                }
 2842
 2843                // For multiline edits, perform a diff of the old and new text so that
 2844                // we can identify the changes more precisely, preserving the locations
 2845                // of any anchors positioned in the unchanged regions.
 2846                if range.end.row > range.start.row {
 2847                    let offset = range.start.to_offset(&snapshot);
 2848                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2849                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2850                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2851                        (
 2852                            snapshot.anchor_after(offset + range.start)
 2853                                ..snapshot.anchor_before(offset + range.end),
 2854                            replacement,
 2855                        )
 2856                    }));
 2857                } else if range.end == range.start {
 2858                    let anchor = snapshot.anchor_after(range.start);
 2859                    edits.push((anchor..anchor, new_text.into()));
 2860                } else {
 2861                    let edit_start = snapshot.anchor_after(range.start);
 2862                    let edit_end = snapshot.anchor_before(range.end);
 2863                    edits.push((edit_start..edit_end, new_text.into()));
 2864                }
 2865            }
 2866
 2867            Ok(edits)
 2868        })
 2869    }
 2870
 2871    pub(crate) async fn deserialize_workspace_edit(
 2872        this: Entity<LspStore>,
 2873        edit: lsp::WorkspaceEdit,
 2874        push_to_history: bool,
 2875        language_server: Arc<LanguageServer>,
 2876        cx: &mut AsyncApp,
 2877    ) -> Result<ProjectTransaction> {
 2878        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2879
 2880        let mut operations = Vec::new();
 2881        if let Some(document_changes) = edit.document_changes {
 2882            match document_changes {
 2883                lsp::DocumentChanges::Edits(edits) => {
 2884                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2885                }
 2886                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2887            }
 2888        } else if let Some(changes) = edit.changes {
 2889            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2890                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2891                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2892                        uri,
 2893                        version: None,
 2894                    },
 2895                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2896                })
 2897            }));
 2898        }
 2899
 2900        let mut project_transaction = ProjectTransaction::default();
 2901        for operation in operations {
 2902            match operation {
 2903                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2904                    let abs_path = op
 2905                        .uri
 2906                        .to_file_path()
 2907                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2908
 2909                    if let Some(parent_path) = abs_path.parent() {
 2910                        fs.create_dir(parent_path).await?;
 2911                    }
 2912                    if abs_path.ends_with("/") {
 2913                        fs.create_dir(&abs_path).await?;
 2914                    } else {
 2915                        fs.create_file(
 2916                            &abs_path,
 2917                            op.options
 2918                                .map(|options| fs::CreateOptions {
 2919                                    overwrite: options.overwrite.unwrap_or(false),
 2920                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2921                                })
 2922                                .unwrap_or_default(),
 2923                        )
 2924                        .await?;
 2925                    }
 2926                }
 2927
 2928                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2929                    let source_abs_path = op
 2930                        .old_uri
 2931                        .to_file_path()
 2932                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2933                    let target_abs_path = op
 2934                        .new_uri
 2935                        .to_file_path()
 2936                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2937                    fs.rename(
 2938                        &source_abs_path,
 2939                        &target_abs_path,
 2940                        op.options
 2941                            .map(|options| fs::RenameOptions {
 2942                                overwrite: options.overwrite.unwrap_or(false),
 2943                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2944                            })
 2945                            .unwrap_or_default(),
 2946                    )
 2947                    .await?;
 2948                }
 2949
 2950                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 2951                    let abs_path = op
 2952                        .uri
 2953                        .to_file_path()
 2954                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2955                    let options = op
 2956                        .options
 2957                        .map(|options| fs::RemoveOptions {
 2958                            recursive: options.recursive.unwrap_or(false),
 2959                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 2960                        })
 2961                        .unwrap_or_default();
 2962                    if abs_path.ends_with("/") {
 2963                        fs.remove_dir(&abs_path, options).await?;
 2964                    } else {
 2965                        fs.remove_file(&abs_path, options).await?;
 2966                    }
 2967                }
 2968
 2969                lsp::DocumentChangeOperation::Edit(op) => {
 2970                    let buffer_to_edit = this
 2971                        .update(cx, |this, cx| {
 2972                            this.open_local_buffer_via_lsp(
 2973                                op.text_document.uri.clone(),
 2974                                language_server.server_id(),
 2975                                cx,
 2976                            )
 2977                        })?
 2978                        .await?;
 2979
 2980                    let edits = this
 2981                        .update(cx, |this, cx| {
 2982                            let path = buffer_to_edit.read(cx).project_path(cx);
 2983                            let active_entry = this.active_entry;
 2984                            let is_active_entry = path.is_some_and(|project_path| {
 2985                                this.worktree_store
 2986                                    .read(cx)
 2987                                    .entry_for_path(&project_path, cx)
 2988                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 2989                            });
 2990                            let local = this.as_local_mut().unwrap();
 2991
 2992                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 2993                            for edit in op.edits {
 2994                                match edit {
 2995                                    Edit::Plain(edit) => {
 2996                                        if !edits.contains(&edit) {
 2997                                            edits.push(edit)
 2998                                        }
 2999                                    }
 3000                                    Edit::Annotated(edit) => {
 3001                                        if !edits.contains(&edit.text_edit) {
 3002                                            edits.push(edit.text_edit)
 3003                                        }
 3004                                    }
 3005                                    Edit::Snippet(edit) => {
 3006                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3007                                        else {
 3008                                            continue;
 3009                                        };
 3010
 3011                                        if is_active_entry {
 3012                                            snippet_edits.push((edit.range, snippet));
 3013                                        } else {
 3014                                            // Since this buffer is not focused, apply a normal edit.
 3015                                            let new_edit = TextEdit {
 3016                                                range: edit.range,
 3017                                                new_text: snippet.text,
 3018                                            };
 3019                                            if !edits.contains(&new_edit) {
 3020                                                edits.push(new_edit);
 3021                                            }
 3022                                        }
 3023                                    }
 3024                                }
 3025                            }
 3026                            if !snippet_edits.is_empty() {
 3027                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3028                                let version = if let Some(buffer_version) = op.text_document.version
 3029                                {
 3030                                    local
 3031                                        .buffer_snapshot_for_lsp_version(
 3032                                            &buffer_to_edit,
 3033                                            language_server.server_id(),
 3034                                            Some(buffer_version),
 3035                                            cx,
 3036                                        )
 3037                                        .ok()
 3038                                        .map(|snapshot| snapshot.version)
 3039                                } else {
 3040                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3041                                };
 3042
 3043                                let most_recent_edit =
 3044                                    version.and_then(|version| version.most_recent());
 3045                                // Check if the edit that triggered that edit has been made by this participant.
 3046
 3047                                if let Some(most_recent_edit) = most_recent_edit {
 3048                                    cx.emit(LspStoreEvent::SnippetEdit {
 3049                                        buffer_id,
 3050                                        edits: snippet_edits,
 3051                                        most_recent_edit,
 3052                                    });
 3053                                }
 3054                            }
 3055
 3056                            local.edits_from_lsp(
 3057                                &buffer_to_edit,
 3058                                edits,
 3059                                language_server.server_id(),
 3060                                op.text_document.version,
 3061                                cx,
 3062                            )
 3063                        })?
 3064                        .await?;
 3065
 3066                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3067                        buffer.finalize_last_transaction();
 3068                        buffer.start_transaction();
 3069                        for (range, text) in edits {
 3070                            buffer.edit([(range, text)], None, cx);
 3071                        }
 3072
 3073                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3074                            if push_to_history {
 3075                                buffer.finalize_last_transaction();
 3076                                buffer.get_transaction(transaction_id).cloned()
 3077                            } else {
 3078                                buffer.forget_transaction(transaction_id)
 3079                            }
 3080                        })
 3081                    })?;
 3082                    if let Some(transaction) = transaction {
 3083                        project_transaction.0.insert(buffer_to_edit, transaction);
 3084                    }
 3085                }
 3086            }
 3087        }
 3088
 3089        Ok(project_transaction)
 3090    }
 3091
 3092    async fn on_lsp_workspace_edit(
 3093        this: WeakEntity<LspStore>,
 3094        params: lsp::ApplyWorkspaceEditParams,
 3095        server_id: LanguageServerId,
 3096        cx: &mut AsyncApp,
 3097    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3098        let this = this.upgrade().context("project project closed")?;
 3099        let language_server = this
 3100            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3101            .context("language server not found")?;
 3102        let transaction = Self::deserialize_workspace_edit(
 3103            this.clone(),
 3104            params.edit,
 3105            true,
 3106            language_server.clone(),
 3107            cx,
 3108        )
 3109        .await
 3110        .log_err();
 3111        this.update(cx, |this, _| {
 3112            if let Some(transaction) = transaction {
 3113                this.as_local_mut()
 3114                    .unwrap()
 3115                    .last_workspace_edits_by_language_server
 3116                    .insert(server_id, transaction);
 3117            }
 3118        })?;
 3119        Ok(lsp::ApplyWorkspaceEditResponse {
 3120            applied: true,
 3121            failed_change: None,
 3122            failure_reason: None,
 3123        })
 3124    }
 3125
 3126    fn remove_worktree(
 3127        &mut self,
 3128        id_to_remove: WorktreeId,
 3129        cx: &mut Context<LspStore>,
 3130    ) -> Vec<LanguageServerId> {
 3131        self.diagnostics.remove(&id_to_remove);
 3132        self.prettier_store.update(cx, |prettier_store, cx| {
 3133            prettier_store.remove_worktree(id_to_remove, cx);
 3134        });
 3135
 3136        let mut servers_to_remove = BTreeSet::default();
 3137        let mut servers_to_preserve = HashSet::default();
 3138        for (seed, state) in &self.language_server_ids {
 3139            if seed.worktree_id == id_to_remove {
 3140                servers_to_remove.insert(state.id);
 3141            } else {
 3142                servers_to_preserve.insert(state.id);
 3143            }
 3144        }
 3145        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3146        self.language_server_ids
 3147            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3148        for server_id_to_remove in &servers_to_remove {
 3149            self.language_server_watched_paths
 3150                .remove(server_id_to_remove);
 3151            self.language_server_paths_watched_for_rename
 3152                .remove(server_id_to_remove);
 3153            self.last_workspace_edits_by_language_server
 3154                .remove(server_id_to_remove);
 3155            self.language_servers.remove(server_id_to_remove);
 3156            self.buffer_pull_diagnostics_result_ids
 3157                .remove(server_id_to_remove);
 3158            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3159                buffer_servers.remove(server_id_to_remove);
 3160            }
 3161            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3162        }
 3163        servers_to_remove.into_iter().collect()
 3164    }
 3165
 3166    fn rebuild_watched_paths_inner<'a>(
 3167        &'a self,
 3168        language_server_id: LanguageServerId,
 3169        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3170        cx: &mut Context<LspStore>,
 3171    ) -> LanguageServerWatchedPathsBuilder {
 3172        let worktrees = self
 3173            .worktree_store
 3174            .read(cx)
 3175            .worktrees()
 3176            .filter_map(|worktree| {
 3177                self.language_servers_for_worktree(worktree.read(cx).id())
 3178                    .find(|server| server.server_id() == language_server_id)
 3179                    .map(|_| worktree)
 3180            })
 3181            .collect::<Vec<_>>();
 3182
 3183        let mut worktree_globs = HashMap::default();
 3184        let mut abs_globs = HashMap::default();
 3185        log::trace!(
 3186            "Processing new watcher paths for language server with id {}",
 3187            language_server_id
 3188        );
 3189
 3190        for watcher in watchers {
 3191            if let Some((worktree, literal_prefix, pattern)) =
 3192                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3193            {
 3194                worktree.update(cx, |worktree, _| {
 3195                    if let Some((tree, glob)) =
 3196                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3197                    {
 3198                        tree.add_path_prefix_to_scan(literal_prefix);
 3199                        worktree_globs
 3200                            .entry(tree.id())
 3201                            .or_insert_with(GlobSetBuilder::new)
 3202                            .add(glob);
 3203                    }
 3204                });
 3205            } else {
 3206                let (path, pattern) = match &watcher.glob_pattern {
 3207                    lsp::GlobPattern::String(s) => {
 3208                        let watcher_path = SanitizedPath::new(s);
 3209                        let path = glob_literal_prefix(watcher_path.as_path());
 3210                        let pattern = watcher_path
 3211                            .as_path()
 3212                            .strip_prefix(&path)
 3213                            .map(|p| p.to_string_lossy().into_owned())
 3214                            .unwrap_or_else(|e| {
 3215                                debug_panic!(
 3216                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3217                                    s,
 3218                                    path.display(),
 3219                                    e
 3220                                );
 3221                                watcher_path.as_path().to_string_lossy().into_owned()
 3222                            });
 3223                        (path, pattern)
 3224                    }
 3225                    lsp::GlobPattern::Relative(rp) => {
 3226                        let Ok(mut base_uri) = match &rp.base_uri {
 3227                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3228                            lsp::OneOf::Right(base_uri) => base_uri,
 3229                        }
 3230                        .to_file_path() else {
 3231                            continue;
 3232                        };
 3233
 3234                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3235                        let pattern = Path::new(&rp.pattern)
 3236                            .strip_prefix(&path)
 3237                            .map(|p| p.to_string_lossy().into_owned())
 3238                            .unwrap_or_else(|e| {
 3239                                debug_panic!(
 3240                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3241                                    rp.pattern,
 3242                                    path.display(),
 3243                                    e
 3244                                );
 3245                                rp.pattern.clone()
 3246                            });
 3247                        base_uri.push(path);
 3248                        (base_uri, pattern)
 3249                    }
 3250                };
 3251
 3252                if let Some(glob) = Glob::new(&pattern).log_err() {
 3253                    if !path
 3254                        .components()
 3255                        .any(|c| matches!(c, path::Component::Normal(_)))
 3256                    {
 3257                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3258                        // rather than adding a new watcher for `/`.
 3259                        for worktree in &worktrees {
 3260                            worktree_globs
 3261                                .entry(worktree.read(cx).id())
 3262                                .or_insert_with(GlobSetBuilder::new)
 3263                                .add(glob.clone());
 3264                        }
 3265                    } else {
 3266                        abs_globs
 3267                            .entry(path.into())
 3268                            .or_insert_with(GlobSetBuilder::new)
 3269                            .add(glob);
 3270                    }
 3271                }
 3272            }
 3273        }
 3274
 3275        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3276        for (worktree_id, builder) in worktree_globs {
 3277            if let Ok(globset) = builder.build() {
 3278                watch_builder.watch_worktree(worktree_id, globset);
 3279            }
 3280        }
 3281        for (abs_path, builder) in abs_globs {
 3282            if let Ok(globset) = builder.build() {
 3283                watch_builder.watch_abs_path(abs_path, globset);
 3284            }
 3285        }
 3286        watch_builder
 3287    }
 3288
 3289    fn worktree_and_path_for_file_watcher(
 3290        worktrees: &[Entity<Worktree>],
 3291        watcher: &FileSystemWatcher,
 3292        cx: &App,
 3293    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3294        worktrees.iter().find_map(|worktree| {
 3295            let tree = worktree.read(cx);
 3296            let worktree_root_path = tree.abs_path();
 3297            let path_style = tree.path_style();
 3298            match &watcher.glob_pattern {
 3299                lsp::GlobPattern::String(s) => {
 3300                    let watcher_path = SanitizedPath::new(s);
 3301                    let relative = watcher_path
 3302                        .as_path()
 3303                        .strip_prefix(&worktree_root_path)
 3304                        .ok()?;
 3305                    let literal_prefix = glob_literal_prefix(relative);
 3306                    Some((
 3307                        worktree.clone(),
 3308                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3309                        relative.to_string_lossy().into_owned(),
 3310                    ))
 3311                }
 3312                lsp::GlobPattern::Relative(rp) => {
 3313                    let base_uri = match &rp.base_uri {
 3314                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3315                        lsp::OneOf::Right(base_uri) => base_uri,
 3316                    }
 3317                    .to_file_path()
 3318                    .ok()?;
 3319                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3320                    let mut literal_prefix = relative.to_owned();
 3321                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3322                    Some((
 3323                        worktree.clone(),
 3324                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3325                        rp.pattern.clone(),
 3326                    ))
 3327                }
 3328            }
 3329        })
 3330    }
 3331
 3332    fn rebuild_watched_paths(
 3333        &mut self,
 3334        language_server_id: LanguageServerId,
 3335        cx: &mut Context<LspStore>,
 3336    ) {
 3337        let Some(registrations) = self
 3338            .language_server_dynamic_registrations
 3339            .get(&language_server_id)
 3340        else {
 3341            return;
 3342        };
 3343
 3344        let watch_builder = self.rebuild_watched_paths_inner(
 3345            language_server_id,
 3346            registrations.did_change_watched_files.values().flatten(),
 3347            cx,
 3348        );
 3349        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3350        self.language_server_watched_paths
 3351            .insert(language_server_id, watcher);
 3352
 3353        cx.notify();
 3354    }
 3355
 3356    fn on_lsp_did_change_watched_files(
 3357        &mut self,
 3358        language_server_id: LanguageServerId,
 3359        registration_id: &str,
 3360        params: DidChangeWatchedFilesRegistrationOptions,
 3361        cx: &mut Context<LspStore>,
 3362    ) {
 3363        let registrations = self
 3364            .language_server_dynamic_registrations
 3365            .entry(language_server_id)
 3366            .or_default();
 3367
 3368        registrations
 3369            .did_change_watched_files
 3370            .insert(registration_id.to_string(), params.watchers);
 3371
 3372        self.rebuild_watched_paths(language_server_id, cx);
 3373    }
 3374
 3375    fn on_lsp_unregister_did_change_watched_files(
 3376        &mut self,
 3377        language_server_id: LanguageServerId,
 3378        registration_id: &str,
 3379        cx: &mut Context<LspStore>,
 3380    ) {
 3381        let registrations = self
 3382            .language_server_dynamic_registrations
 3383            .entry(language_server_id)
 3384            .or_default();
 3385
 3386        if registrations
 3387            .did_change_watched_files
 3388            .remove(registration_id)
 3389            .is_some()
 3390        {
 3391            log::info!(
 3392                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3393                language_server_id,
 3394                registration_id
 3395            );
 3396        } else {
 3397            log::warn!(
 3398                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3399                language_server_id,
 3400                registration_id
 3401            );
 3402        }
 3403
 3404        self.rebuild_watched_paths(language_server_id, cx);
 3405    }
 3406
 3407    async fn initialization_options_for_adapter(
 3408        adapter: Arc<dyn LspAdapter>,
 3409        delegate: &Arc<dyn LspAdapterDelegate>,
 3410    ) -> Result<Option<serde_json::Value>> {
 3411        let Some(mut initialization_config) =
 3412            adapter.clone().initialization_options(delegate).await?
 3413        else {
 3414            return Ok(None);
 3415        };
 3416
 3417        for other_adapter in delegate.registered_lsp_adapters() {
 3418            if other_adapter.name() == adapter.name() {
 3419                continue;
 3420            }
 3421            if let Ok(Some(target_config)) = other_adapter
 3422                .clone()
 3423                .additional_initialization_options(adapter.name(), delegate)
 3424                .await
 3425            {
 3426                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3427            }
 3428        }
 3429
 3430        Ok(Some(initialization_config))
 3431    }
 3432
 3433    async fn workspace_configuration_for_adapter(
 3434        adapter: Arc<dyn LspAdapter>,
 3435        delegate: &Arc<dyn LspAdapterDelegate>,
 3436        toolchain: Option<Toolchain>,
 3437        cx: &mut AsyncApp,
 3438    ) -> Result<serde_json::Value> {
 3439        let mut workspace_config = adapter
 3440            .clone()
 3441            .workspace_configuration(delegate, toolchain, cx)
 3442            .await?;
 3443
 3444        for other_adapter in delegate.registered_lsp_adapters() {
 3445            if other_adapter.name() == adapter.name() {
 3446                continue;
 3447            }
 3448            if let Ok(Some(target_config)) = other_adapter
 3449                .clone()
 3450                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3451                .await
 3452            {
 3453                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3454            }
 3455        }
 3456
 3457        Ok(workspace_config)
 3458    }
 3459
 3460    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3461        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3462            Some(server.clone())
 3463        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3464            Some(Arc::clone(server))
 3465        } else {
 3466            None
 3467        }
 3468    }
 3469}
 3470
 3471fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3472    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3473        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3474            language_server_id: server.server_id(),
 3475            name: Some(server.name()),
 3476            message: proto::update_language_server::Variant::MetadataUpdated(
 3477                proto::ServerMetadataUpdated {
 3478                    capabilities: Some(capabilities),
 3479                },
 3480            ),
 3481        });
 3482    }
 3483}
 3484
 3485#[derive(Debug)]
 3486pub struct FormattableBuffer {
 3487    handle: Entity<Buffer>,
 3488    abs_path: Option<PathBuf>,
 3489    env: Option<HashMap<String, String>>,
 3490    ranges: Option<Vec<Range<Anchor>>>,
 3491}
 3492
 3493pub struct RemoteLspStore {
 3494    upstream_client: Option<AnyProtoClient>,
 3495    upstream_project_id: u64,
 3496}
 3497
 3498pub(crate) enum LspStoreMode {
 3499    Local(LocalLspStore),   // ssh host and collab host
 3500    Remote(RemoteLspStore), // collab guest
 3501}
 3502
 3503impl LspStoreMode {
 3504    fn is_local(&self) -> bool {
 3505        matches!(self, LspStoreMode::Local(_))
 3506    }
 3507}
 3508
 3509pub struct LspStore {
 3510    mode: LspStoreMode,
 3511    last_formatting_failure: Option<String>,
 3512    downstream_client: Option<(AnyProtoClient, u64)>,
 3513    nonce: u128,
 3514    buffer_store: Entity<BufferStore>,
 3515    worktree_store: Entity<WorktreeStore>,
 3516    pub languages: Arc<LanguageRegistry>,
 3517    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3518    active_entry: Option<ProjectEntryId>,
 3519    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3520    _maintain_buffer_languages: Task<()>,
 3521    diagnostic_summaries:
 3522        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3523    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3524    lsp_data: HashMap<BufferId, BufferLspData>,
 3525    next_hint_id: Arc<AtomicUsize>,
 3526}
 3527
 3528#[derive(Debug)]
 3529pub struct BufferLspData {
 3530    buffer_version: Global,
 3531    document_colors: Option<DocumentColorData>,
 3532    code_lens: Option<CodeLensData>,
 3533    inlay_hints: BufferInlayHints,
 3534    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3535    chunk_lsp_requests: HashMap<LspKey, HashMap<BufferChunk, LspRequestId>>,
 3536}
 3537
 3538#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3539struct LspKey {
 3540    request_type: TypeId,
 3541    server_queried: Option<LanguageServerId>,
 3542}
 3543
 3544impl BufferLspData {
 3545    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3546        Self {
 3547            buffer_version: buffer.read(cx).version(),
 3548            document_colors: None,
 3549            code_lens: None,
 3550            inlay_hints: BufferInlayHints::new(buffer, cx),
 3551            lsp_requests: HashMap::default(),
 3552            chunk_lsp_requests: HashMap::default(),
 3553        }
 3554    }
 3555
 3556    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3557        if let Some(document_colors) = &mut self.document_colors {
 3558            document_colors.colors.remove(&for_server);
 3559            document_colors.cache_version += 1;
 3560        }
 3561
 3562        if let Some(code_lens) = &mut self.code_lens {
 3563            code_lens.lens.remove(&for_server);
 3564        }
 3565
 3566        self.inlay_hints.remove_server_data(for_server);
 3567    }
 3568
 3569    #[cfg(any(test, feature = "test-support"))]
 3570    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3571        &self.inlay_hints
 3572    }
 3573}
 3574
 3575#[derive(Debug, Default, Clone)]
 3576pub struct DocumentColors {
 3577    pub colors: HashSet<DocumentColor>,
 3578    pub cache_version: Option<usize>,
 3579}
 3580
 3581type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3582type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3583
 3584#[derive(Debug, Default)]
 3585struct DocumentColorData {
 3586    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3587    cache_version: usize,
 3588    colors_update: Option<(Global, DocumentColorTask)>,
 3589}
 3590
 3591#[derive(Debug, Default)]
 3592struct CodeLensData {
 3593    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3594    update: Option<(Global, CodeLensTask)>,
 3595}
 3596
 3597#[derive(Debug)]
 3598pub enum LspStoreEvent {
 3599    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3600    LanguageServerRemoved(LanguageServerId),
 3601    LanguageServerUpdate {
 3602        language_server_id: LanguageServerId,
 3603        name: Option<LanguageServerName>,
 3604        message: proto::update_language_server::Variant,
 3605    },
 3606    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3607    LanguageServerPrompt(LanguageServerPromptRequest),
 3608    LanguageDetected {
 3609        buffer: Entity<Buffer>,
 3610        new_language: Option<Arc<Language>>,
 3611    },
 3612    Notification(String),
 3613    RefreshInlayHints(LanguageServerId),
 3614    RefreshCodeLens,
 3615    DiagnosticsUpdated {
 3616        server_id: LanguageServerId,
 3617        paths: Vec<ProjectPath>,
 3618    },
 3619    DiskBasedDiagnosticsStarted {
 3620        language_server_id: LanguageServerId,
 3621    },
 3622    DiskBasedDiagnosticsFinished {
 3623        language_server_id: LanguageServerId,
 3624    },
 3625    SnippetEdit {
 3626        buffer_id: BufferId,
 3627        edits: Vec<(lsp::Range, Snippet)>,
 3628        most_recent_edit: clock::Lamport,
 3629    },
 3630}
 3631
 3632#[derive(Clone, Debug, Serialize)]
 3633pub struct LanguageServerStatus {
 3634    pub name: LanguageServerName,
 3635    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 3636    pub has_pending_diagnostic_updates: bool,
 3637    progress_tokens: HashSet<String>,
 3638    pub worktree: Option<WorktreeId>,
 3639}
 3640
 3641#[derive(Clone, Debug)]
 3642struct CoreSymbol {
 3643    pub language_server_name: LanguageServerName,
 3644    pub source_worktree_id: WorktreeId,
 3645    pub source_language_server_id: LanguageServerId,
 3646    pub path: SymbolLocation,
 3647    pub name: String,
 3648    pub kind: lsp::SymbolKind,
 3649    pub range: Range<Unclipped<PointUtf16>>,
 3650}
 3651
 3652#[derive(Clone, Debug, PartialEq, Eq)]
 3653pub enum SymbolLocation {
 3654    InProject(ProjectPath),
 3655    OutsideProject {
 3656        abs_path: Arc<Path>,
 3657        signature: [u8; 32],
 3658    },
 3659}
 3660
 3661impl SymbolLocation {
 3662    fn file_name(&self) -> Option<&str> {
 3663        match self {
 3664            Self::InProject(path) => path.path.file_name(),
 3665            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3666        }
 3667    }
 3668}
 3669
 3670impl LspStore {
 3671    pub fn init(client: &AnyProtoClient) {
 3672        client.add_entity_request_handler(Self::handle_lsp_query);
 3673        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3674        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3675        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3676        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3677        client.add_entity_message_handler(Self::handle_start_language_server);
 3678        client.add_entity_message_handler(Self::handle_update_language_server);
 3679        client.add_entity_message_handler(Self::handle_language_server_log);
 3680        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3681        client.add_entity_request_handler(Self::handle_format_buffers);
 3682        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3683        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3684        client.add_entity_request_handler(Self::handle_apply_code_action);
 3685        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3686        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3687        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3688        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3689        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3690        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3691        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3692        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3693        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3694        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3695        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3696        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3697        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3698        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3699        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3700        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3701        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3702
 3703        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3704        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3705        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3706        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3707        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3708        client.add_entity_request_handler(
 3709            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3710        );
 3711        client.add_entity_request_handler(
 3712            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3713        );
 3714        client.add_entity_request_handler(
 3715            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3716        );
 3717    }
 3718
 3719    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3720        match &self.mode {
 3721            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3722            _ => None,
 3723        }
 3724    }
 3725
 3726    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3727        match &self.mode {
 3728            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3729            _ => None,
 3730        }
 3731    }
 3732
 3733    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3734        match &mut self.mode {
 3735            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3736            _ => None,
 3737        }
 3738    }
 3739
 3740    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3741        match &self.mode {
 3742            LspStoreMode::Remote(RemoteLspStore {
 3743                upstream_client: Some(upstream_client),
 3744                upstream_project_id,
 3745                ..
 3746            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3747
 3748            LspStoreMode::Remote(RemoteLspStore {
 3749                upstream_client: None,
 3750                ..
 3751            }) => None,
 3752            LspStoreMode::Local(_) => None,
 3753        }
 3754    }
 3755
 3756    pub fn new_local(
 3757        buffer_store: Entity<BufferStore>,
 3758        worktree_store: Entity<WorktreeStore>,
 3759        prettier_store: Entity<PrettierStore>,
 3760        toolchain_store: Entity<LocalToolchainStore>,
 3761        environment: Entity<ProjectEnvironment>,
 3762        manifest_tree: Entity<ManifestTree>,
 3763        languages: Arc<LanguageRegistry>,
 3764        http_client: Arc<dyn HttpClient>,
 3765        fs: Arc<dyn Fs>,
 3766        cx: &mut Context<Self>,
 3767    ) -> Self {
 3768        let yarn = YarnPathStore::new(fs.clone(), cx);
 3769        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3770            .detach();
 3771        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3772            .detach();
 3773        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3774            .detach();
 3775        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3776            .detach();
 3777        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3778            .detach();
 3779        subscribe_to_binary_statuses(&languages, cx).detach();
 3780
 3781        let _maintain_workspace_config = {
 3782            let (sender, receiver) = watch::channel();
 3783            (Self::maintain_workspace_config(receiver, cx), sender)
 3784        };
 3785
 3786        Self {
 3787            mode: LspStoreMode::Local(LocalLspStore {
 3788                weak: cx.weak_entity(),
 3789                worktree_store: worktree_store.clone(),
 3790
 3791                supplementary_language_servers: Default::default(),
 3792                languages: languages.clone(),
 3793                language_server_ids: Default::default(),
 3794                language_servers: Default::default(),
 3795                last_workspace_edits_by_language_server: Default::default(),
 3796                language_server_watched_paths: Default::default(),
 3797                language_server_paths_watched_for_rename: Default::default(),
 3798                language_server_dynamic_registrations: Default::default(),
 3799                buffers_being_formatted: Default::default(),
 3800                buffer_snapshots: Default::default(),
 3801                prettier_store,
 3802                environment,
 3803                http_client,
 3804                fs,
 3805                yarn,
 3806                next_diagnostic_group_id: Default::default(),
 3807                diagnostics: Default::default(),
 3808                _subscription: cx.on_app_quit(|this, cx| {
 3809                    this.as_local_mut()
 3810                        .unwrap()
 3811                        .shutdown_language_servers_on_quit(cx)
 3812                }),
 3813                lsp_tree: LanguageServerTree::new(
 3814                    manifest_tree,
 3815                    languages.clone(),
 3816                    toolchain_store.clone(),
 3817                ),
 3818                toolchain_store,
 3819                registered_buffers: HashMap::default(),
 3820                buffers_opened_in_servers: HashMap::default(),
 3821                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3822                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3823                    .manifest_file_names(),
 3824            }),
 3825            last_formatting_failure: None,
 3826            downstream_client: None,
 3827            buffer_store,
 3828            worktree_store,
 3829            languages: languages.clone(),
 3830            language_server_statuses: Default::default(),
 3831            nonce: StdRng::from_os_rng().random(),
 3832            diagnostic_summaries: HashMap::default(),
 3833            lsp_server_capabilities: HashMap::default(),
 3834            lsp_data: HashMap::default(),
 3835            next_hint_id: Arc::default(),
 3836            active_entry: None,
 3837            _maintain_workspace_config,
 3838            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3839        }
 3840    }
 3841
 3842    fn send_lsp_proto_request<R: LspCommand>(
 3843        &self,
 3844        buffer: Entity<Buffer>,
 3845        client: AnyProtoClient,
 3846        upstream_project_id: u64,
 3847        request: R,
 3848        cx: &mut Context<LspStore>,
 3849    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3850        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3851            return Task::ready(Ok(R::Response::default()));
 3852        }
 3853        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3854        cx.spawn(async move |this, cx| {
 3855            let response = client.request(message).await?;
 3856            let this = this.upgrade().context("project dropped")?;
 3857            request
 3858                .response_from_proto(response, this, buffer, cx.clone())
 3859                .await
 3860        })
 3861    }
 3862
 3863    pub(super) fn new_remote(
 3864        buffer_store: Entity<BufferStore>,
 3865        worktree_store: Entity<WorktreeStore>,
 3866        languages: Arc<LanguageRegistry>,
 3867        upstream_client: AnyProtoClient,
 3868        project_id: u64,
 3869        cx: &mut Context<Self>,
 3870    ) -> Self {
 3871        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3872            .detach();
 3873        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3874            .detach();
 3875        subscribe_to_binary_statuses(&languages, cx).detach();
 3876        let _maintain_workspace_config = {
 3877            let (sender, receiver) = watch::channel();
 3878            (Self::maintain_workspace_config(receiver, cx), sender)
 3879        };
 3880        Self {
 3881            mode: LspStoreMode::Remote(RemoteLspStore {
 3882                upstream_client: Some(upstream_client),
 3883                upstream_project_id: project_id,
 3884            }),
 3885            downstream_client: None,
 3886            last_formatting_failure: None,
 3887            buffer_store,
 3888            worktree_store,
 3889            languages: languages.clone(),
 3890            language_server_statuses: Default::default(),
 3891            nonce: StdRng::from_os_rng().random(),
 3892            diagnostic_summaries: HashMap::default(),
 3893            lsp_server_capabilities: HashMap::default(),
 3894            next_hint_id: Arc::default(),
 3895            lsp_data: HashMap::default(),
 3896            active_entry: None,
 3897
 3898            _maintain_workspace_config,
 3899            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3900        }
 3901    }
 3902
 3903    fn on_buffer_store_event(
 3904        &mut self,
 3905        _: Entity<BufferStore>,
 3906        event: &BufferStoreEvent,
 3907        cx: &mut Context<Self>,
 3908    ) {
 3909        match event {
 3910            BufferStoreEvent::BufferAdded(buffer) => {
 3911                self.on_buffer_added(buffer, cx).log_err();
 3912            }
 3913            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3914                let buffer_id = buffer.read(cx).remote_id();
 3915                if let Some(local) = self.as_local_mut()
 3916                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3917                {
 3918                    local.reset_buffer(buffer, old_file, cx);
 3919
 3920                    if local.registered_buffers.contains_key(&buffer_id) {
 3921                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3922                    }
 3923                }
 3924
 3925                self.detect_language_for_buffer(buffer, cx);
 3926                if let Some(local) = self.as_local_mut() {
 3927                    local.initialize_buffer(buffer, cx);
 3928                    if local.registered_buffers.contains_key(&buffer_id) {
 3929                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3930                    }
 3931                }
 3932            }
 3933            _ => {}
 3934        }
 3935    }
 3936
 3937    fn on_worktree_store_event(
 3938        &mut self,
 3939        _: Entity<WorktreeStore>,
 3940        event: &WorktreeStoreEvent,
 3941        cx: &mut Context<Self>,
 3942    ) {
 3943        match event {
 3944            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3945                if !worktree.read(cx).is_local() {
 3946                    return;
 3947                }
 3948                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3949                    worktree::Event::UpdatedEntries(changes) => {
 3950                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 3951                    }
 3952                    worktree::Event::UpdatedGitRepositories(_)
 3953                    | worktree::Event::DeletedEntry(_) => {}
 3954                })
 3955                .detach()
 3956            }
 3957            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 3958            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 3959                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 3960            }
 3961            WorktreeStoreEvent::WorktreeReleased(..)
 3962            | WorktreeStoreEvent::WorktreeOrderChanged
 3963            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 3964            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 3965            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 3966        }
 3967    }
 3968
 3969    fn on_prettier_store_event(
 3970        &mut self,
 3971        _: Entity<PrettierStore>,
 3972        event: &PrettierStoreEvent,
 3973        cx: &mut Context<Self>,
 3974    ) {
 3975        match event {
 3976            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 3977                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 3978            }
 3979            PrettierStoreEvent::LanguageServerAdded {
 3980                new_server_id,
 3981                name,
 3982                prettier_server,
 3983            } => {
 3984                self.register_supplementary_language_server(
 3985                    *new_server_id,
 3986                    name.clone(),
 3987                    prettier_server.clone(),
 3988                    cx,
 3989                );
 3990            }
 3991        }
 3992    }
 3993
 3994    fn on_toolchain_store_event(
 3995        &mut self,
 3996        _: Entity<LocalToolchainStore>,
 3997        event: &ToolchainStoreEvent,
 3998        _: &mut Context<Self>,
 3999    ) {
 4000        if let ToolchainStoreEvent::ToolchainActivated = event {
 4001            self.request_workspace_config_refresh()
 4002        }
 4003    }
 4004
 4005    fn request_workspace_config_refresh(&mut self) {
 4006        *self._maintain_workspace_config.1.borrow_mut() = ();
 4007    }
 4008
 4009    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4010        self.as_local().map(|local| local.prettier_store.clone())
 4011    }
 4012
 4013    fn on_buffer_event(
 4014        &mut self,
 4015        buffer: Entity<Buffer>,
 4016        event: &language::BufferEvent,
 4017        cx: &mut Context<Self>,
 4018    ) {
 4019        match event {
 4020            language::BufferEvent::Edited => {
 4021                self.on_buffer_edited(buffer, cx);
 4022            }
 4023
 4024            language::BufferEvent::Saved => {
 4025                self.on_buffer_saved(buffer, cx);
 4026            }
 4027
 4028            _ => {}
 4029        }
 4030    }
 4031
 4032    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4033        buffer
 4034            .read(cx)
 4035            .set_language_registry(self.languages.clone());
 4036
 4037        cx.subscribe(buffer, |this, buffer, event, cx| {
 4038            this.on_buffer_event(buffer, event, cx);
 4039        })
 4040        .detach();
 4041
 4042        self.detect_language_for_buffer(buffer, cx);
 4043        if let Some(local) = self.as_local_mut() {
 4044            local.initialize_buffer(buffer, cx);
 4045        }
 4046
 4047        Ok(())
 4048    }
 4049
 4050    pub(crate) fn register_buffer_with_language_servers(
 4051        &mut self,
 4052        buffer: &Entity<Buffer>,
 4053        only_register_servers: HashSet<LanguageServerSelector>,
 4054        ignore_refcounts: bool,
 4055        cx: &mut Context<Self>,
 4056    ) -> OpenLspBufferHandle {
 4057        let buffer_id = buffer.read(cx).remote_id();
 4058        let handle = cx.new(|_| buffer.clone());
 4059        if let Some(local) = self.as_local_mut() {
 4060            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4061            if !ignore_refcounts {
 4062                *refcount += 1;
 4063            }
 4064
 4065            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4066            // 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
 4067            // 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
 4068            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4069            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4070                return handle;
 4071            };
 4072            if !file.is_local() {
 4073                return handle;
 4074            }
 4075
 4076            if ignore_refcounts || *refcount == 1 {
 4077                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4078            }
 4079            if !ignore_refcounts {
 4080                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4081                    let refcount = {
 4082                        let local = lsp_store.as_local_mut().unwrap();
 4083                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4084                            debug_panic!("bad refcounting");
 4085                            return;
 4086                        };
 4087
 4088                        *refcount -= 1;
 4089                        *refcount
 4090                    };
 4091                    if refcount == 0 {
 4092                        lsp_store.lsp_data.remove(&buffer_id);
 4093                        let local = lsp_store.as_local_mut().unwrap();
 4094                        local.registered_buffers.remove(&buffer_id);
 4095                        local.buffers_opened_in_servers.remove(&buffer_id);
 4096                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4097                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4098                        }
 4099                    }
 4100                })
 4101                .detach();
 4102            }
 4103        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4104            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4105            cx.background_spawn(async move {
 4106                upstream_client
 4107                    .request(proto::RegisterBufferWithLanguageServers {
 4108                        project_id: upstream_project_id,
 4109                        buffer_id,
 4110                        only_servers: only_register_servers
 4111                            .into_iter()
 4112                            .map(|selector| {
 4113                                let selector = match selector {
 4114                                    LanguageServerSelector::Id(language_server_id) => {
 4115                                        proto::language_server_selector::Selector::ServerId(
 4116                                            language_server_id.to_proto(),
 4117                                        )
 4118                                    }
 4119                                    LanguageServerSelector::Name(language_server_name) => {
 4120                                        proto::language_server_selector::Selector::Name(
 4121                                            language_server_name.to_string(),
 4122                                        )
 4123                                    }
 4124                                };
 4125                                proto::LanguageServerSelector {
 4126                                    selector: Some(selector),
 4127                                }
 4128                            })
 4129                            .collect(),
 4130                    })
 4131                    .await
 4132            })
 4133            .detach();
 4134        } else {
 4135            panic!("oops!");
 4136        }
 4137        handle
 4138    }
 4139
 4140    fn maintain_buffer_languages(
 4141        languages: Arc<LanguageRegistry>,
 4142        cx: &mut Context<Self>,
 4143    ) -> Task<()> {
 4144        let mut subscription = languages.subscribe();
 4145        let mut prev_reload_count = languages.reload_count();
 4146        cx.spawn(async move |this, cx| {
 4147            while let Some(()) = subscription.next().await {
 4148                if let Some(this) = this.upgrade() {
 4149                    // If the language registry has been reloaded, then remove and
 4150                    // re-assign the languages on all open buffers.
 4151                    let reload_count = languages.reload_count();
 4152                    if reload_count > prev_reload_count {
 4153                        prev_reload_count = reload_count;
 4154                        this.update(cx, |this, cx| {
 4155                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4156                                for buffer in buffer_store.buffers() {
 4157                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4158                                    {
 4159                                        buffer
 4160                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4161                                        if let Some(local) = this.as_local_mut() {
 4162                                            local.reset_buffer(&buffer, &f, cx);
 4163
 4164                                            if local
 4165                                                .registered_buffers
 4166                                                .contains_key(&buffer.read(cx).remote_id())
 4167                                                && let Some(file_url) =
 4168                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4169                                            {
 4170                                                local.unregister_buffer_from_language_servers(
 4171                                                    &buffer, &file_url, cx,
 4172                                                );
 4173                                            }
 4174                                        }
 4175                                    }
 4176                                }
 4177                            });
 4178                        })
 4179                        .ok();
 4180                    }
 4181
 4182                    this.update(cx, |this, cx| {
 4183                        let mut plain_text_buffers = Vec::new();
 4184                        let mut buffers_with_unknown_injections = Vec::new();
 4185                        for handle in this.buffer_store.read(cx).buffers() {
 4186                            let buffer = handle.read(cx);
 4187                            if buffer.language().is_none()
 4188                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4189                            {
 4190                                plain_text_buffers.push(handle);
 4191                            } else if buffer.contains_unknown_injections() {
 4192                                buffers_with_unknown_injections.push(handle);
 4193                            }
 4194                        }
 4195
 4196                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4197                        // and reused later in the invisible worktrees.
 4198                        plain_text_buffers.sort_by_key(|buffer| {
 4199                            Reverse(
 4200                                File::from_dyn(buffer.read(cx).file())
 4201                                    .map(|file| file.worktree.read(cx).is_visible()),
 4202                            )
 4203                        });
 4204
 4205                        for buffer in plain_text_buffers {
 4206                            this.detect_language_for_buffer(&buffer, cx);
 4207                            if let Some(local) = this.as_local_mut() {
 4208                                local.initialize_buffer(&buffer, cx);
 4209                                if local
 4210                                    .registered_buffers
 4211                                    .contains_key(&buffer.read(cx).remote_id())
 4212                                {
 4213                                    local.register_buffer_with_language_servers(
 4214                                        &buffer,
 4215                                        HashSet::default(),
 4216                                        cx,
 4217                                    );
 4218                                }
 4219                            }
 4220                        }
 4221
 4222                        for buffer in buffers_with_unknown_injections {
 4223                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4224                        }
 4225                    })
 4226                    .ok();
 4227                }
 4228            }
 4229        })
 4230    }
 4231
 4232    fn detect_language_for_buffer(
 4233        &mut self,
 4234        buffer_handle: &Entity<Buffer>,
 4235        cx: &mut Context<Self>,
 4236    ) -> Option<language::AvailableLanguage> {
 4237        // If the buffer has a language, set it and start the language server if we haven't already.
 4238        let buffer = buffer_handle.read(cx);
 4239        let file = buffer.file()?;
 4240
 4241        let content = buffer.as_rope();
 4242        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4243        if let Some(available_language) = &available_language {
 4244            if let Some(Ok(Ok(new_language))) = self
 4245                .languages
 4246                .load_language(available_language)
 4247                .now_or_never()
 4248            {
 4249                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4250            }
 4251        } else {
 4252            cx.emit(LspStoreEvent::LanguageDetected {
 4253                buffer: buffer_handle.clone(),
 4254                new_language: None,
 4255            });
 4256        }
 4257
 4258        available_language
 4259    }
 4260
 4261    pub(crate) fn set_language_for_buffer(
 4262        &mut self,
 4263        buffer_entity: &Entity<Buffer>,
 4264        new_language: Arc<Language>,
 4265        cx: &mut Context<Self>,
 4266    ) {
 4267        let buffer = buffer_entity.read(cx);
 4268        let buffer_file = buffer.file().cloned();
 4269        let buffer_id = buffer.remote_id();
 4270        if let Some(local_store) = self.as_local_mut()
 4271            && local_store.registered_buffers.contains_key(&buffer_id)
 4272            && let Some(abs_path) =
 4273                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4274            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4275        {
 4276            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4277        }
 4278        buffer_entity.update(cx, |buffer, cx| {
 4279            if buffer
 4280                .language()
 4281                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4282            {
 4283                buffer.set_language(Some(new_language.clone()), cx);
 4284            }
 4285        });
 4286
 4287        let settings =
 4288            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4289        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4290
 4291        let worktree_id = if let Some(file) = buffer_file {
 4292            let worktree = file.worktree.clone();
 4293
 4294            if let Some(local) = self.as_local_mut()
 4295                && local.registered_buffers.contains_key(&buffer_id)
 4296            {
 4297                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4298            }
 4299            Some(worktree.read(cx).id())
 4300        } else {
 4301            None
 4302        };
 4303
 4304        if settings.prettier.allowed
 4305            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4306        {
 4307            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4308            if let Some(prettier_store) = prettier_store {
 4309                prettier_store.update(cx, |prettier_store, cx| {
 4310                    prettier_store.install_default_prettier(
 4311                        worktree_id,
 4312                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4313                        cx,
 4314                    )
 4315                })
 4316            }
 4317        }
 4318
 4319        cx.emit(LspStoreEvent::LanguageDetected {
 4320            buffer: buffer_entity.clone(),
 4321            new_language: Some(new_language),
 4322        })
 4323    }
 4324
 4325    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4326        self.buffer_store.clone()
 4327    }
 4328
 4329    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4330        self.active_entry = active_entry;
 4331    }
 4332
 4333    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4334        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4335            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4336        {
 4337            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4338                summaries
 4339                    .iter()
 4340                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4341            });
 4342            if let Some(summary) = summaries.next() {
 4343                client
 4344                    .send(proto::UpdateDiagnosticSummary {
 4345                        project_id: downstream_project_id,
 4346                        worktree_id: worktree.id().to_proto(),
 4347                        summary: Some(summary),
 4348                        more_summaries: summaries.collect(),
 4349                    })
 4350                    .log_err();
 4351            }
 4352        }
 4353    }
 4354
 4355    fn is_capable_for_proto_request<R>(
 4356        &self,
 4357        buffer: &Entity<Buffer>,
 4358        request: &R,
 4359        cx: &App,
 4360    ) -> bool
 4361    where
 4362        R: LspCommand,
 4363    {
 4364        self.check_if_capable_for_proto_request(
 4365            buffer,
 4366            |capabilities| {
 4367                request.check_capabilities(AdapterServerCapabilities {
 4368                    server_capabilities: capabilities.clone(),
 4369                    code_action_kinds: None,
 4370                })
 4371            },
 4372            cx,
 4373        )
 4374    }
 4375
 4376    fn check_if_capable_for_proto_request<F>(
 4377        &self,
 4378        buffer: &Entity<Buffer>,
 4379        check: F,
 4380        cx: &App,
 4381    ) -> bool
 4382    where
 4383        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4384    {
 4385        let Some(language) = buffer.read(cx).language().cloned() else {
 4386            return false;
 4387        };
 4388        let relevant_language_servers = self
 4389            .languages
 4390            .lsp_adapters(&language.name())
 4391            .into_iter()
 4392            .map(|lsp_adapter| lsp_adapter.name())
 4393            .collect::<HashSet<_>>();
 4394        self.language_server_statuses
 4395            .iter()
 4396            .filter_map(|(server_id, server_status)| {
 4397                relevant_language_servers
 4398                    .contains(&server_status.name)
 4399                    .then_some(server_id)
 4400            })
 4401            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4402            .any(check)
 4403    }
 4404
 4405    pub fn request_lsp<R>(
 4406        &mut self,
 4407        buffer: Entity<Buffer>,
 4408        server: LanguageServerToQuery,
 4409        request: R,
 4410        cx: &mut Context<Self>,
 4411    ) -> Task<Result<R::Response>>
 4412    where
 4413        R: LspCommand,
 4414        <R::LspRequest as lsp::request::Request>::Result: Send,
 4415        <R::LspRequest as lsp::request::Request>::Params: Send,
 4416    {
 4417        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4418            return self.send_lsp_proto_request(
 4419                buffer,
 4420                upstream_client,
 4421                upstream_project_id,
 4422                request,
 4423                cx,
 4424            );
 4425        }
 4426
 4427        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4428            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4429                local
 4430                    .language_servers_for_buffer(buffer, cx)
 4431                    .find(|(_, server)| {
 4432                        request.check_capabilities(server.adapter_server_capabilities())
 4433                    })
 4434                    .map(|(_, server)| server.clone())
 4435            }),
 4436            LanguageServerToQuery::Other(id) => self
 4437                .language_server_for_local_buffer(buffer, id, cx)
 4438                .and_then(|(_, server)| {
 4439                    request
 4440                        .check_capabilities(server.adapter_server_capabilities())
 4441                        .then(|| Arc::clone(server))
 4442                }),
 4443        }) else {
 4444            return Task::ready(Ok(Default::default()));
 4445        };
 4446
 4447        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4448
 4449        let Some(file) = file else {
 4450            return Task::ready(Ok(Default::default()));
 4451        };
 4452
 4453        let lsp_params = match request.to_lsp_params_or_response(
 4454            &file.abs_path(cx),
 4455            buffer.read(cx),
 4456            &language_server,
 4457            cx,
 4458        ) {
 4459            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4460            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4461
 4462            Err(err) => {
 4463                let message = format!(
 4464                    "{} via {} failed: {}",
 4465                    request.display_name(),
 4466                    language_server.name(),
 4467                    err
 4468                );
 4469                log::warn!("{message}");
 4470                return Task::ready(Err(anyhow!(message)));
 4471            }
 4472        };
 4473
 4474        let status = request.status();
 4475        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4476            return Task::ready(Ok(Default::default()));
 4477        }
 4478        cx.spawn(async move |this, cx| {
 4479            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4480
 4481            let id = lsp_request.id();
 4482            let _cleanup = if status.is_some() {
 4483                cx.update(|cx| {
 4484                    this.update(cx, |this, cx| {
 4485                        this.on_lsp_work_start(
 4486                            language_server.server_id(),
 4487                            id.to_string(),
 4488                            LanguageServerProgress {
 4489                                is_disk_based_diagnostics_progress: false,
 4490                                is_cancellable: false,
 4491                                title: None,
 4492                                message: status.clone(),
 4493                                percentage: None,
 4494                                last_update_at: cx.background_executor().now(),
 4495                            },
 4496                            cx,
 4497                        );
 4498                    })
 4499                })
 4500                .log_err();
 4501
 4502                Some(defer(|| {
 4503                    cx.update(|cx| {
 4504                        this.update(cx, |this, cx| {
 4505                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
 4506                        })
 4507                    })
 4508                    .log_err();
 4509                }))
 4510            } else {
 4511                None
 4512            };
 4513
 4514            let result = lsp_request.await.into_response();
 4515
 4516            let response = result.map_err(|err| {
 4517                let message = format!(
 4518                    "{} via {} failed: {}",
 4519                    request.display_name(),
 4520                    language_server.name(),
 4521                    err
 4522                );
 4523                log::warn!("{message}");
 4524                anyhow::anyhow!(message)
 4525            })?;
 4526
 4527            request
 4528                .response_from_lsp(
 4529                    response,
 4530                    this.upgrade().context("no app context")?,
 4531                    buffer,
 4532                    language_server.server_id(),
 4533                    cx.clone(),
 4534                )
 4535                .await
 4536        })
 4537    }
 4538
 4539    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4540        let mut language_formatters_to_check = Vec::new();
 4541        for buffer in self.buffer_store.read(cx).buffers() {
 4542            let buffer = buffer.read(cx);
 4543            let buffer_file = File::from_dyn(buffer.file());
 4544            let buffer_language = buffer.language();
 4545            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4546            if buffer_language.is_some() {
 4547                language_formatters_to_check.push((
 4548                    buffer_file.map(|f| f.worktree_id(cx)),
 4549                    settings.into_owned(),
 4550                ));
 4551            }
 4552        }
 4553
 4554        self.request_workspace_config_refresh();
 4555
 4556        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4557            prettier_store.update(cx, |prettier_store, cx| {
 4558                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4559            })
 4560        }
 4561
 4562        cx.notify();
 4563    }
 4564
 4565    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4566        let buffer_store = self.buffer_store.clone();
 4567        let Some(local) = self.as_local_mut() else {
 4568            return;
 4569        };
 4570        let mut adapters = BTreeMap::default();
 4571        let get_adapter = {
 4572            let languages = local.languages.clone();
 4573            let environment = local.environment.clone();
 4574            let weak = local.weak.clone();
 4575            let worktree_store = local.worktree_store.clone();
 4576            let http_client = local.http_client.clone();
 4577            let fs = local.fs.clone();
 4578            move |worktree_id, cx: &mut App| {
 4579                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4580                Some(LocalLspAdapterDelegate::new(
 4581                    languages.clone(),
 4582                    &environment,
 4583                    weak.clone(),
 4584                    &worktree,
 4585                    http_client.clone(),
 4586                    fs.clone(),
 4587                    cx,
 4588                ))
 4589            }
 4590        };
 4591
 4592        let mut messages_to_report = Vec::new();
 4593        let (new_tree, to_stop) = {
 4594            let mut rebase = local.lsp_tree.rebase();
 4595            let buffers = buffer_store
 4596                .read(cx)
 4597                .buffers()
 4598                .filter_map(|buffer| {
 4599                    let raw_buffer = buffer.read(cx);
 4600                    if !local
 4601                        .registered_buffers
 4602                        .contains_key(&raw_buffer.remote_id())
 4603                    {
 4604                        return None;
 4605                    }
 4606                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4607                    let language = raw_buffer.language().cloned()?;
 4608                    Some((file, language, raw_buffer.remote_id()))
 4609                })
 4610                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4611            for (file, language, buffer_id) in buffers {
 4612                let worktree_id = file.worktree_id(cx);
 4613                let Some(worktree) = local
 4614                    .worktree_store
 4615                    .read(cx)
 4616                    .worktree_for_id(worktree_id, cx)
 4617                else {
 4618                    continue;
 4619                };
 4620
 4621                if let Some((_, apply)) = local.reuse_existing_language_server(
 4622                    rebase.server_tree(),
 4623                    &worktree,
 4624                    &language.name(),
 4625                    cx,
 4626                ) {
 4627                    (apply)(rebase.server_tree());
 4628                } else if let Some(lsp_delegate) = adapters
 4629                    .entry(worktree_id)
 4630                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4631                    .clone()
 4632                {
 4633                    let delegate =
 4634                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4635                    let path = file
 4636                        .path()
 4637                        .parent()
 4638                        .map(Arc::from)
 4639                        .unwrap_or_else(|| file.path().clone());
 4640                    let worktree_path = ProjectPath { worktree_id, path };
 4641                    let abs_path = file.abs_path(cx);
 4642                    let nodes = rebase
 4643                        .walk(
 4644                            worktree_path,
 4645                            language.name(),
 4646                            language.manifest(),
 4647                            delegate.clone(),
 4648                            cx,
 4649                        )
 4650                        .collect::<Vec<_>>();
 4651                    for node in nodes {
 4652                        let server_id = node.server_id_or_init(|disposition| {
 4653                            let path = &disposition.path;
 4654                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4655                            let key = LanguageServerSeed {
 4656                                worktree_id,
 4657                                name: disposition.server_name.clone(),
 4658                                settings: disposition.settings.clone(),
 4659                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4660                                    path.worktree_id,
 4661                                    &path.path,
 4662                                    language.name(),
 4663                                ),
 4664                            };
 4665                            local.language_server_ids.remove(&key);
 4666
 4667                            let server_id = local.get_or_insert_language_server(
 4668                                &worktree,
 4669                                lsp_delegate.clone(),
 4670                                disposition,
 4671                                &language.name(),
 4672                                cx,
 4673                            );
 4674                            if let Some(state) = local.language_servers.get(&server_id)
 4675                                && let Ok(uri) = uri
 4676                            {
 4677                                state.add_workspace_folder(uri);
 4678                            };
 4679                            server_id
 4680                        });
 4681
 4682                        if let Some(language_server_id) = server_id {
 4683                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4684                                language_server_id,
 4685                                name: node.name(),
 4686                                message:
 4687                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4688                                        proto::RegisteredForBuffer {
 4689                                            buffer_abs_path: abs_path
 4690                                                .to_string_lossy()
 4691                                                .into_owned(),
 4692                                            buffer_id: buffer_id.to_proto(),
 4693                                        },
 4694                                    ),
 4695                            });
 4696                        }
 4697                    }
 4698                } else {
 4699                    continue;
 4700                }
 4701            }
 4702            rebase.finish()
 4703        };
 4704        for message in messages_to_report {
 4705            cx.emit(message);
 4706        }
 4707        local.lsp_tree = new_tree;
 4708        for (id, _) in to_stop {
 4709            self.stop_local_language_server(id, cx).detach();
 4710        }
 4711    }
 4712
 4713    pub fn apply_code_action(
 4714        &self,
 4715        buffer_handle: Entity<Buffer>,
 4716        mut action: CodeAction,
 4717        push_to_history: bool,
 4718        cx: &mut Context<Self>,
 4719    ) -> Task<Result<ProjectTransaction>> {
 4720        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4721            let request = proto::ApplyCodeAction {
 4722                project_id,
 4723                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4724                action: Some(Self::serialize_code_action(&action)),
 4725            };
 4726            let buffer_store = self.buffer_store();
 4727            cx.spawn(async move |_, cx| {
 4728                let response = upstream_client
 4729                    .request(request)
 4730                    .await?
 4731                    .transaction
 4732                    .context("missing transaction")?;
 4733
 4734                buffer_store
 4735                    .update(cx, |buffer_store, cx| {
 4736                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4737                    })?
 4738                    .await
 4739            })
 4740        } else if self.mode.is_local() {
 4741            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4742                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4743                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4744            }) else {
 4745                return Task::ready(Ok(ProjectTransaction::default()));
 4746            };
 4747            cx.spawn(async move |this,  cx| {
 4748                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4749                    .await
 4750                    .context("resolving a code action")?;
 4751                if let Some(edit) = action.lsp_action.edit()
 4752                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4753                        return LocalLspStore::deserialize_workspace_edit(
 4754                            this.upgrade().context("no app present")?,
 4755                            edit.clone(),
 4756                            push_to_history,
 4757
 4758                            lang_server.clone(),
 4759                            cx,
 4760                        )
 4761                        .await;
 4762                    }
 4763
 4764                if let Some(command) = action.lsp_action.command() {
 4765                    let server_capabilities = lang_server.capabilities();
 4766                    let available_commands = server_capabilities
 4767                        .execute_command_provider
 4768                        .as_ref()
 4769                        .map(|options| options.commands.as_slice())
 4770                        .unwrap_or_default();
 4771                    if available_commands.contains(&command.command) {
 4772                        this.update(cx, |this, _| {
 4773                            this.as_local_mut()
 4774                                .unwrap()
 4775                                .last_workspace_edits_by_language_server
 4776                                .remove(&lang_server.server_id());
 4777                        })?;
 4778
 4779                        let _result = lang_server
 4780                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4781                                command: command.command.clone(),
 4782                                arguments: command.arguments.clone().unwrap_or_default(),
 4783                                ..lsp::ExecuteCommandParams::default()
 4784                            })
 4785                            .await.into_response()
 4786                            .context("execute command")?;
 4787
 4788                        return this.update(cx, |this, _| {
 4789                            this.as_local_mut()
 4790                                .unwrap()
 4791                                .last_workspace_edits_by_language_server
 4792                                .remove(&lang_server.server_id())
 4793                                .unwrap_or_default()
 4794                        });
 4795                    } else {
 4796                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4797                    }
 4798                }
 4799
 4800                Ok(ProjectTransaction::default())
 4801            })
 4802        } else {
 4803            Task::ready(Err(anyhow!("no upstream client and not local")))
 4804        }
 4805    }
 4806
 4807    pub fn apply_code_action_kind(
 4808        &mut self,
 4809        buffers: HashSet<Entity<Buffer>>,
 4810        kind: CodeActionKind,
 4811        push_to_history: bool,
 4812        cx: &mut Context<Self>,
 4813    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4814        if self.as_local().is_some() {
 4815            cx.spawn(async move |lsp_store, cx| {
 4816                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4817                let result = LocalLspStore::execute_code_action_kind_locally(
 4818                    lsp_store.clone(),
 4819                    buffers,
 4820                    kind,
 4821                    push_to_history,
 4822                    cx,
 4823                )
 4824                .await;
 4825                lsp_store.update(cx, |lsp_store, _| {
 4826                    lsp_store.update_last_formatting_failure(&result);
 4827                })?;
 4828                result
 4829            })
 4830        } else if let Some((client, project_id)) = self.upstream_client() {
 4831            let buffer_store = self.buffer_store();
 4832            cx.spawn(async move |lsp_store, cx| {
 4833                let result = client
 4834                    .request(proto::ApplyCodeActionKind {
 4835                        project_id,
 4836                        kind: kind.as_str().to_owned(),
 4837                        buffer_ids: buffers
 4838                            .iter()
 4839                            .map(|buffer| {
 4840                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4841                            })
 4842                            .collect::<Result<_>>()?,
 4843                    })
 4844                    .await
 4845                    .and_then(|result| result.transaction.context("missing transaction"));
 4846                lsp_store.update(cx, |lsp_store, _| {
 4847                    lsp_store.update_last_formatting_failure(&result);
 4848                })?;
 4849
 4850                let transaction_response = result?;
 4851                buffer_store
 4852                    .update(cx, |buffer_store, cx| {
 4853                        buffer_store.deserialize_project_transaction(
 4854                            transaction_response,
 4855                            push_to_history,
 4856                            cx,
 4857                        )
 4858                    })?
 4859                    .await
 4860            })
 4861        } else {
 4862            Task::ready(Ok(ProjectTransaction::default()))
 4863        }
 4864    }
 4865
 4866    pub fn resolved_hint(
 4867        &mut self,
 4868        buffer_id: BufferId,
 4869        id: InlayId,
 4870        cx: &mut Context<Self>,
 4871    ) -> Option<ResolvedHint> {
 4872        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 4873
 4874        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 4875        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 4876        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 4877        let (server_id, resolve_data) = match &hint.resolve_state {
 4878            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 4879            ResolveState::Resolving => {
 4880                return Some(ResolvedHint::Resolving(
 4881                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 4882                ));
 4883            }
 4884            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 4885        };
 4886
 4887        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 4888        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 4889        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 4890            id,
 4891            cx.spawn(async move |lsp_store, cx| {
 4892                let resolved_hint = resolve_task.await;
 4893                lsp_store
 4894                    .update(cx, |lsp_store, _| {
 4895                        if let Some(old_inlay_hint) = lsp_store
 4896                            .lsp_data
 4897                            .get_mut(&buffer_id)
 4898                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 4899                        {
 4900                            match resolved_hint {
 4901                                Ok(resolved_hint) => {
 4902                                    *old_inlay_hint = resolved_hint;
 4903                                }
 4904                                Err(e) => {
 4905                                    old_inlay_hint.resolve_state =
 4906                                        ResolveState::CanResolve(server_id, resolve_data);
 4907                                    log::error!("Inlay hint resolve failed: {e:#}");
 4908                                }
 4909                            }
 4910                        }
 4911                    })
 4912                    .ok();
 4913            })
 4914            .shared(),
 4915        );
 4916        debug_assert!(
 4917            previous_task.is_none(),
 4918            "Did not change hint's resolve state after spawning its resolve"
 4919        );
 4920        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 4921        None
 4922    }
 4923
 4924    fn resolve_inlay_hint(
 4925        &self,
 4926        mut hint: InlayHint,
 4927        buffer: Entity<Buffer>,
 4928        server_id: LanguageServerId,
 4929        cx: &mut Context<Self>,
 4930    ) -> Task<anyhow::Result<InlayHint>> {
 4931        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4932            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4933            {
 4934                hint.resolve_state = ResolveState::Resolved;
 4935                return Task::ready(Ok(hint));
 4936            }
 4937            let request = proto::ResolveInlayHint {
 4938                project_id,
 4939                buffer_id: buffer.read(cx).remote_id().into(),
 4940                language_server_id: server_id.0 as u64,
 4941                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 4942            };
 4943            cx.background_spawn(async move {
 4944                let response = upstream_client
 4945                    .request(request)
 4946                    .await
 4947                    .context("inlay hints proto request")?;
 4948                match response.hint {
 4949                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 4950                        .context("inlay hints proto resolve response conversion"),
 4951                    None => Ok(hint),
 4952                }
 4953            })
 4954        } else {
 4955            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 4956                self.language_server_for_local_buffer(buffer, server_id, cx)
 4957                    .map(|(_, server)| server.clone())
 4958            }) else {
 4959                return Task::ready(Ok(hint));
 4960            };
 4961            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 4962                return Task::ready(Ok(hint));
 4963            }
 4964            let buffer_snapshot = buffer.read(cx).snapshot();
 4965            cx.spawn(async move |_, cx| {
 4966                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 4967                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 4968                );
 4969                let resolved_hint = resolve_task
 4970                    .await
 4971                    .into_response()
 4972                    .context("inlay hint resolve LSP request")?;
 4973                let resolved_hint = InlayHints::lsp_to_project_hint(
 4974                    resolved_hint,
 4975                    &buffer,
 4976                    server_id,
 4977                    ResolveState::Resolved,
 4978                    false,
 4979                    cx,
 4980                )
 4981                .await?;
 4982                Ok(resolved_hint)
 4983            })
 4984        }
 4985    }
 4986
 4987    pub fn resolve_color_presentation(
 4988        &mut self,
 4989        mut color: DocumentColor,
 4990        buffer: Entity<Buffer>,
 4991        server_id: LanguageServerId,
 4992        cx: &mut Context<Self>,
 4993    ) -> Task<Result<DocumentColor>> {
 4994        if color.resolved {
 4995            return Task::ready(Ok(color));
 4996        }
 4997
 4998        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4999            let start = color.lsp_range.start;
 5000            let end = color.lsp_range.end;
 5001            let request = proto::GetColorPresentation {
 5002                project_id,
 5003                server_id: server_id.to_proto(),
 5004                buffer_id: buffer.read(cx).remote_id().into(),
 5005                color: Some(proto::ColorInformation {
 5006                    red: color.color.red,
 5007                    green: color.color.green,
 5008                    blue: color.color.blue,
 5009                    alpha: color.color.alpha,
 5010                    lsp_range_start: Some(proto::PointUtf16 {
 5011                        row: start.line,
 5012                        column: start.character,
 5013                    }),
 5014                    lsp_range_end: Some(proto::PointUtf16 {
 5015                        row: end.line,
 5016                        column: end.character,
 5017                    }),
 5018                }),
 5019            };
 5020            cx.background_spawn(async move {
 5021                let response = upstream_client
 5022                    .request(request)
 5023                    .await
 5024                    .context("color presentation proto request")?;
 5025                color.resolved = true;
 5026                color.color_presentations = response
 5027                    .presentations
 5028                    .into_iter()
 5029                    .map(|presentation| ColorPresentation {
 5030                        label: SharedString::from(presentation.label),
 5031                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5032                        additional_text_edits: presentation
 5033                            .additional_text_edits
 5034                            .into_iter()
 5035                            .filter_map(deserialize_lsp_edit)
 5036                            .collect(),
 5037                    })
 5038                    .collect();
 5039                Ok(color)
 5040            })
 5041        } else {
 5042            let path = match buffer
 5043                .update(cx, |buffer, cx| {
 5044                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5045                })
 5046                .context("buffer with the missing path")
 5047            {
 5048                Ok(path) => path,
 5049                Err(e) => return Task::ready(Err(e)),
 5050            };
 5051            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5052                self.language_server_for_local_buffer(buffer, server_id, cx)
 5053                    .map(|(_, server)| server.clone())
 5054            }) else {
 5055                return Task::ready(Ok(color));
 5056            };
 5057            cx.background_spawn(async move {
 5058                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5059                    lsp::ColorPresentationParams {
 5060                        text_document: make_text_document_identifier(&path)?,
 5061                        color: color.color,
 5062                        range: color.lsp_range,
 5063                        work_done_progress_params: Default::default(),
 5064                        partial_result_params: Default::default(),
 5065                    },
 5066                );
 5067                color.color_presentations = resolve_task
 5068                    .await
 5069                    .into_response()
 5070                    .context("color presentation resolve LSP request")?
 5071                    .into_iter()
 5072                    .map(|presentation| ColorPresentation {
 5073                        label: SharedString::from(presentation.label),
 5074                        text_edit: presentation.text_edit,
 5075                        additional_text_edits: presentation
 5076                            .additional_text_edits
 5077                            .unwrap_or_default(),
 5078                    })
 5079                    .collect();
 5080                color.resolved = true;
 5081                Ok(color)
 5082            })
 5083        }
 5084    }
 5085
 5086    pub(crate) fn linked_edits(
 5087        &mut self,
 5088        buffer: &Entity<Buffer>,
 5089        position: Anchor,
 5090        cx: &mut Context<Self>,
 5091    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5092        let snapshot = buffer.read(cx).snapshot();
 5093        let scope = snapshot.language_scope_at(position);
 5094        let Some(server_id) = self
 5095            .as_local()
 5096            .and_then(|local| {
 5097                buffer.update(cx, |buffer, cx| {
 5098                    local
 5099                        .language_servers_for_buffer(buffer, cx)
 5100                        .filter(|(_, server)| {
 5101                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5102                        })
 5103                        .filter(|(adapter, _)| {
 5104                            scope
 5105                                .as_ref()
 5106                                .map(|scope| scope.language_allowed(&adapter.name))
 5107                                .unwrap_or(true)
 5108                        })
 5109                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5110                        .next()
 5111                })
 5112            })
 5113            .or_else(|| {
 5114                self.upstream_client()
 5115                    .is_some()
 5116                    .then_some(LanguageServerToQuery::FirstCapable)
 5117            })
 5118            .filter(|_| {
 5119                maybe!({
 5120                    let language = buffer.read(cx).language_at(position)?;
 5121                    Some(
 5122                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5123                            .linked_edits,
 5124                    )
 5125                }) == Some(true)
 5126            })
 5127        else {
 5128            return Task::ready(Ok(Vec::new()));
 5129        };
 5130
 5131        self.request_lsp(
 5132            buffer.clone(),
 5133            server_id,
 5134            LinkedEditingRange { position },
 5135            cx,
 5136        )
 5137    }
 5138
 5139    fn apply_on_type_formatting(
 5140        &mut self,
 5141        buffer: Entity<Buffer>,
 5142        position: Anchor,
 5143        trigger: String,
 5144        cx: &mut Context<Self>,
 5145    ) -> Task<Result<Option<Transaction>>> {
 5146        if let Some((client, project_id)) = self.upstream_client() {
 5147            if !self.check_if_capable_for_proto_request(
 5148                &buffer,
 5149                |capabilities| {
 5150                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5151                },
 5152                cx,
 5153            ) {
 5154                return Task::ready(Ok(None));
 5155            }
 5156            let request = proto::OnTypeFormatting {
 5157                project_id,
 5158                buffer_id: buffer.read(cx).remote_id().into(),
 5159                position: Some(serialize_anchor(&position)),
 5160                trigger,
 5161                version: serialize_version(&buffer.read(cx).version()),
 5162            };
 5163            cx.background_spawn(async move {
 5164                client
 5165                    .request(request)
 5166                    .await?
 5167                    .transaction
 5168                    .map(language::proto::deserialize_transaction)
 5169                    .transpose()
 5170            })
 5171        } else if let Some(local) = self.as_local_mut() {
 5172            let buffer_id = buffer.read(cx).remote_id();
 5173            local.buffers_being_formatted.insert(buffer_id);
 5174            cx.spawn(async move |this, cx| {
 5175                let _cleanup = defer({
 5176                    let this = this.clone();
 5177                    let mut cx = cx.clone();
 5178                    move || {
 5179                        this.update(&mut cx, |this, _| {
 5180                            if let Some(local) = this.as_local_mut() {
 5181                                local.buffers_being_formatted.remove(&buffer_id);
 5182                            }
 5183                        })
 5184                        .ok();
 5185                    }
 5186                });
 5187
 5188                buffer
 5189                    .update(cx, |buffer, _| {
 5190                        buffer.wait_for_edits(Some(position.timestamp))
 5191                    })?
 5192                    .await?;
 5193                this.update(cx, |this, cx| {
 5194                    let position = position.to_point_utf16(buffer.read(cx));
 5195                    this.on_type_format(buffer, position, trigger, false, cx)
 5196                })?
 5197                .await
 5198            })
 5199        } else {
 5200            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5201        }
 5202    }
 5203
 5204    pub fn on_type_format<T: ToPointUtf16>(
 5205        &mut self,
 5206        buffer: Entity<Buffer>,
 5207        position: T,
 5208        trigger: String,
 5209        push_to_history: bool,
 5210        cx: &mut Context<Self>,
 5211    ) -> Task<Result<Option<Transaction>>> {
 5212        let position = position.to_point_utf16(buffer.read(cx));
 5213        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5214    }
 5215
 5216    fn on_type_format_impl(
 5217        &mut self,
 5218        buffer: Entity<Buffer>,
 5219        position: PointUtf16,
 5220        trigger: String,
 5221        push_to_history: bool,
 5222        cx: &mut Context<Self>,
 5223    ) -> Task<Result<Option<Transaction>>> {
 5224        let options = buffer.update(cx, |buffer, cx| {
 5225            lsp_command::lsp_formatting_options(
 5226                language_settings(
 5227                    buffer.language_at(position).map(|l| l.name()),
 5228                    buffer.file(),
 5229                    cx,
 5230                )
 5231                .as_ref(),
 5232            )
 5233        });
 5234
 5235        cx.spawn(async move |this, cx| {
 5236            if let Some(waiter) =
 5237                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5238            {
 5239                waiter.await?;
 5240            }
 5241            cx.update(|cx| {
 5242                this.update(cx, |this, cx| {
 5243                    this.request_lsp(
 5244                        buffer.clone(),
 5245                        LanguageServerToQuery::FirstCapable,
 5246                        OnTypeFormatting {
 5247                            position,
 5248                            trigger,
 5249                            options,
 5250                            push_to_history,
 5251                        },
 5252                        cx,
 5253                    )
 5254                })
 5255            })??
 5256            .await
 5257        })
 5258    }
 5259
 5260    pub fn definitions(
 5261        &mut self,
 5262        buffer: &Entity<Buffer>,
 5263        position: PointUtf16,
 5264        cx: &mut Context<Self>,
 5265    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5266        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5267            let request = GetDefinitions { position };
 5268            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5269                return Task::ready(Ok(None));
 5270            }
 5271            let request_task = upstream_client.request_lsp(
 5272                project_id,
 5273                None,
 5274                LSP_REQUEST_TIMEOUT,
 5275                cx.background_executor().clone(),
 5276                request.to_proto(project_id, buffer.read(cx)),
 5277            );
 5278            let buffer = buffer.clone();
 5279            cx.spawn(async move |weak_project, cx| {
 5280                let Some(project) = weak_project.upgrade() else {
 5281                    return Ok(None);
 5282                };
 5283                let Some(responses) = request_task.await? else {
 5284                    return Ok(None);
 5285                };
 5286                let actions = join_all(responses.payload.into_iter().map(|response| {
 5287                    GetDefinitions { position }.response_from_proto(
 5288                        response.response,
 5289                        project.clone(),
 5290                        buffer.clone(),
 5291                        cx.clone(),
 5292                    )
 5293                }))
 5294                .await;
 5295
 5296                Ok(Some(
 5297                    actions
 5298                        .into_iter()
 5299                        .collect::<Result<Vec<Vec<_>>>>()?
 5300                        .into_iter()
 5301                        .flatten()
 5302                        .dedup()
 5303                        .collect(),
 5304                ))
 5305            })
 5306        } else {
 5307            let definitions_task = self.request_multiple_lsp_locally(
 5308                buffer,
 5309                Some(position),
 5310                GetDefinitions { position },
 5311                cx,
 5312            );
 5313            cx.background_spawn(async move {
 5314                Ok(Some(
 5315                    definitions_task
 5316                        .await
 5317                        .into_iter()
 5318                        .flat_map(|(_, definitions)| definitions)
 5319                        .dedup()
 5320                        .collect(),
 5321                ))
 5322            })
 5323        }
 5324    }
 5325
 5326    pub fn declarations(
 5327        &mut self,
 5328        buffer: &Entity<Buffer>,
 5329        position: PointUtf16,
 5330        cx: &mut Context<Self>,
 5331    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5332        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5333            let request = GetDeclarations { position };
 5334            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5335                return Task::ready(Ok(None));
 5336            }
 5337            let request_task = upstream_client.request_lsp(
 5338                project_id,
 5339                None,
 5340                LSP_REQUEST_TIMEOUT,
 5341                cx.background_executor().clone(),
 5342                request.to_proto(project_id, buffer.read(cx)),
 5343            );
 5344            let buffer = buffer.clone();
 5345            cx.spawn(async move |weak_project, cx| {
 5346                let Some(project) = weak_project.upgrade() else {
 5347                    return Ok(None);
 5348                };
 5349                let Some(responses) = request_task.await? else {
 5350                    return Ok(None);
 5351                };
 5352                let actions = join_all(responses.payload.into_iter().map(|response| {
 5353                    GetDeclarations { position }.response_from_proto(
 5354                        response.response,
 5355                        project.clone(),
 5356                        buffer.clone(),
 5357                        cx.clone(),
 5358                    )
 5359                }))
 5360                .await;
 5361
 5362                Ok(Some(
 5363                    actions
 5364                        .into_iter()
 5365                        .collect::<Result<Vec<Vec<_>>>>()?
 5366                        .into_iter()
 5367                        .flatten()
 5368                        .dedup()
 5369                        .collect(),
 5370                ))
 5371            })
 5372        } else {
 5373            let declarations_task = self.request_multiple_lsp_locally(
 5374                buffer,
 5375                Some(position),
 5376                GetDeclarations { position },
 5377                cx,
 5378            );
 5379            cx.background_spawn(async move {
 5380                Ok(Some(
 5381                    declarations_task
 5382                        .await
 5383                        .into_iter()
 5384                        .flat_map(|(_, declarations)| declarations)
 5385                        .dedup()
 5386                        .collect(),
 5387                ))
 5388            })
 5389        }
 5390    }
 5391
 5392    pub fn type_definitions(
 5393        &mut self,
 5394        buffer: &Entity<Buffer>,
 5395        position: PointUtf16,
 5396        cx: &mut Context<Self>,
 5397    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5398        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5399            let request = GetTypeDefinitions { position };
 5400            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5401                return Task::ready(Ok(None));
 5402            }
 5403            let request_task = upstream_client.request_lsp(
 5404                project_id,
 5405                None,
 5406                LSP_REQUEST_TIMEOUT,
 5407                cx.background_executor().clone(),
 5408                request.to_proto(project_id, buffer.read(cx)),
 5409            );
 5410            let buffer = buffer.clone();
 5411            cx.spawn(async move |weak_project, cx| {
 5412                let Some(project) = weak_project.upgrade() else {
 5413                    return Ok(None);
 5414                };
 5415                let Some(responses) = request_task.await? else {
 5416                    return Ok(None);
 5417                };
 5418                let actions = join_all(responses.payload.into_iter().map(|response| {
 5419                    GetTypeDefinitions { position }.response_from_proto(
 5420                        response.response,
 5421                        project.clone(),
 5422                        buffer.clone(),
 5423                        cx.clone(),
 5424                    )
 5425                }))
 5426                .await;
 5427
 5428                Ok(Some(
 5429                    actions
 5430                        .into_iter()
 5431                        .collect::<Result<Vec<Vec<_>>>>()?
 5432                        .into_iter()
 5433                        .flatten()
 5434                        .dedup()
 5435                        .collect(),
 5436                ))
 5437            })
 5438        } else {
 5439            let type_definitions_task = self.request_multiple_lsp_locally(
 5440                buffer,
 5441                Some(position),
 5442                GetTypeDefinitions { position },
 5443                cx,
 5444            );
 5445            cx.background_spawn(async move {
 5446                Ok(Some(
 5447                    type_definitions_task
 5448                        .await
 5449                        .into_iter()
 5450                        .flat_map(|(_, type_definitions)| type_definitions)
 5451                        .dedup()
 5452                        .collect(),
 5453                ))
 5454            })
 5455        }
 5456    }
 5457
 5458    pub fn implementations(
 5459        &mut self,
 5460        buffer: &Entity<Buffer>,
 5461        position: PointUtf16,
 5462        cx: &mut Context<Self>,
 5463    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5464        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5465            let request = GetImplementations { position };
 5466            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5467                return Task::ready(Ok(None));
 5468            }
 5469            let request_task = upstream_client.request_lsp(
 5470                project_id,
 5471                None,
 5472                LSP_REQUEST_TIMEOUT,
 5473                cx.background_executor().clone(),
 5474                request.to_proto(project_id, buffer.read(cx)),
 5475            );
 5476            let buffer = buffer.clone();
 5477            cx.spawn(async move |weak_project, cx| {
 5478                let Some(project) = weak_project.upgrade() else {
 5479                    return Ok(None);
 5480                };
 5481                let Some(responses) = request_task.await? else {
 5482                    return Ok(None);
 5483                };
 5484                let actions = join_all(responses.payload.into_iter().map(|response| {
 5485                    GetImplementations { position }.response_from_proto(
 5486                        response.response,
 5487                        project.clone(),
 5488                        buffer.clone(),
 5489                        cx.clone(),
 5490                    )
 5491                }))
 5492                .await;
 5493
 5494                Ok(Some(
 5495                    actions
 5496                        .into_iter()
 5497                        .collect::<Result<Vec<Vec<_>>>>()?
 5498                        .into_iter()
 5499                        .flatten()
 5500                        .dedup()
 5501                        .collect(),
 5502                ))
 5503            })
 5504        } else {
 5505            let implementations_task = self.request_multiple_lsp_locally(
 5506                buffer,
 5507                Some(position),
 5508                GetImplementations { position },
 5509                cx,
 5510            );
 5511            cx.background_spawn(async move {
 5512                Ok(Some(
 5513                    implementations_task
 5514                        .await
 5515                        .into_iter()
 5516                        .flat_map(|(_, implementations)| implementations)
 5517                        .dedup()
 5518                        .collect(),
 5519                ))
 5520            })
 5521        }
 5522    }
 5523
 5524    pub fn references(
 5525        &mut self,
 5526        buffer: &Entity<Buffer>,
 5527        position: PointUtf16,
 5528        cx: &mut Context<Self>,
 5529    ) -> Task<Result<Option<Vec<Location>>>> {
 5530        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5531            let request = GetReferences { position };
 5532            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5533                return Task::ready(Ok(None));
 5534            }
 5535
 5536            let request_task = upstream_client.request_lsp(
 5537                project_id,
 5538                None,
 5539                LSP_REQUEST_TIMEOUT,
 5540                cx.background_executor().clone(),
 5541                request.to_proto(project_id, buffer.read(cx)),
 5542            );
 5543            let buffer = buffer.clone();
 5544            cx.spawn(async move |weak_project, cx| {
 5545                let Some(project) = weak_project.upgrade() else {
 5546                    return Ok(None);
 5547                };
 5548                let Some(responses) = request_task.await? else {
 5549                    return Ok(None);
 5550                };
 5551
 5552                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5553                    GetReferences { position }.response_from_proto(
 5554                        lsp_response.response,
 5555                        project.clone(),
 5556                        buffer.clone(),
 5557                        cx.clone(),
 5558                    )
 5559                }))
 5560                .await
 5561                .into_iter()
 5562                .collect::<Result<Vec<Vec<_>>>>()?
 5563                .into_iter()
 5564                .flatten()
 5565                .dedup()
 5566                .collect();
 5567                Ok(Some(locations))
 5568            })
 5569        } else {
 5570            let references_task = self.request_multiple_lsp_locally(
 5571                buffer,
 5572                Some(position),
 5573                GetReferences { position },
 5574                cx,
 5575            );
 5576            cx.background_spawn(async move {
 5577                Ok(Some(
 5578                    references_task
 5579                        .await
 5580                        .into_iter()
 5581                        .flat_map(|(_, references)| references)
 5582                        .dedup()
 5583                        .collect(),
 5584                ))
 5585            })
 5586        }
 5587    }
 5588
 5589    pub fn code_actions(
 5590        &mut self,
 5591        buffer: &Entity<Buffer>,
 5592        range: Range<Anchor>,
 5593        kinds: Option<Vec<CodeActionKind>>,
 5594        cx: &mut Context<Self>,
 5595    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5596        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5597            let request = GetCodeActions {
 5598                range: range.clone(),
 5599                kinds: kinds.clone(),
 5600            };
 5601            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5602                return Task::ready(Ok(None));
 5603            }
 5604            let request_task = upstream_client.request_lsp(
 5605                project_id,
 5606                None,
 5607                LSP_REQUEST_TIMEOUT,
 5608                cx.background_executor().clone(),
 5609                request.to_proto(project_id, buffer.read(cx)),
 5610            );
 5611            let buffer = buffer.clone();
 5612            cx.spawn(async move |weak_project, cx| {
 5613                let Some(project) = weak_project.upgrade() else {
 5614                    return Ok(None);
 5615                };
 5616                let Some(responses) = request_task.await? else {
 5617                    return Ok(None);
 5618                };
 5619                let actions = join_all(responses.payload.into_iter().map(|response| {
 5620                    GetCodeActions {
 5621                        range: range.clone(),
 5622                        kinds: kinds.clone(),
 5623                    }
 5624                    .response_from_proto(
 5625                        response.response,
 5626                        project.clone(),
 5627                        buffer.clone(),
 5628                        cx.clone(),
 5629                    )
 5630                }))
 5631                .await;
 5632
 5633                Ok(Some(
 5634                    actions
 5635                        .into_iter()
 5636                        .collect::<Result<Vec<Vec<_>>>>()?
 5637                        .into_iter()
 5638                        .flatten()
 5639                        .collect(),
 5640                ))
 5641            })
 5642        } else {
 5643            let all_actions_task = self.request_multiple_lsp_locally(
 5644                buffer,
 5645                Some(range.start),
 5646                GetCodeActions { range, kinds },
 5647                cx,
 5648            );
 5649            cx.background_spawn(async move {
 5650                Ok(Some(
 5651                    all_actions_task
 5652                        .await
 5653                        .into_iter()
 5654                        .flat_map(|(_, actions)| actions)
 5655                        .collect(),
 5656                ))
 5657            })
 5658        }
 5659    }
 5660
 5661    pub fn code_lens_actions(
 5662        &mut self,
 5663        buffer: &Entity<Buffer>,
 5664        cx: &mut Context<Self>,
 5665    ) -> CodeLensTask {
 5666        let version_queried_for = buffer.read(cx).version();
 5667        let buffer_id = buffer.read(cx).remote_id();
 5668        let existing_servers = self.as_local().map(|local| {
 5669            local
 5670                .buffers_opened_in_servers
 5671                .get(&buffer_id)
 5672                .cloned()
 5673                .unwrap_or_default()
 5674        });
 5675
 5676        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5677            if let Some(cached_lens) = &lsp_data.code_lens {
 5678                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5679                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5680                        existing_servers != cached_lens.lens.keys().copied().collect()
 5681                    });
 5682                    if !has_different_servers {
 5683                        return Task::ready(Ok(Some(
 5684                            cached_lens.lens.values().flatten().cloned().collect(),
 5685                        )))
 5686                        .shared();
 5687                    }
 5688                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5689                    if !version_queried_for.changed_since(updating_for) {
 5690                        return running_update.clone();
 5691                    }
 5692                }
 5693            }
 5694        }
 5695
 5696        let lens_lsp_data = self
 5697            .latest_lsp_data(buffer, cx)
 5698            .code_lens
 5699            .get_or_insert_default();
 5700        let buffer = buffer.clone();
 5701        let query_version_queried_for = version_queried_for.clone();
 5702        let new_task = cx
 5703            .spawn(async move |lsp_store, cx| {
 5704                cx.background_executor()
 5705                    .timer(Duration::from_millis(30))
 5706                    .await;
 5707                let fetched_lens = lsp_store
 5708                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5709                    .map_err(Arc::new)?
 5710                    .await
 5711                    .context("fetching code lens")
 5712                    .map_err(Arc::new);
 5713                let fetched_lens = match fetched_lens {
 5714                    Ok(fetched_lens) => fetched_lens,
 5715                    Err(e) => {
 5716                        lsp_store
 5717                            .update(cx, |lsp_store, _| {
 5718                                if let Some(lens_lsp_data) = lsp_store
 5719                                    .lsp_data
 5720                                    .get_mut(&buffer_id)
 5721                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5722                                {
 5723                                    lens_lsp_data.update = None;
 5724                                }
 5725                            })
 5726                            .ok();
 5727                        return Err(e);
 5728                    }
 5729                };
 5730
 5731                lsp_store
 5732                    .update(cx, |lsp_store, _| {
 5733                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5734                        let code_lens = lsp_data.code_lens.as_mut()?;
 5735                        if let Some(fetched_lens) = fetched_lens {
 5736                            if lsp_data.buffer_version == query_version_queried_for {
 5737                                code_lens.lens.extend(fetched_lens);
 5738                            } else if !lsp_data
 5739                                .buffer_version
 5740                                .changed_since(&query_version_queried_for)
 5741                            {
 5742                                lsp_data.buffer_version = query_version_queried_for;
 5743                                code_lens.lens = fetched_lens;
 5744                            }
 5745                        }
 5746                        code_lens.update = None;
 5747                        Some(code_lens.lens.values().flatten().cloned().collect())
 5748                    })
 5749                    .map_err(Arc::new)
 5750            })
 5751            .shared();
 5752        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5753        new_task
 5754    }
 5755
 5756    fn fetch_code_lens(
 5757        &mut self,
 5758        buffer: &Entity<Buffer>,
 5759        cx: &mut Context<Self>,
 5760    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5761        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5762            let request = GetCodeLens;
 5763            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5764                return Task::ready(Ok(None));
 5765            }
 5766            let request_task = upstream_client.request_lsp(
 5767                project_id,
 5768                None,
 5769                LSP_REQUEST_TIMEOUT,
 5770                cx.background_executor().clone(),
 5771                request.to_proto(project_id, buffer.read(cx)),
 5772            );
 5773            let buffer = buffer.clone();
 5774            cx.spawn(async move |weak_lsp_store, cx| {
 5775                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5776                    return Ok(None);
 5777                };
 5778                let Some(responses) = request_task.await? else {
 5779                    return Ok(None);
 5780                };
 5781
 5782                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5783                    let lsp_store = lsp_store.clone();
 5784                    let buffer = buffer.clone();
 5785                    let cx = cx.clone();
 5786                    async move {
 5787                        (
 5788                            LanguageServerId::from_proto(response.server_id),
 5789                            GetCodeLens
 5790                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5791                                .await,
 5792                        )
 5793                    }
 5794                }))
 5795                .await;
 5796
 5797                let mut has_errors = false;
 5798                let code_lens_actions = code_lens_actions
 5799                    .into_iter()
 5800                    .filter_map(|(server_id, code_lens)| match code_lens {
 5801                        Ok(code_lens) => Some((server_id, code_lens)),
 5802                        Err(e) => {
 5803                            has_errors = true;
 5804                            log::error!("{e:#}");
 5805                            None
 5806                        }
 5807                    })
 5808                    .collect::<HashMap<_, _>>();
 5809                anyhow::ensure!(
 5810                    !has_errors || !code_lens_actions.is_empty(),
 5811                    "Failed to fetch code lens"
 5812                );
 5813                Ok(Some(code_lens_actions))
 5814            })
 5815        } else {
 5816            let code_lens_actions_task =
 5817                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5818            cx.background_spawn(async move {
 5819                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5820            })
 5821        }
 5822    }
 5823
 5824    #[inline(never)]
 5825    pub fn completions(
 5826        &self,
 5827        buffer: &Entity<Buffer>,
 5828        position: PointUtf16,
 5829        context: CompletionContext,
 5830        cx: &mut Context<Self>,
 5831    ) -> Task<Result<Vec<CompletionResponse>>> {
 5832        let language_registry = self.languages.clone();
 5833
 5834        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5835            let request = GetCompletions { position, context };
 5836            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5837                return Task::ready(Ok(Vec::new()));
 5838            }
 5839            let task = self.send_lsp_proto_request(
 5840                buffer.clone(),
 5841                upstream_client,
 5842                project_id,
 5843                request,
 5844                cx,
 5845            );
 5846            let language = buffer.read(cx).language().cloned();
 5847
 5848            // In the future, we should provide project guests with the names of LSP adapters,
 5849            // so that they can use the correct LSP adapter when computing labels. For now,
 5850            // guests just use the first LSP adapter associated with the buffer's language.
 5851            let lsp_adapter = language.as_ref().and_then(|language| {
 5852                language_registry
 5853                    .lsp_adapters(&language.name())
 5854                    .first()
 5855                    .cloned()
 5856            });
 5857
 5858            cx.foreground_executor().spawn(async move {
 5859                let completion_response = task.await?;
 5860                let completions = populate_labels_for_completions(
 5861                    completion_response.completions,
 5862                    language,
 5863                    lsp_adapter,
 5864                )
 5865                .await;
 5866                Ok(vec![CompletionResponse {
 5867                    completions,
 5868                    display_options: CompletionDisplayOptions::default(),
 5869                    is_incomplete: completion_response.is_incomplete,
 5870                }])
 5871            })
 5872        } else if let Some(local) = self.as_local() {
 5873            let snapshot = buffer.read(cx).snapshot();
 5874            let offset = position.to_offset(&snapshot);
 5875            let scope = snapshot.language_scope_at(offset);
 5876            let language = snapshot.language().cloned();
 5877            let completion_settings = language_settings(
 5878                language.as_ref().map(|language| language.name()),
 5879                buffer.read(cx).file(),
 5880                cx,
 5881            )
 5882            .completions
 5883            .clone();
 5884            if !completion_settings.lsp {
 5885                return Task::ready(Ok(Vec::new()));
 5886            }
 5887
 5888            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5889                local
 5890                    .language_servers_for_buffer(buffer, cx)
 5891                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5892                    .filter(|(adapter, _)| {
 5893                        scope
 5894                            .as_ref()
 5895                            .map(|scope| scope.language_allowed(&adapter.name))
 5896                            .unwrap_or(true)
 5897                    })
 5898                    .map(|(_, server)| server.server_id())
 5899                    .collect()
 5900            });
 5901
 5902            let buffer = buffer.clone();
 5903            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5904            let lsp_timeout = if lsp_timeout > 0 {
 5905                Some(Duration::from_millis(lsp_timeout))
 5906            } else {
 5907                None
 5908            };
 5909            cx.spawn(async move |this,  cx| {
 5910                let mut tasks = Vec::with_capacity(server_ids.len());
 5911                this.update(cx, |lsp_store, cx| {
 5912                    for server_id in server_ids {
 5913                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5914                        let lsp_timeout = lsp_timeout
 5915                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5916                        let mut timeout = cx.background_spawn(async move {
 5917                            match lsp_timeout {
 5918                                Some(lsp_timeout) => {
 5919                                    lsp_timeout.await;
 5920                                    true
 5921                                },
 5922                                None => false,
 5923                            }
 5924                        }).fuse();
 5925                        let mut lsp_request = lsp_store.request_lsp(
 5926                            buffer.clone(),
 5927                            LanguageServerToQuery::Other(server_id),
 5928                            GetCompletions {
 5929                                position,
 5930                                context: context.clone(),
 5931                            },
 5932                            cx,
 5933                        ).fuse();
 5934                        let new_task = cx.background_spawn(async move {
 5935                            select_biased! {
 5936                                response = lsp_request => anyhow::Ok(Some(response?)),
 5937                                timeout_happened = timeout => {
 5938                                    if timeout_happened {
 5939                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5940                                        Ok(None)
 5941                                    } else {
 5942                                        let completions = lsp_request.await?;
 5943                                        Ok(Some(completions))
 5944                                    }
 5945                                },
 5946                            }
 5947                        });
 5948                        tasks.push((lsp_adapter, new_task));
 5949                    }
 5950                })?;
 5951
 5952                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5953                    let completion_response = task.await.ok()??;
 5954                    let completions = populate_labels_for_completions(
 5955                            completion_response.completions,
 5956                            language.clone(),
 5957                            lsp_adapter,
 5958                        )
 5959                        .await;
 5960                    Some(CompletionResponse {
 5961                        completions,
 5962                        display_options: CompletionDisplayOptions::default(),
 5963                        is_incomplete: completion_response.is_incomplete,
 5964                    })
 5965                });
 5966
 5967                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 5968
 5969                Ok(responses.into_iter().flatten().collect())
 5970            })
 5971        } else {
 5972            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5973        }
 5974    }
 5975
 5976    pub fn resolve_completions(
 5977        &self,
 5978        buffer: Entity<Buffer>,
 5979        completion_indices: Vec<usize>,
 5980        completions: Rc<RefCell<Box<[Completion]>>>,
 5981        cx: &mut Context<Self>,
 5982    ) -> Task<Result<bool>> {
 5983        let client = self.upstream_client();
 5984        let buffer_id = buffer.read(cx).remote_id();
 5985        let buffer_snapshot = buffer.read(cx).snapshot();
 5986
 5987        if !self.check_if_capable_for_proto_request(
 5988            &buffer,
 5989            GetCompletions::can_resolve_completions,
 5990            cx,
 5991        ) {
 5992            return Task::ready(Ok(false));
 5993        }
 5994        cx.spawn(async move |lsp_store, cx| {
 5995            let mut did_resolve = false;
 5996            if let Some((client, project_id)) = client {
 5997                for completion_index in completion_indices {
 5998                    let server_id = {
 5999                        let completion = &completions.borrow()[completion_index];
 6000                        completion.source.server_id()
 6001                    };
 6002                    if let Some(server_id) = server_id {
 6003                        if Self::resolve_completion_remote(
 6004                            project_id,
 6005                            server_id,
 6006                            buffer_id,
 6007                            completions.clone(),
 6008                            completion_index,
 6009                            client.clone(),
 6010                        )
 6011                        .await
 6012                        .log_err()
 6013                        .is_some()
 6014                        {
 6015                            did_resolve = true;
 6016                        }
 6017                    } else {
 6018                        resolve_word_completion(
 6019                            &buffer_snapshot,
 6020                            &mut completions.borrow_mut()[completion_index],
 6021                        );
 6022                    }
 6023                }
 6024            } else {
 6025                for completion_index in completion_indices {
 6026                    let server_id = {
 6027                        let completion = &completions.borrow()[completion_index];
 6028                        completion.source.server_id()
 6029                    };
 6030                    if let Some(server_id) = server_id {
 6031                        let server_and_adapter = lsp_store
 6032                            .read_with(cx, |lsp_store, _| {
 6033                                let server = lsp_store.language_server_for_id(server_id)?;
 6034                                let adapter =
 6035                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6036                                Some((server, adapter))
 6037                            })
 6038                            .ok()
 6039                            .flatten();
 6040                        let Some((server, adapter)) = server_and_adapter else {
 6041                            continue;
 6042                        };
 6043
 6044                        let resolved = Self::resolve_completion_local(
 6045                            server,
 6046                            completions.clone(),
 6047                            completion_index,
 6048                        )
 6049                        .await
 6050                        .log_err()
 6051                        .is_some();
 6052                        if resolved {
 6053                            Self::regenerate_completion_labels(
 6054                                adapter,
 6055                                &buffer_snapshot,
 6056                                completions.clone(),
 6057                                completion_index,
 6058                            )
 6059                            .await
 6060                            .log_err();
 6061                            did_resolve = true;
 6062                        }
 6063                    } else {
 6064                        resolve_word_completion(
 6065                            &buffer_snapshot,
 6066                            &mut completions.borrow_mut()[completion_index],
 6067                        );
 6068                    }
 6069                }
 6070            }
 6071
 6072            Ok(did_resolve)
 6073        })
 6074    }
 6075
 6076    async fn resolve_completion_local(
 6077        server: Arc<lsp::LanguageServer>,
 6078        completions: Rc<RefCell<Box<[Completion]>>>,
 6079        completion_index: usize,
 6080    ) -> Result<()> {
 6081        let server_id = server.server_id();
 6082        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6083            return Ok(());
 6084        }
 6085
 6086        let request = {
 6087            let completion = &completions.borrow()[completion_index];
 6088            match &completion.source {
 6089                CompletionSource::Lsp {
 6090                    lsp_completion,
 6091                    resolved,
 6092                    server_id: completion_server_id,
 6093                    ..
 6094                } => {
 6095                    if *resolved {
 6096                        return Ok(());
 6097                    }
 6098                    anyhow::ensure!(
 6099                        server_id == *completion_server_id,
 6100                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6101                    );
 6102                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6103                }
 6104                CompletionSource::BufferWord { .. }
 6105                | CompletionSource::Dap { .. }
 6106                | CompletionSource::Custom => {
 6107                    return Ok(());
 6108                }
 6109            }
 6110        };
 6111        let resolved_completion = request
 6112            .await
 6113            .into_response()
 6114            .context("resolve completion")?;
 6115
 6116        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6117        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6118
 6119        let mut completions = completions.borrow_mut();
 6120        let completion = &mut completions[completion_index];
 6121        if let CompletionSource::Lsp {
 6122            lsp_completion,
 6123            resolved,
 6124            server_id: completion_server_id,
 6125            ..
 6126        } = &mut completion.source
 6127        {
 6128            if *resolved {
 6129                return Ok(());
 6130            }
 6131            anyhow::ensure!(
 6132                server_id == *completion_server_id,
 6133                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6134            );
 6135            *lsp_completion = Box::new(resolved_completion);
 6136            *resolved = true;
 6137        }
 6138        Ok(())
 6139    }
 6140
 6141    async fn regenerate_completion_labels(
 6142        adapter: Arc<CachedLspAdapter>,
 6143        snapshot: &BufferSnapshot,
 6144        completions: Rc<RefCell<Box<[Completion]>>>,
 6145        completion_index: usize,
 6146    ) -> Result<()> {
 6147        let completion_item = completions.borrow()[completion_index]
 6148            .source
 6149            .lsp_completion(true)
 6150            .map(Cow::into_owned);
 6151        if let Some(lsp_documentation) = completion_item
 6152            .as_ref()
 6153            .and_then(|completion_item| completion_item.documentation.clone())
 6154        {
 6155            let mut completions = completions.borrow_mut();
 6156            let completion = &mut completions[completion_index];
 6157            completion.documentation = Some(lsp_documentation.into());
 6158        } else {
 6159            let mut completions = completions.borrow_mut();
 6160            let completion = &mut completions[completion_index];
 6161            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6162        }
 6163
 6164        let mut new_label = match completion_item {
 6165            Some(completion_item) => {
 6166                // 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
 6167                // So we have to update the label here anyway...
 6168                let language = snapshot.language();
 6169                match language {
 6170                    Some(language) => {
 6171                        adapter
 6172                            .labels_for_completions(
 6173                                std::slice::from_ref(&completion_item),
 6174                                language,
 6175                            )
 6176                            .await?
 6177                    }
 6178                    None => Vec::new(),
 6179                }
 6180                .pop()
 6181                .flatten()
 6182                .unwrap_or_else(|| {
 6183                    CodeLabel::fallback_for_completion(
 6184                        &completion_item,
 6185                        language.map(|language| language.as_ref()),
 6186                    )
 6187                })
 6188            }
 6189            None => CodeLabel::plain(
 6190                completions.borrow()[completion_index].new_text.clone(),
 6191                None,
 6192            ),
 6193        };
 6194        ensure_uniform_list_compatible_label(&mut new_label);
 6195
 6196        let mut completions = completions.borrow_mut();
 6197        let completion = &mut completions[completion_index];
 6198        if completion.label.filter_text() == new_label.filter_text() {
 6199            completion.label = new_label;
 6200        } else {
 6201            log::error!(
 6202                "Resolved completion changed display label from {} to {}. \
 6203                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6204                completion.label.text(),
 6205                new_label.text(),
 6206                completion.label.filter_text(),
 6207                new_label.filter_text()
 6208            );
 6209        }
 6210
 6211        Ok(())
 6212    }
 6213
 6214    async fn resolve_completion_remote(
 6215        project_id: u64,
 6216        server_id: LanguageServerId,
 6217        buffer_id: BufferId,
 6218        completions: Rc<RefCell<Box<[Completion]>>>,
 6219        completion_index: usize,
 6220        client: AnyProtoClient,
 6221    ) -> Result<()> {
 6222        let lsp_completion = {
 6223            let completion = &completions.borrow()[completion_index];
 6224            match &completion.source {
 6225                CompletionSource::Lsp {
 6226                    lsp_completion,
 6227                    resolved,
 6228                    server_id: completion_server_id,
 6229                    ..
 6230                } => {
 6231                    anyhow::ensure!(
 6232                        server_id == *completion_server_id,
 6233                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6234                    );
 6235                    if *resolved {
 6236                        return Ok(());
 6237                    }
 6238                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6239                }
 6240                CompletionSource::Custom
 6241                | CompletionSource::Dap { .. }
 6242                | CompletionSource::BufferWord { .. } => {
 6243                    return Ok(());
 6244                }
 6245            }
 6246        };
 6247        let request = proto::ResolveCompletionDocumentation {
 6248            project_id,
 6249            language_server_id: server_id.0 as u64,
 6250            lsp_completion,
 6251            buffer_id: buffer_id.into(),
 6252        };
 6253
 6254        let response = client
 6255            .request(request)
 6256            .await
 6257            .context("completion documentation resolve proto request")?;
 6258        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6259
 6260        let documentation = if response.documentation.is_empty() {
 6261            CompletionDocumentation::Undocumented
 6262        } else if response.documentation_is_markdown {
 6263            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6264        } else if response.documentation.lines().count() <= 1 {
 6265            CompletionDocumentation::SingleLine(response.documentation.into())
 6266        } else {
 6267            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6268        };
 6269
 6270        let mut completions = completions.borrow_mut();
 6271        let completion = &mut completions[completion_index];
 6272        completion.documentation = Some(documentation);
 6273        if let CompletionSource::Lsp {
 6274            insert_range,
 6275            lsp_completion,
 6276            resolved,
 6277            server_id: completion_server_id,
 6278            lsp_defaults: _,
 6279        } = &mut completion.source
 6280        {
 6281            let completion_insert_range = response
 6282                .old_insert_start
 6283                .and_then(deserialize_anchor)
 6284                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6285            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6286
 6287            if *resolved {
 6288                return Ok(());
 6289            }
 6290            anyhow::ensure!(
 6291                server_id == *completion_server_id,
 6292                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6293            );
 6294            *lsp_completion = Box::new(resolved_lsp_completion);
 6295            *resolved = true;
 6296        }
 6297
 6298        let replace_range = response
 6299            .old_replace_start
 6300            .and_then(deserialize_anchor)
 6301            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6302        if let Some((old_replace_start, old_replace_end)) = replace_range
 6303            && !response.new_text.is_empty()
 6304        {
 6305            completion.new_text = response.new_text;
 6306            completion.replace_range = old_replace_start..old_replace_end;
 6307        }
 6308
 6309        Ok(())
 6310    }
 6311
 6312    pub fn apply_additional_edits_for_completion(
 6313        &self,
 6314        buffer_handle: Entity<Buffer>,
 6315        completions: Rc<RefCell<Box<[Completion]>>>,
 6316        completion_index: usize,
 6317        push_to_history: bool,
 6318        cx: &mut Context<Self>,
 6319    ) -> Task<Result<Option<Transaction>>> {
 6320        if let Some((client, project_id)) = self.upstream_client() {
 6321            let buffer = buffer_handle.read(cx);
 6322            let buffer_id = buffer.remote_id();
 6323            cx.spawn(async move |_, cx| {
 6324                let request = {
 6325                    let completion = completions.borrow()[completion_index].clone();
 6326                    proto::ApplyCompletionAdditionalEdits {
 6327                        project_id,
 6328                        buffer_id: buffer_id.into(),
 6329                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6330                            replace_range: completion.replace_range,
 6331                            new_text: completion.new_text,
 6332                            source: completion.source,
 6333                        })),
 6334                    }
 6335                };
 6336
 6337                if let Some(transaction) = client.request(request).await?.transaction {
 6338                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6339                    buffer_handle
 6340                        .update(cx, |buffer, _| {
 6341                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6342                        })?
 6343                        .await?;
 6344                    if push_to_history {
 6345                        buffer_handle.update(cx, |buffer, _| {
 6346                            buffer.push_transaction(transaction.clone(), Instant::now());
 6347                            buffer.finalize_last_transaction();
 6348                        })?;
 6349                    }
 6350                    Ok(Some(transaction))
 6351                } else {
 6352                    Ok(None)
 6353                }
 6354            })
 6355        } else {
 6356            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6357                let completion = &completions.borrow()[completion_index];
 6358                let server_id = completion.source.server_id()?;
 6359                Some(
 6360                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6361                        .1
 6362                        .clone(),
 6363                )
 6364            }) else {
 6365                return Task::ready(Ok(None));
 6366            };
 6367
 6368            cx.spawn(async move |this, cx| {
 6369                Self::resolve_completion_local(
 6370                    server.clone(),
 6371                    completions.clone(),
 6372                    completion_index,
 6373                )
 6374                .await
 6375                .context("resolving completion")?;
 6376                let completion = completions.borrow()[completion_index].clone();
 6377                let additional_text_edits = completion
 6378                    .source
 6379                    .lsp_completion(true)
 6380                    .as_ref()
 6381                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6382                if let Some(edits) = additional_text_edits {
 6383                    let edits = this
 6384                        .update(cx, |this, cx| {
 6385                            this.as_local_mut().unwrap().edits_from_lsp(
 6386                                &buffer_handle,
 6387                                edits,
 6388                                server.server_id(),
 6389                                None,
 6390                                cx,
 6391                            )
 6392                        })?
 6393                        .await?;
 6394
 6395                    buffer_handle.update(cx, |buffer, cx| {
 6396                        buffer.finalize_last_transaction();
 6397                        buffer.start_transaction();
 6398
 6399                        for (range, text) in edits {
 6400                            let primary = &completion.replace_range;
 6401
 6402                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6403                            // and the primary completion is just an insertion (empty range), then this is likely
 6404                            // an auto-import scenario and should not be considered overlapping
 6405                            // https://github.com/zed-industries/zed/issues/26136
 6406                            let is_file_start_auto_import = {
 6407                                let snapshot = buffer.snapshot();
 6408                                let primary_start_point = primary.start.to_point(&snapshot);
 6409                                let range_start_point = range.start.to_point(&snapshot);
 6410
 6411                                let result = primary_start_point.row == 0
 6412                                    && primary_start_point.column == 0
 6413                                    && range_start_point.row == 0
 6414                                    && range_start_point.column == 0;
 6415
 6416                                result
 6417                            };
 6418
 6419                            let has_overlap = if is_file_start_auto_import {
 6420                                false
 6421                            } else {
 6422                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6423                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6424                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6425                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6426                                let result = start_within || end_within;
 6427                                result
 6428                            };
 6429
 6430                            //Skip additional edits which overlap with the primary completion edit
 6431                            //https://github.com/zed-industries/zed/pull/1871
 6432                            if !has_overlap {
 6433                                buffer.edit([(range, text)], None, cx);
 6434                            }
 6435                        }
 6436
 6437                        let transaction = if buffer.end_transaction(cx).is_some() {
 6438                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6439                            if !push_to_history {
 6440                                buffer.forget_transaction(transaction.id);
 6441                            }
 6442                            Some(transaction)
 6443                        } else {
 6444                            None
 6445                        };
 6446                        Ok(transaction)
 6447                    })?
 6448                } else {
 6449                    Ok(None)
 6450                }
 6451            })
 6452        }
 6453    }
 6454
 6455    pub fn pull_diagnostics(
 6456        &mut self,
 6457        buffer: Entity<Buffer>,
 6458        cx: &mut Context<Self>,
 6459    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6460        let buffer_id = buffer.read(cx).remote_id();
 6461
 6462        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6463            let mut suitable_capabilities = None;
 6464            // Are we capable for proto request?
 6465            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6466                &buffer,
 6467                |capabilities| {
 6468                    if let Some(caps) = &capabilities.diagnostic_provider {
 6469                        suitable_capabilities = Some(caps.clone());
 6470                        true
 6471                    } else {
 6472                        false
 6473                    }
 6474                },
 6475                cx,
 6476            );
 6477            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6478            let Some(dynamic_caps) = suitable_capabilities else {
 6479                return Task::ready(Ok(None));
 6480            };
 6481            assert!(any_server_has_diagnostics_provider);
 6482
 6483            let request = GetDocumentDiagnostics {
 6484                previous_result_id: None,
 6485                dynamic_caps,
 6486            };
 6487            let request_task = client.request_lsp(
 6488                upstream_project_id,
 6489                None,
 6490                LSP_REQUEST_TIMEOUT,
 6491                cx.background_executor().clone(),
 6492                request.to_proto(upstream_project_id, buffer.read(cx)),
 6493            );
 6494            cx.background_spawn(async move {
 6495                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6496                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6497                // Do not attempt to further process the dummy responses here.
 6498                let _response = request_task.await?;
 6499                Ok(None)
 6500            })
 6501        } else {
 6502            let servers = buffer.update(cx, |buffer, cx| {
 6503                self.language_servers_for_local_buffer(buffer, cx)
 6504                    .map(|(_, server)| server.clone())
 6505                    .collect::<Vec<_>>()
 6506            });
 6507
 6508            let pull_diagnostics = servers
 6509                .into_iter()
 6510                .flat_map(|server| {
 6511                    let result = maybe!({
 6512                        let local = self.as_local()?;
 6513                        let server_id = server.server_id();
 6514                        let providers_with_identifiers = local
 6515                            .language_server_dynamic_registrations
 6516                            .get(&server_id)
 6517                            .into_iter()
 6518                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6519                            .collect::<Vec<_>>();
 6520                        Some(
 6521                            providers_with_identifiers
 6522                                .into_iter()
 6523                                .map(|dynamic_caps| {
 6524                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6525                                    self.request_lsp(
 6526                                        buffer.clone(),
 6527                                        LanguageServerToQuery::Other(server_id),
 6528                                        GetDocumentDiagnostics {
 6529                                            previous_result_id: result_id,
 6530                                            dynamic_caps,
 6531                                        },
 6532                                        cx,
 6533                                    )
 6534                                })
 6535                                .collect::<Vec<_>>(),
 6536                        )
 6537                    });
 6538
 6539                    result.unwrap_or_default()
 6540                })
 6541                .collect::<Vec<_>>();
 6542
 6543            cx.background_spawn(async move {
 6544                let mut responses = Vec::new();
 6545                for diagnostics in join_all(pull_diagnostics).await {
 6546                    responses.extend(diagnostics?);
 6547                }
 6548                Ok(Some(responses))
 6549            })
 6550        }
 6551    }
 6552
 6553    pub fn applicable_inlay_chunks(
 6554        &mut self,
 6555        buffer: &Entity<Buffer>,
 6556        ranges: &[Range<text::Anchor>],
 6557        cx: &mut Context<Self>,
 6558    ) -> Vec<Range<BufferRow>> {
 6559        self.latest_lsp_data(buffer, cx)
 6560            .inlay_hints
 6561            .applicable_chunks(ranges)
 6562            .map(|chunk| chunk.start..chunk.end)
 6563            .collect()
 6564    }
 6565
 6566    pub fn invalidate_inlay_hints<'a>(
 6567        &'a mut self,
 6568        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6569    ) {
 6570        for buffer_id in for_buffers {
 6571            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6572                lsp_data.inlay_hints.clear();
 6573            }
 6574        }
 6575    }
 6576
 6577    pub fn inlay_hints(
 6578        &mut self,
 6579        invalidate: InvalidationStrategy,
 6580        buffer: Entity<Buffer>,
 6581        ranges: Vec<Range<text::Anchor>>,
 6582        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6583        cx: &mut Context<Self>,
 6584    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6585        let buffer_snapshot = buffer.read(cx).snapshot();
 6586        let for_server = if let InvalidationStrategy::RefreshRequested(server_id) = invalidate {
 6587            Some(server_id)
 6588        } else {
 6589            None
 6590        };
 6591        let invalidate_cache = invalidate.should_invalidate();
 6592        let next_hint_id = self.next_hint_id.clone();
 6593        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6594        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6595        let known_chunks = known_chunks
 6596            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6597            .map(|(_, known_chunks)| known_chunks)
 6598            .unwrap_or_default();
 6599
 6600        let mut hint_fetch_tasks = Vec::new();
 6601        let mut cached_inlay_hints = HashMap::default();
 6602        let mut ranges_to_query = Vec::new();
 6603        let applicable_chunks = existing_inlay_hints
 6604            .applicable_chunks(ranges.as_slice())
 6605            .filter(|chunk| !known_chunks.contains(&(chunk.start..chunk.end)))
 6606            .collect::<Vec<_>>();
 6607        if applicable_chunks.is_empty() {
 6608            return HashMap::default();
 6609        }
 6610
 6611        let last_chunk_number = applicable_chunks.len() - 1;
 6612
 6613        for (i, row_chunk) in applicable_chunks.into_iter().enumerate() {
 6614            match (
 6615                existing_inlay_hints
 6616                    .cached_hints(&row_chunk)
 6617                    .filter(|_| !invalidate_cache)
 6618                    .cloned(),
 6619                existing_inlay_hints
 6620                    .fetched_hints(&row_chunk)
 6621                    .as_ref()
 6622                    .filter(|_| !invalidate_cache)
 6623                    .cloned(),
 6624            ) {
 6625                (None, None) => {
 6626                    let end = if last_chunk_number == i {
 6627                        Point::new(row_chunk.end, buffer_snapshot.line_len(row_chunk.end))
 6628                    } else {
 6629                        Point::new(row_chunk.end, 0)
 6630                    };
 6631                    ranges_to_query.push((
 6632                        row_chunk,
 6633                        buffer_snapshot.anchor_before(Point::new(row_chunk.start, 0))
 6634                            ..buffer_snapshot.anchor_after(end),
 6635                    ));
 6636                }
 6637                (None, Some(fetched_hints)) => {
 6638                    hint_fetch_tasks.push((row_chunk, fetched_hints.clone()))
 6639                }
 6640                (Some(cached_hints), None) => {
 6641                    for (server_id, cached_hints) in cached_hints {
 6642                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6643                            cached_inlay_hints
 6644                                .entry(row_chunk.start..row_chunk.end)
 6645                                .or_insert_with(HashMap::default)
 6646                                .entry(server_id)
 6647                                .or_insert_with(Vec::new)
 6648                                .extend(cached_hints);
 6649                        }
 6650                    }
 6651                }
 6652                (Some(cached_hints), Some(fetched_hints)) => {
 6653                    hint_fetch_tasks.push((row_chunk, fetched_hints.clone()));
 6654                    for (server_id, cached_hints) in cached_hints {
 6655                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6656                            cached_inlay_hints
 6657                                .entry(row_chunk.start..row_chunk.end)
 6658                                .or_insert_with(HashMap::default)
 6659                                .entry(server_id)
 6660                                .or_insert_with(Vec::new)
 6661                                .extend(cached_hints);
 6662                        }
 6663                    }
 6664                }
 6665            }
 6666        }
 6667
 6668        let cached_chunk_data = cached_inlay_hints
 6669            .into_iter()
 6670            .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6671            .collect();
 6672        if hint_fetch_tasks.is_empty() && ranges_to_query.is_empty() {
 6673            cached_chunk_data
 6674        } else {
 6675            if invalidate_cache {
 6676                lsp_data.inlay_hints.clear();
 6677            }
 6678
 6679            for (chunk, range_to_query) in ranges_to_query {
 6680                let next_hint_id = next_hint_id.clone();
 6681                let buffer = buffer.clone();
 6682                let new_inlay_hints = cx
 6683                    .spawn(async move |lsp_store, cx| {
 6684                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6685                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6686                        })?;
 6687                        new_fetch_task
 6688                            .await
 6689                            .and_then(|new_hints_by_server| {
 6690                                lsp_store.update(cx, |lsp_store, cx| {
 6691                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6692                                    let update_cache = !lsp_data
 6693                                        .buffer_version
 6694                                        .changed_since(&buffer.read(cx).version());
 6695                                    new_hints_by_server
 6696                                        .into_iter()
 6697                                        .map(|(server_id, new_hints)| {
 6698                                            let new_hints = new_hints
 6699                                                .into_iter()
 6700                                                .map(|new_hint| {
 6701                                                    (
 6702                                                        InlayId::Hint(next_hint_id.fetch_add(
 6703                                                            1,
 6704                                                            atomic::Ordering::AcqRel,
 6705                                                        )),
 6706                                                        new_hint,
 6707                                                    )
 6708                                                })
 6709                                                .collect::<Vec<_>>();
 6710                                            if update_cache {
 6711                                                lsp_data.inlay_hints.insert_new_hints(
 6712                                                    chunk,
 6713                                                    server_id,
 6714                                                    new_hints.clone(),
 6715                                                );
 6716                                            }
 6717                                            (server_id, new_hints)
 6718                                        })
 6719                                        .collect()
 6720                                })
 6721                            })
 6722                            .map_err(Arc::new)
 6723                    })
 6724                    .shared();
 6725
 6726                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6727                *fetch_task = Some(new_inlay_hints.clone());
 6728                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6729            }
 6730
 6731            let mut combined_data = cached_chunk_data;
 6732            combined_data.extend(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6733                (
 6734                    chunk.start..chunk.end,
 6735                    cx.spawn(async move |_, _| {
 6736                        hints_fetch.await.map_err(|e| {
 6737                            if e.error_code() != ErrorCode::Internal {
 6738                                anyhow!(e.error_code())
 6739                            } else {
 6740                                anyhow!("{e:#}")
 6741                            }
 6742                        })
 6743                    }),
 6744                )
 6745            }));
 6746            combined_data
 6747        }
 6748    }
 6749
 6750    fn fetch_inlay_hints(
 6751        &mut self,
 6752        for_server: Option<LanguageServerId>,
 6753        buffer: &Entity<Buffer>,
 6754        range: Range<Anchor>,
 6755        cx: &mut Context<Self>,
 6756    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6757        let request = InlayHints {
 6758            range: range.clone(),
 6759        };
 6760        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6761            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6762                return Task::ready(Ok(HashMap::default()));
 6763            }
 6764            let request_task = upstream_client.request_lsp(
 6765                project_id,
 6766                for_server.map(|id| id.to_proto()),
 6767                LSP_REQUEST_TIMEOUT,
 6768                cx.background_executor().clone(),
 6769                request.to_proto(project_id, buffer.read(cx)),
 6770            );
 6771            let buffer = buffer.clone();
 6772            cx.spawn(async move |weak_lsp_store, cx| {
 6773                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6774                    return Ok(HashMap::default());
 6775                };
 6776                let Some(responses) = request_task.await? else {
 6777                    return Ok(HashMap::default());
 6778                };
 6779
 6780                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 6781                    let lsp_store = lsp_store.clone();
 6782                    let buffer = buffer.clone();
 6783                    let cx = cx.clone();
 6784                    let request = request.clone();
 6785                    async move {
 6786                        (
 6787                            LanguageServerId::from_proto(response.server_id),
 6788                            request
 6789                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6790                                .await,
 6791                        )
 6792                    }
 6793                }))
 6794                .await;
 6795
 6796                let mut has_errors = false;
 6797                let inlay_hints = inlay_hints
 6798                    .into_iter()
 6799                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 6800                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 6801                        Err(e) => {
 6802                            has_errors = true;
 6803                            log::error!("{e:#}");
 6804                            None
 6805                        }
 6806                    })
 6807                    .collect::<HashMap<_, _>>();
 6808                anyhow::ensure!(
 6809                    !has_errors || !inlay_hints.is_empty(),
 6810                    "Failed to fetch inlay hints"
 6811                );
 6812                Ok(inlay_hints)
 6813            })
 6814        } else {
 6815            let inlay_hints_task = match for_server {
 6816                Some(server_id) => {
 6817                    let server_task = self.request_lsp(
 6818                        buffer.clone(),
 6819                        LanguageServerToQuery::Other(server_id),
 6820                        request,
 6821                        cx,
 6822                    );
 6823                    cx.background_spawn(async move {
 6824                        let mut responses = Vec::new();
 6825                        match server_task.await {
 6826                            Ok(response) => responses.push((server_id, response)),
 6827                            Err(e) => log::error!(
 6828                                "Error handling response for inlay hints request: {e:#}"
 6829                            ),
 6830                        }
 6831                        responses
 6832                    })
 6833                }
 6834                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 6835            };
 6836            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 6837            cx.background_spawn(async move {
 6838                Ok(inlay_hints_task
 6839                    .await
 6840                    .into_iter()
 6841                    .map(|(server_id, mut new_hints)| {
 6842                        new_hints.retain(|hint| {
 6843                            hint.position.is_valid(&buffer_snapshot)
 6844                                && range.start.is_valid(&buffer_snapshot)
 6845                                && range.end.is_valid(&buffer_snapshot)
 6846                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 6847                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 6848                        });
 6849                        (server_id, new_hints)
 6850                    })
 6851                    .collect())
 6852            })
 6853        }
 6854    }
 6855
 6856    pub fn pull_diagnostics_for_buffer(
 6857        &mut self,
 6858        buffer: Entity<Buffer>,
 6859        cx: &mut Context<Self>,
 6860    ) -> Task<anyhow::Result<()>> {
 6861        let diagnostics = self.pull_diagnostics(buffer, cx);
 6862        cx.spawn(async move |lsp_store, cx| {
 6863            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6864                return Ok(());
 6865            };
 6866            lsp_store.update(cx, |lsp_store, cx| {
 6867                if lsp_store.as_local().is_none() {
 6868                    return;
 6869                }
 6870
 6871                let mut unchanged_buffers = HashSet::default();
 6872                let mut changed_buffers = HashSet::default();
 6873                let server_diagnostics_updates = diagnostics
 6874                    .into_iter()
 6875                    .filter_map(|diagnostics_set| match diagnostics_set {
 6876                        LspPullDiagnostics::Response {
 6877                            server_id,
 6878                            uri,
 6879                            diagnostics,
 6880                        } => Some((server_id, uri, diagnostics)),
 6881                        LspPullDiagnostics::Default => None,
 6882                    })
 6883                    .fold(
 6884                        HashMap::default(),
 6885                        |mut acc, (server_id, uri, diagnostics)| {
 6886                            let (result_id, diagnostics) = match diagnostics {
 6887                                PulledDiagnostics::Unchanged { result_id } => {
 6888                                    unchanged_buffers.insert(uri.clone());
 6889                                    (Some(result_id), Vec::new())
 6890                                }
 6891                                PulledDiagnostics::Changed {
 6892                                    result_id,
 6893                                    diagnostics,
 6894                                } => {
 6895                                    changed_buffers.insert(uri.clone());
 6896                                    (result_id, diagnostics)
 6897                                }
 6898                            };
 6899                            let disk_based_sources = Cow::Owned(
 6900                                lsp_store
 6901                                    .language_server_adapter_for_id(server_id)
 6902                                    .as_ref()
 6903                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6904                                    .unwrap_or(&[])
 6905                                    .to_vec(),
 6906                            );
 6907                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6908                                DocumentDiagnosticsUpdate {
 6909                                    server_id,
 6910                                    diagnostics: lsp::PublishDiagnosticsParams {
 6911                                        uri,
 6912                                        diagnostics,
 6913                                        version: None,
 6914                                    },
 6915                                    result_id,
 6916                                    disk_based_sources,
 6917                                },
 6918                            );
 6919                            acc
 6920                        },
 6921                    );
 6922
 6923                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6924                    lsp_store
 6925                        .merge_lsp_diagnostics(
 6926                            DiagnosticSourceKind::Pulled,
 6927                            diagnostic_updates,
 6928                            |buffer, old_diagnostic, cx| {
 6929                                File::from_dyn(buffer.file())
 6930                                    .and_then(|file| {
 6931                                        let abs_path = file.as_local()?.abs_path(cx);
 6932                                        lsp::Uri::from_file_path(abs_path).ok()
 6933                                    })
 6934                                    .is_none_or(|buffer_uri| {
 6935                                        unchanged_buffers.contains(&buffer_uri)
 6936                                            || match old_diagnostic.source_kind {
 6937                                                DiagnosticSourceKind::Pulled => {
 6938                                                    !changed_buffers.contains(&buffer_uri)
 6939                                                }
 6940                                                DiagnosticSourceKind::Other
 6941                                                | DiagnosticSourceKind::Pushed => true,
 6942                                            }
 6943                                    })
 6944                            },
 6945                            cx,
 6946                        )
 6947                        .log_err();
 6948                }
 6949            })
 6950        })
 6951    }
 6952
 6953    pub fn document_colors(
 6954        &mut self,
 6955        known_cache_version: Option<usize>,
 6956        buffer: Entity<Buffer>,
 6957        cx: &mut Context<Self>,
 6958    ) -> Option<DocumentColorTask> {
 6959        let version_queried_for = buffer.read(cx).version();
 6960        let buffer_id = buffer.read(cx).remote_id();
 6961
 6962        let current_language_servers = self.as_local().map(|local| {
 6963            local
 6964                .buffers_opened_in_servers
 6965                .get(&buffer_id)
 6966                .cloned()
 6967                .unwrap_or_default()
 6968        });
 6969
 6970        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6971            if let Some(cached_colors) = &lsp_data.document_colors {
 6972                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6973                    let has_different_servers =
 6974                        current_language_servers.is_some_and(|current_language_servers| {
 6975                            current_language_servers
 6976                                != cached_colors.colors.keys().copied().collect()
 6977                        });
 6978                    if !has_different_servers {
 6979                        let cache_version = cached_colors.cache_version;
 6980                        if Some(cache_version) == known_cache_version {
 6981                            return None;
 6982                        } else {
 6983                            return Some(
 6984                                Task::ready(Ok(DocumentColors {
 6985                                    colors: cached_colors
 6986                                        .colors
 6987                                        .values()
 6988                                        .flatten()
 6989                                        .cloned()
 6990                                        .collect(),
 6991                                    cache_version: Some(cache_version),
 6992                                }))
 6993                                .shared(),
 6994                            );
 6995                        }
 6996                    }
 6997                }
 6998            }
 6999        }
 7000
 7001        let color_lsp_data = self
 7002            .latest_lsp_data(&buffer, cx)
 7003            .document_colors
 7004            .get_or_insert_default();
 7005        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7006            && !version_queried_for.changed_since(updating_for)
 7007        {
 7008            return Some(running_update.clone());
 7009        }
 7010        let buffer_version_queried_for = version_queried_for.clone();
 7011        let new_task = cx
 7012            .spawn(async move |lsp_store, cx| {
 7013                cx.background_executor()
 7014                    .timer(Duration::from_millis(30))
 7015                    .await;
 7016                let fetched_colors = lsp_store
 7017                    .update(cx, |lsp_store, cx| {
 7018                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7019                    })?
 7020                    .await
 7021                    .context("fetching document colors")
 7022                    .map_err(Arc::new);
 7023                let fetched_colors = match fetched_colors {
 7024                    Ok(fetched_colors) => {
 7025                        if Some(true)
 7026                            == buffer
 7027                                .update(cx, |buffer, _| {
 7028                                    buffer.version() != buffer_version_queried_for
 7029                                })
 7030                                .ok()
 7031                        {
 7032                            return Ok(DocumentColors::default());
 7033                        }
 7034                        fetched_colors
 7035                    }
 7036                    Err(e) => {
 7037                        lsp_store
 7038                            .update(cx, |lsp_store, _| {
 7039                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7040                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7041                                        document_colors.colors_update = None;
 7042                                    }
 7043                                }
 7044                            })
 7045                            .ok();
 7046                        return Err(e);
 7047                    }
 7048                };
 7049
 7050                lsp_store
 7051                    .update(cx, |lsp_store, cx| {
 7052                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7053                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7054
 7055                        if let Some(fetched_colors) = fetched_colors {
 7056                            if lsp_data.buffer_version == buffer_version_queried_for {
 7057                                lsp_colors.colors.extend(fetched_colors);
 7058                                lsp_colors.cache_version += 1;
 7059                            } else if !lsp_data
 7060                                .buffer_version
 7061                                .changed_since(&buffer_version_queried_for)
 7062                            {
 7063                                lsp_data.buffer_version = buffer_version_queried_for;
 7064                                lsp_colors.colors = fetched_colors;
 7065                                lsp_colors.cache_version += 1;
 7066                            }
 7067                        }
 7068                        lsp_colors.colors_update = None;
 7069                        let colors = lsp_colors
 7070                            .colors
 7071                            .values()
 7072                            .flatten()
 7073                            .cloned()
 7074                            .collect::<HashSet<_>>();
 7075                        DocumentColors {
 7076                            colors,
 7077                            cache_version: Some(lsp_colors.cache_version),
 7078                        }
 7079                    })
 7080                    .map_err(Arc::new)
 7081            })
 7082            .shared();
 7083        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7084        Some(new_task)
 7085    }
 7086
 7087    fn fetch_document_colors_for_buffer(
 7088        &mut self,
 7089        buffer: &Entity<Buffer>,
 7090        cx: &mut Context<Self>,
 7091    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7092        if let Some((client, project_id)) = self.upstream_client() {
 7093            let request = GetDocumentColor {};
 7094            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7095                return Task::ready(Ok(None));
 7096            }
 7097
 7098            let request_task = client.request_lsp(
 7099                project_id,
 7100                None,
 7101                LSP_REQUEST_TIMEOUT,
 7102                cx.background_executor().clone(),
 7103                request.to_proto(project_id, buffer.read(cx)),
 7104            );
 7105            let buffer = buffer.clone();
 7106            cx.spawn(async move |lsp_store, cx| {
 7107                let Some(project) = lsp_store.upgrade() else {
 7108                    return Ok(None);
 7109                };
 7110                let colors = join_all(
 7111                    request_task
 7112                        .await
 7113                        .log_err()
 7114                        .flatten()
 7115                        .map(|response| response.payload)
 7116                        .unwrap_or_default()
 7117                        .into_iter()
 7118                        .map(|color_response| {
 7119                            let response = request.response_from_proto(
 7120                                color_response.response,
 7121                                project.clone(),
 7122                                buffer.clone(),
 7123                                cx.clone(),
 7124                            );
 7125                            async move {
 7126                                (
 7127                                    LanguageServerId::from_proto(color_response.server_id),
 7128                                    response.await.log_err().unwrap_or_default(),
 7129                                )
 7130                            }
 7131                        }),
 7132                )
 7133                .await
 7134                .into_iter()
 7135                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7136                    acc.entry(server_id)
 7137                        .or_insert_with(HashSet::default)
 7138                        .extend(colors);
 7139                    acc
 7140                });
 7141                Ok(Some(colors))
 7142            })
 7143        } else {
 7144            let document_colors_task =
 7145                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7146            cx.background_spawn(async move {
 7147                Ok(Some(
 7148                    document_colors_task
 7149                        .await
 7150                        .into_iter()
 7151                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7152                            acc.entry(server_id)
 7153                                .or_insert_with(HashSet::default)
 7154                                .extend(colors);
 7155                            acc
 7156                        })
 7157                        .into_iter()
 7158                        .collect(),
 7159                ))
 7160            })
 7161        }
 7162    }
 7163
 7164    pub fn signature_help<T: ToPointUtf16>(
 7165        &mut self,
 7166        buffer: &Entity<Buffer>,
 7167        position: T,
 7168        cx: &mut Context<Self>,
 7169    ) -> Task<Option<Vec<SignatureHelp>>> {
 7170        let position = position.to_point_utf16(buffer.read(cx));
 7171
 7172        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7173            let request = GetSignatureHelp { position };
 7174            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7175                return Task::ready(None);
 7176            }
 7177            let request_task = client.request_lsp(
 7178                upstream_project_id,
 7179                None,
 7180                LSP_REQUEST_TIMEOUT,
 7181                cx.background_executor().clone(),
 7182                request.to_proto(upstream_project_id, buffer.read(cx)),
 7183            );
 7184            let buffer = buffer.clone();
 7185            cx.spawn(async move |weak_project, cx| {
 7186                let project = weak_project.upgrade()?;
 7187                let signatures = join_all(
 7188                    request_task
 7189                        .await
 7190                        .log_err()
 7191                        .flatten()
 7192                        .map(|response| response.payload)
 7193                        .unwrap_or_default()
 7194                        .into_iter()
 7195                        .map(|response| {
 7196                            let response = GetSignatureHelp { position }.response_from_proto(
 7197                                response.response,
 7198                                project.clone(),
 7199                                buffer.clone(),
 7200                                cx.clone(),
 7201                            );
 7202                            async move { response.await.log_err().flatten() }
 7203                        }),
 7204                )
 7205                .await
 7206                .into_iter()
 7207                .flatten()
 7208                .collect();
 7209                Some(signatures)
 7210            })
 7211        } else {
 7212            let all_actions_task = self.request_multiple_lsp_locally(
 7213                buffer,
 7214                Some(position),
 7215                GetSignatureHelp { position },
 7216                cx,
 7217            );
 7218            cx.background_spawn(async move {
 7219                Some(
 7220                    all_actions_task
 7221                        .await
 7222                        .into_iter()
 7223                        .flat_map(|(_, actions)| actions)
 7224                        .collect::<Vec<_>>(),
 7225                )
 7226            })
 7227        }
 7228    }
 7229
 7230    pub fn hover(
 7231        &mut self,
 7232        buffer: &Entity<Buffer>,
 7233        position: PointUtf16,
 7234        cx: &mut Context<Self>,
 7235    ) -> Task<Option<Vec<Hover>>> {
 7236        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7237            let request = GetHover { position };
 7238            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7239                return Task::ready(None);
 7240            }
 7241            let request_task = client.request_lsp(
 7242                upstream_project_id,
 7243                None,
 7244                LSP_REQUEST_TIMEOUT,
 7245                cx.background_executor().clone(),
 7246                request.to_proto(upstream_project_id, buffer.read(cx)),
 7247            );
 7248            let buffer = buffer.clone();
 7249            cx.spawn(async move |weak_project, cx| {
 7250                let project = weak_project.upgrade()?;
 7251                let hovers = join_all(
 7252                    request_task
 7253                        .await
 7254                        .log_err()
 7255                        .flatten()
 7256                        .map(|response| response.payload)
 7257                        .unwrap_or_default()
 7258                        .into_iter()
 7259                        .map(|response| {
 7260                            let response = GetHover { position }.response_from_proto(
 7261                                response.response,
 7262                                project.clone(),
 7263                                buffer.clone(),
 7264                                cx.clone(),
 7265                            );
 7266                            async move {
 7267                                response
 7268                                    .await
 7269                                    .log_err()
 7270                                    .flatten()
 7271                                    .and_then(remove_empty_hover_blocks)
 7272                            }
 7273                        }),
 7274                )
 7275                .await
 7276                .into_iter()
 7277                .flatten()
 7278                .collect();
 7279                Some(hovers)
 7280            })
 7281        } else {
 7282            let all_actions_task = self.request_multiple_lsp_locally(
 7283                buffer,
 7284                Some(position),
 7285                GetHover { position },
 7286                cx,
 7287            );
 7288            cx.background_spawn(async move {
 7289                Some(
 7290                    all_actions_task
 7291                        .await
 7292                        .into_iter()
 7293                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7294                        .collect::<Vec<Hover>>(),
 7295                )
 7296            })
 7297        }
 7298    }
 7299
 7300    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7301        let language_registry = self.languages.clone();
 7302
 7303        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7304            let request = upstream_client.request(proto::GetProjectSymbols {
 7305                project_id: *project_id,
 7306                query: query.to_string(),
 7307            });
 7308            cx.foreground_executor().spawn(async move {
 7309                let response = request.await?;
 7310                let mut symbols = Vec::new();
 7311                let core_symbols = response
 7312                    .symbols
 7313                    .into_iter()
 7314                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7315                    .collect::<Vec<_>>();
 7316                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7317                    .await;
 7318                Ok(symbols)
 7319            })
 7320        } else if let Some(local) = self.as_local() {
 7321            struct WorkspaceSymbolsResult {
 7322                server_id: LanguageServerId,
 7323                lsp_adapter: Arc<CachedLspAdapter>,
 7324                worktree: WeakEntity<Worktree>,
 7325                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7326            }
 7327
 7328            let mut requests = Vec::new();
 7329            let mut requested_servers = BTreeSet::new();
 7330            for (seed, state) in local.language_server_ids.iter() {
 7331                let Some(worktree_handle) = self
 7332                    .worktree_store
 7333                    .read(cx)
 7334                    .worktree_for_id(seed.worktree_id, cx)
 7335                else {
 7336                    continue;
 7337                };
 7338                let worktree = worktree_handle.read(cx);
 7339                if !worktree.is_visible() {
 7340                    continue;
 7341                }
 7342
 7343                if !requested_servers.insert(state.id) {
 7344                    continue;
 7345                }
 7346
 7347                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7348                    Some(LanguageServerState::Running {
 7349                        adapter, server, ..
 7350                    }) => (adapter.clone(), server),
 7351
 7352                    _ => continue,
 7353                };
 7354                let supports_workspace_symbol_request =
 7355                    match server.capabilities().workspace_symbol_provider {
 7356                        Some(OneOf::Left(supported)) => supported,
 7357                        Some(OneOf::Right(_)) => true,
 7358                        None => false,
 7359                    };
 7360                if !supports_workspace_symbol_request {
 7361                    continue;
 7362                }
 7363                let worktree_handle = worktree_handle.clone();
 7364                let server_id = server.server_id();
 7365                requests.push(
 7366                        server
 7367                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7368                                lsp::WorkspaceSymbolParams {
 7369                                    query: query.to_string(),
 7370                                    ..Default::default()
 7371                                },
 7372                            )
 7373                            .map(move |response| {
 7374                                let lsp_symbols = response.into_response()
 7375                                    .context("workspace symbols request")
 7376                                    .log_err()
 7377                                    .flatten()
 7378                                    .map(|symbol_response| match symbol_response {
 7379                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7380                                            flat_responses.into_iter().map(|lsp_symbol| {
 7381                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7382                                            }).collect::<Vec<_>>()
 7383                                        }
 7384                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7385                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7386                                                let location = match lsp_symbol.location {
 7387                                                    OneOf::Left(location) => location,
 7388                                                    OneOf::Right(_) => {
 7389                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7390                                                        return None
 7391                                                    }
 7392                                                };
 7393                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7394                                            }).collect::<Vec<_>>()
 7395                                        }
 7396                                    }).unwrap_or_default();
 7397
 7398                                WorkspaceSymbolsResult {
 7399                                    server_id,
 7400                                    lsp_adapter,
 7401                                    worktree: worktree_handle.downgrade(),
 7402                                    lsp_symbols,
 7403                                }
 7404                            }),
 7405                    );
 7406            }
 7407
 7408            cx.spawn(async move |this, cx| {
 7409                let responses = futures::future::join_all(requests).await;
 7410                let this = match this.upgrade() {
 7411                    Some(this) => this,
 7412                    None => return Ok(Vec::new()),
 7413                };
 7414
 7415                let mut symbols = Vec::new();
 7416                for result in responses {
 7417                    let core_symbols = this.update(cx, |this, cx| {
 7418                        result
 7419                            .lsp_symbols
 7420                            .into_iter()
 7421                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7422                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7423                                let source_worktree = result.worktree.upgrade()?;
 7424                                let source_worktree_id = source_worktree.read(cx).id();
 7425
 7426                                let path = if let Some((tree, rel_path)) =
 7427                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7428                                {
 7429                                    let worktree_id = tree.read(cx).id();
 7430                                    SymbolLocation::InProject(ProjectPath {
 7431                                        worktree_id,
 7432                                        path: rel_path,
 7433                                    })
 7434                                } else {
 7435                                    SymbolLocation::OutsideProject {
 7436                                        signature: this.symbol_signature(&abs_path),
 7437                                        abs_path: abs_path.into(),
 7438                                    }
 7439                                };
 7440
 7441                                Some(CoreSymbol {
 7442                                    source_language_server_id: result.server_id,
 7443                                    language_server_name: result.lsp_adapter.name.clone(),
 7444                                    source_worktree_id,
 7445                                    path,
 7446                                    kind: symbol_kind,
 7447                                    name: symbol_name,
 7448                                    range: range_from_lsp(symbol_location.range),
 7449                                })
 7450                            })
 7451                            .collect()
 7452                    })?;
 7453
 7454                    populate_labels_for_symbols(
 7455                        core_symbols,
 7456                        &language_registry,
 7457                        Some(result.lsp_adapter),
 7458                        &mut symbols,
 7459                    )
 7460                    .await;
 7461                }
 7462
 7463                Ok(symbols)
 7464            })
 7465        } else {
 7466            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7467        }
 7468    }
 7469
 7470    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7471        let mut summary = DiagnosticSummary::default();
 7472        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7473            summary.error_count += path_summary.error_count;
 7474            summary.warning_count += path_summary.warning_count;
 7475        }
 7476        summary
 7477    }
 7478
 7479    /// Returns the diagnostic summary for a specific project path.
 7480    pub fn diagnostic_summary_for_path(
 7481        &self,
 7482        project_path: &ProjectPath,
 7483        _: &App,
 7484    ) -> DiagnosticSummary {
 7485        if let Some(summaries) = self
 7486            .diagnostic_summaries
 7487            .get(&project_path.worktree_id)
 7488            .and_then(|map| map.get(&project_path.path))
 7489        {
 7490            let (error_count, warning_count) = summaries.iter().fold(
 7491                (0, 0),
 7492                |(error_count, warning_count), (_language_server_id, summary)| {
 7493                    (
 7494                        error_count + summary.error_count,
 7495                        warning_count + summary.warning_count,
 7496                    )
 7497                },
 7498            );
 7499
 7500            DiagnosticSummary {
 7501                error_count,
 7502                warning_count,
 7503            }
 7504        } else {
 7505            DiagnosticSummary::default()
 7506        }
 7507    }
 7508
 7509    pub fn diagnostic_summaries<'a>(
 7510        &'a self,
 7511        include_ignored: bool,
 7512        cx: &'a App,
 7513    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7514        self.worktree_store
 7515            .read(cx)
 7516            .visible_worktrees(cx)
 7517            .filter_map(|worktree| {
 7518                let worktree = worktree.read(cx);
 7519                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7520            })
 7521            .flat_map(move |(worktree, summaries)| {
 7522                let worktree_id = worktree.id();
 7523                summaries
 7524                    .iter()
 7525                    .filter(move |(path, _)| {
 7526                        include_ignored
 7527                            || worktree
 7528                                .entry_for_path(path.as_ref())
 7529                                .is_some_and(|entry| !entry.is_ignored)
 7530                    })
 7531                    .flat_map(move |(path, summaries)| {
 7532                        summaries.iter().map(move |(server_id, summary)| {
 7533                            (
 7534                                ProjectPath {
 7535                                    worktree_id,
 7536                                    path: path.clone(),
 7537                                },
 7538                                *server_id,
 7539                                *summary,
 7540                            )
 7541                        })
 7542                    })
 7543            })
 7544    }
 7545
 7546    pub fn on_buffer_edited(
 7547        &mut self,
 7548        buffer: Entity<Buffer>,
 7549        cx: &mut Context<Self>,
 7550    ) -> Option<()> {
 7551        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7552            Some(
 7553                self.as_local()?
 7554                    .language_servers_for_buffer(buffer, cx)
 7555                    .map(|i| i.1.clone())
 7556                    .collect(),
 7557            )
 7558        })?;
 7559
 7560        let buffer = buffer.read(cx);
 7561        let file = File::from_dyn(buffer.file())?;
 7562        let abs_path = file.as_local()?.abs_path(cx);
 7563        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7564        let next_snapshot = buffer.text_snapshot();
 7565        for language_server in language_servers {
 7566            let language_server = language_server.clone();
 7567
 7568            let buffer_snapshots = self
 7569                .as_local_mut()
 7570                .unwrap()
 7571                .buffer_snapshots
 7572                .get_mut(&buffer.remote_id())
 7573                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7574            let previous_snapshot = buffer_snapshots.last()?;
 7575
 7576            let build_incremental_change = || {
 7577                buffer
 7578                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7579                        previous_snapshot.snapshot.version(),
 7580                    )
 7581                    .map(|edit| {
 7582                        let edit_start = edit.new.start.0;
 7583                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7584                        let new_text = next_snapshot
 7585                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7586                            .collect();
 7587                        lsp::TextDocumentContentChangeEvent {
 7588                            range: Some(lsp::Range::new(
 7589                                point_to_lsp(edit_start),
 7590                                point_to_lsp(edit_end),
 7591                            )),
 7592                            range_length: None,
 7593                            text: new_text,
 7594                        }
 7595                    })
 7596                    .collect()
 7597            };
 7598
 7599            let document_sync_kind = language_server
 7600                .capabilities()
 7601                .text_document_sync
 7602                .as_ref()
 7603                .and_then(|sync| match sync {
 7604                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7605                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7606                });
 7607
 7608            let content_changes: Vec<_> = match document_sync_kind {
 7609                Some(lsp::TextDocumentSyncKind::FULL) => {
 7610                    vec![lsp::TextDocumentContentChangeEvent {
 7611                        range: None,
 7612                        range_length: None,
 7613                        text: next_snapshot.text(),
 7614                    }]
 7615                }
 7616                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7617                _ => {
 7618                    #[cfg(any(test, feature = "test-support"))]
 7619                    {
 7620                        build_incremental_change()
 7621                    }
 7622
 7623                    #[cfg(not(any(test, feature = "test-support")))]
 7624                    {
 7625                        continue;
 7626                    }
 7627                }
 7628            };
 7629
 7630            let next_version = previous_snapshot.version + 1;
 7631            buffer_snapshots.push(LspBufferSnapshot {
 7632                version: next_version,
 7633                snapshot: next_snapshot.clone(),
 7634            });
 7635
 7636            language_server
 7637                .notify::<lsp::notification::DidChangeTextDocument>(
 7638                    lsp::DidChangeTextDocumentParams {
 7639                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7640                            uri.clone(),
 7641                            next_version,
 7642                        ),
 7643                        content_changes,
 7644                    },
 7645                )
 7646                .ok();
 7647            self.pull_workspace_diagnostics(language_server.server_id());
 7648        }
 7649
 7650        None
 7651    }
 7652
 7653    pub fn on_buffer_saved(
 7654        &mut self,
 7655        buffer: Entity<Buffer>,
 7656        cx: &mut Context<Self>,
 7657    ) -> Option<()> {
 7658        let file = File::from_dyn(buffer.read(cx).file())?;
 7659        let worktree_id = file.worktree_id(cx);
 7660        let abs_path = file.as_local()?.abs_path(cx);
 7661        let text_document = lsp::TextDocumentIdentifier {
 7662            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7663        };
 7664        let local = self.as_local()?;
 7665
 7666        for server in local.language_servers_for_worktree(worktree_id) {
 7667            if let Some(include_text) = include_text(server.as_ref()) {
 7668                let text = if include_text {
 7669                    Some(buffer.read(cx).text())
 7670                } else {
 7671                    None
 7672                };
 7673                server
 7674                    .notify::<lsp::notification::DidSaveTextDocument>(
 7675                        lsp::DidSaveTextDocumentParams {
 7676                            text_document: text_document.clone(),
 7677                            text,
 7678                        },
 7679                    )
 7680                    .ok();
 7681            }
 7682        }
 7683
 7684        let language_servers = buffer.update(cx, |buffer, cx| {
 7685            local.language_server_ids_for_buffer(buffer, cx)
 7686        });
 7687        for language_server_id in language_servers {
 7688            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7689        }
 7690
 7691        None
 7692    }
 7693
 7694    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7695        maybe!(async move {
 7696            let mut refreshed_servers = HashSet::default();
 7697            let servers = lsp_store
 7698                .update(cx, |lsp_store, cx| {
 7699                    let local = lsp_store.as_local()?;
 7700
 7701                    let servers = local
 7702                        .language_server_ids
 7703                        .iter()
 7704                        .filter_map(|(seed, state)| {
 7705                            let worktree = lsp_store
 7706                                .worktree_store
 7707                                .read(cx)
 7708                                .worktree_for_id(seed.worktree_id, cx);
 7709                            let delegate: Arc<dyn LspAdapterDelegate> =
 7710                                worktree.map(|worktree| {
 7711                                    LocalLspAdapterDelegate::new(
 7712                                        local.languages.clone(),
 7713                                        &local.environment,
 7714                                        cx.weak_entity(),
 7715                                        &worktree,
 7716                                        local.http_client.clone(),
 7717                                        local.fs.clone(),
 7718                                        cx,
 7719                                    )
 7720                                })?;
 7721                            let server_id = state.id;
 7722
 7723                            let states = local.language_servers.get(&server_id)?;
 7724
 7725                            match states {
 7726                                LanguageServerState::Starting { .. } => None,
 7727                                LanguageServerState::Running {
 7728                                    adapter, server, ..
 7729                                } => {
 7730                                    let adapter = adapter.clone();
 7731                                    let server = server.clone();
 7732                                    refreshed_servers.insert(server.name());
 7733                                    let toolchain = seed.toolchain.clone();
 7734                                    Some(cx.spawn(async move |_, cx| {
 7735                                        let settings =
 7736                                            LocalLspStore::workspace_configuration_for_adapter(
 7737                                                adapter.adapter.clone(),
 7738                                                &delegate,
 7739                                                toolchain,
 7740                                                cx,
 7741                                            )
 7742                                            .await
 7743                                            .ok()?;
 7744                                        server
 7745                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7746                                                lsp::DidChangeConfigurationParams { settings },
 7747                                            )
 7748                                            .ok()?;
 7749                                        Some(())
 7750                                    }))
 7751                                }
 7752                            }
 7753                        })
 7754                        .collect::<Vec<_>>();
 7755
 7756                    Some(servers)
 7757                })
 7758                .ok()
 7759                .flatten()?;
 7760
 7761            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7762            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7763            // to stop and unregister its language server wrapper.
 7764            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7765            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7766            let _: Vec<Option<()>> = join_all(servers).await;
 7767
 7768            Some(())
 7769        })
 7770        .await;
 7771    }
 7772
 7773    fn maintain_workspace_config(
 7774        external_refresh_requests: watch::Receiver<()>,
 7775        cx: &mut Context<Self>,
 7776    ) -> Task<Result<()>> {
 7777        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7778        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7779
 7780        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7781            *settings_changed_tx.borrow_mut() = ();
 7782        });
 7783
 7784        let mut joint_future =
 7785            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7786        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7787        // - 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).
 7788        // - 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.
 7789        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7790        // - 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,
 7791        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7792        cx.spawn(async move |this, cx| {
 7793            while let Some(()) = joint_future.next().await {
 7794                this.update(cx, |this, cx| {
 7795                    this.refresh_server_tree(cx);
 7796                })
 7797                .ok();
 7798
 7799                Self::refresh_workspace_configurations(&this, cx).await;
 7800            }
 7801
 7802            drop(settings_observation);
 7803            anyhow::Ok(())
 7804        })
 7805    }
 7806
 7807    pub fn language_servers_for_local_buffer<'a>(
 7808        &'a self,
 7809        buffer: &Buffer,
 7810        cx: &mut App,
 7811    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7812        let local = self.as_local();
 7813        let language_server_ids = local
 7814            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7815            .unwrap_or_default();
 7816
 7817        language_server_ids
 7818            .into_iter()
 7819            .filter_map(
 7820                move |server_id| match local?.language_servers.get(&server_id)? {
 7821                    LanguageServerState::Running {
 7822                        adapter, server, ..
 7823                    } => Some((adapter, server)),
 7824                    _ => None,
 7825                },
 7826            )
 7827    }
 7828
 7829    pub fn language_server_for_local_buffer<'a>(
 7830        &'a self,
 7831        buffer: &'a Buffer,
 7832        server_id: LanguageServerId,
 7833        cx: &'a mut App,
 7834    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7835        self.as_local()?
 7836            .language_servers_for_buffer(buffer, cx)
 7837            .find(|(_, s)| s.server_id() == server_id)
 7838    }
 7839
 7840    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7841        self.diagnostic_summaries.remove(&id_to_remove);
 7842        if let Some(local) = self.as_local_mut() {
 7843            let to_remove = local.remove_worktree(id_to_remove, cx);
 7844            for server in to_remove {
 7845                self.language_server_statuses.remove(&server);
 7846            }
 7847        }
 7848    }
 7849
 7850    pub fn shared(
 7851        &mut self,
 7852        project_id: u64,
 7853        downstream_client: AnyProtoClient,
 7854        _: &mut Context<Self>,
 7855    ) {
 7856        self.downstream_client = Some((downstream_client.clone(), project_id));
 7857
 7858        for (server_id, status) in &self.language_server_statuses {
 7859            if let Some(server) = self.language_server_for_id(*server_id) {
 7860                downstream_client
 7861                    .send(proto::StartLanguageServer {
 7862                        project_id,
 7863                        server: Some(proto::LanguageServer {
 7864                            id: server_id.to_proto(),
 7865                            name: status.name.to_string(),
 7866                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7867                        }),
 7868                        capabilities: serde_json::to_string(&server.capabilities())
 7869                            .expect("serializing server LSP capabilities"),
 7870                    })
 7871                    .log_err();
 7872            }
 7873        }
 7874    }
 7875
 7876    pub fn disconnected_from_host(&mut self) {
 7877        self.downstream_client.take();
 7878    }
 7879
 7880    pub fn disconnected_from_ssh_remote(&mut self) {
 7881        if let LspStoreMode::Remote(RemoteLspStore {
 7882            upstream_client, ..
 7883        }) = &mut self.mode
 7884        {
 7885            upstream_client.take();
 7886        }
 7887    }
 7888
 7889    pub(crate) fn set_language_server_statuses_from_proto(
 7890        &mut self,
 7891        project: WeakEntity<Project>,
 7892        language_servers: Vec<proto::LanguageServer>,
 7893        server_capabilities: Vec<String>,
 7894        cx: &mut Context<Self>,
 7895    ) {
 7896        let lsp_logs = cx
 7897            .try_global::<GlobalLogStore>()
 7898            .map(|lsp_store| lsp_store.0.clone());
 7899
 7900        self.language_server_statuses = language_servers
 7901            .into_iter()
 7902            .zip(server_capabilities)
 7903            .map(|(server, server_capabilities)| {
 7904                let server_id = LanguageServerId(server.id as usize);
 7905                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7906                    self.lsp_server_capabilities
 7907                        .insert(server_id, server_capabilities);
 7908                }
 7909
 7910                let name = LanguageServerName::from_proto(server.name);
 7911                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7912
 7913                if let Some(lsp_logs) = &lsp_logs {
 7914                    lsp_logs.update(cx, |lsp_logs, cx| {
 7915                        lsp_logs.add_language_server(
 7916                            // Only remote clients get their language servers set from proto
 7917                            LanguageServerKind::Remote {
 7918                                project: project.clone(),
 7919                            },
 7920                            server_id,
 7921                            Some(name.clone()),
 7922                            worktree,
 7923                            None,
 7924                            cx,
 7925                        );
 7926                    });
 7927                }
 7928
 7929                (
 7930                    server_id,
 7931                    LanguageServerStatus {
 7932                        name,
 7933                        pending_work: Default::default(),
 7934                        has_pending_diagnostic_updates: false,
 7935                        progress_tokens: Default::default(),
 7936                        worktree,
 7937                    },
 7938                )
 7939            })
 7940            .collect();
 7941    }
 7942
 7943    #[cfg(test)]
 7944    pub fn update_diagnostic_entries(
 7945        &mut self,
 7946        server_id: LanguageServerId,
 7947        abs_path: PathBuf,
 7948        result_id: Option<String>,
 7949        version: Option<i32>,
 7950        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7951        cx: &mut Context<Self>,
 7952    ) -> anyhow::Result<()> {
 7953        self.merge_diagnostic_entries(
 7954            vec![DocumentDiagnosticsUpdate {
 7955                diagnostics: DocumentDiagnostics {
 7956                    diagnostics,
 7957                    document_abs_path: abs_path,
 7958                    version,
 7959                },
 7960                result_id,
 7961                server_id,
 7962                disk_based_sources: Cow::Borrowed(&[]),
 7963            }],
 7964            |_, _, _| false,
 7965            cx,
 7966        )?;
 7967        Ok(())
 7968    }
 7969
 7970    pub fn merge_diagnostic_entries<'a>(
 7971        &mut self,
 7972        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7973        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7974        cx: &mut Context<Self>,
 7975    ) -> anyhow::Result<()> {
 7976        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7977        let mut updated_diagnostics_paths = HashMap::default();
 7978        for mut update in diagnostic_updates {
 7979            let abs_path = &update.diagnostics.document_abs_path;
 7980            let server_id = update.server_id;
 7981            let Some((worktree, relative_path)) =
 7982                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7983            else {
 7984                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7985                return Ok(());
 7986            };
 7987
 7988            let worktree_id = worktree.read(cx).id();
 7989            let project_path = ProjectPath {
 7990                worktree_id,
 7991                path: relative_path,
 7992            };
 7993
 7994            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7995                let snapshot = buffer_handle.read(cx).snapshot();
 7996                let buffer = buffer_handle.read(cx);
 7997                let reused_diagnostics = buffer
 7998                    .buffer_diagnostics(Some(server_id))
 7999                    .iter()
 8000                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8001                    .map(|v| {
 8002                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8003                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8004                        DiagnosticEntry {
 8005                            range: start..end,
 8006                            diagnostic: v.diagnostic.clone(),
 8007                        }
 8008                    })
 8009                    .collect::<Vec<_>>();
 8010
 8011                self.as_local_mut()
 8012                    .context("cannot merge diagnostics on a remote LspStore")?
 8013                    .update_buffer_diagnostics(
 8014                        &buffer_handle,
 8015                        server_id,
 8016                        update.result_id,
 8017                        update.diagnostics.version,
 8018                        update.diagnostics.diagnostics.clone(),
 8019                        reused_diagnostics.clone(),
 8020                        cx,
 8021                    )?;
 8022
 8023                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8024            }
 8025
 8026            let updated = worktree.update(cx, |worktree, cx| {
 8027                self.update_worktree_diagnostics(
 8028                    worktree.id(),
 8029                    server_id,
 8030                    project_path.path.clone(),
 8031                    update.diagnostics.diagnostics,
 8032                    cx,
 8033                )
 8034            })?;
 8035            match updated {
 8036                ControlFlow::Continue(new_summary) => {
 8037                    if let Some((project_id, new_summary)) = new_summary {
 8038                        match &mut diagnostics_summary {
 8039                            Some(diagnostics_summary) => {
 8040                                diagnostics_summary
 8041                                    .more_summaries
 8042                                    .push(proto::DiagnosticSummary {
 8043                                        path: project_path.path.as_ref().to_proto(),
 8044                                        language_server_id: server_id.0 as u64,
 8045                                        error_count: new_summary.error_count,
 8046                                        warning_count: new_summary.warning_count,
 8047                                    })
 8048                            }
 8049                            None => {
 8050                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8051                                    project_id,
 8052                                    worktree_id: worktree_id.to_proto(),
 8053                                    summary: Some(proto::DiagnosticSummary {
 8054                                        path: project_path.path.as_ref().to_proto(),
 8055                                        language_server_id: server_id.0 as u64,
 8056                                        error_count: new_summary.error_count,
 8057                                        warning_count: new_summary.warning_count,
 8058                                    }),
 8059                                    more_summaries: Vec::new(),
 8060                                })
 8061                            }
 8062                        }
 8063                    }
 8064                    updated_diagnostics_paths
 8065                        .entry(server_id)
 8066                        .or_insert_with(Vec::new)
 8067                        .push(project_path);
 8068                }
 8069                ControlFlow::Break(()) => {}
 8070            }
 8071        }
 8072
 8073        if let Some((diagnostics_summary, (downstream_client, _))) =
 8074            diagnostics_summary.zip(self.downstream_client.as_ref())
 8075        {
 8076            downstream_client.send(diagnostics_summary).log_err();
 8077        }
 8078        for (server_id, paths) in updated_diagnostics_paths {
 8079            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8080        }
 8081        Ok(())
 8082    }
 8083
 8084    fn update_worktree_diagnostics(
 8085        &mut self,
 8086        worktree_id: WorktreeId,
 8087        server_id: LanguageServerId,
 8088        path_in_worktree: Arc<RelPath>,
 8089        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8090        _: &mut Context<Worktree>,
 8091    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8092        let local = match &mut self.mode {
 8093            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8094            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8095        };
 8096
 8097        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8098        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8099        let summaries_by_server_id = summaries_for_tree
 8100            .entry(path_in_worktree.clone())
 8101            .or_default();
 8102
 8103        let old_summary = summaries_by_server_id
 8104            .remove(&server_id)
 8105            .unwrap_or_default();
 8106
 8107        let new_summary = DiagnosticSummary::new(&diagnostics);
 8108        if new_summary.is_empty() {
 8109            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8110            {
 8111                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8112                    diagnostics_by_server_id.remove(ix);
 8113                }
 8114                if diagnostics_by_server_id.is_empty() {
 8115                    diagnostics_for_tree.remove(&path_in_worktree);
 8116                }
 8117            }
 8118        } else {
 8119            summaries_by_server_id.insert(server_id, new_summary);
 8120            let diagnostics_by_server_id = diagnostics_for_tree
 8121                .entry(path_in_worktree.clone())
 8122                .or_default();
 8123            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8124                Ok(ix) => {
 8125                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8126                }
 8127                Err(ix) => {
 8128                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8129                }
 8130            }
 8131        }
 8132
 8133        if !old_summary.is_empty() || !new_summary.is_empty() {
 8134            if let Some((_, project_id)) = &self.downstream_client {
 8135                Ok(ControlFlow::Continue(Some((
 8136                    *project_id,
 8137                    proto::DiagnosticSummary {
 8138                        path: path_in_worktree.to_proto(),
 8139                        language_server_id: server_id.0 as u64,
 8140                        error_count: new_summary.error_count as u32,
 8141                        warning_count: new_summary.warning_count as u32,
 8142                    },
 8143                ))))
 8144            } else {
 8145                Ok(ControlFlow::Continue(None))
 8146            }
 8147        } else {
 8148            Ok(ControlFlow::Break(()))
 8149        }
 8150    }
 8151
 8152    pub fn open_buffer_for_symbol(
 8153        &mut self,
 8154        symbol: &Symbol,
 8155        cx: &mut Context<Self>,
 8156    ) -> Task<Result<Entity<Buffer>>> {
 8157        if let Some((client, project_id)) = self.upstream_client() {
 8158            let request = client.request(proto::OpenBufferForSymbol {
 8159                project_id,
 8160                symbol: Some(Self::serialize_symbol(symbol)),
 8161            });
 8162            cx.spawn(async move |this, cx| {
 8163                let response = request.await?;
 8164                let buffer_id = BufferId::new(response.buffer_id)?;
 8165                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8166                    .await
 8167            })
 8168        } else if let Some(local) = self.as_local() {
 8169            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8170                seed.worktree_id == symbol.source_worktree_id
 8171                    && state.id == symbol.source_language_server_id
 8172                    && symbol.language_server_name == seed.name
 8173            });
 8174            if !is_valid {
 8175                return Task::ready(Err(anyhow!(
 8176                    "language server for worktree and language not found"
 8177                )));
 8178            };
 8179
 8180            let symbol_abs_path = match &symbol.path {
 8181                SymbolLocation::InProject(project_path) => self
 8182                    .worktree_store
 8183                    .read(cx)
 8184                    .absolutize(&project_path, cx)
 8185                    .context("no such worktree"),
 8186                SymbolLocation::OutsideProject {
 8187                    abs_path,
 8188                    signature: _,
 8189                } => Ok(abs_path.to_path_buf()),
 8190            };
 8191            let symbol_abs_path = match symbol_abs_path {
 8192                Ok(abs_path) => abs_path,
 8193                Err(err) => return Task::ready(Err(err)),
 8194            };
 8195            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8196                uri
 8197            } else {
 8198                return Task::ready(Err(anyhow!("invalid symbol path")));
 8199            };
 8200
 8201            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8202        } else {
 8203            Task::ready(Err(anyhow!("no upstream client or local store")))
 8204        }
 8205    }
 8206
 8207    pub(crate) fn open_local_buffer_via_lsp(
 8208        &mut self,
 8209        abs_path: lsp::Uri,
 8210        language_server_id: LanguageServerId,
 8211        cx: &mut Context<Self>,
 8212    ) -> Task<Result<Entity<Buffer>>> {
 8213        cx.spawn(async move |lsp_store, cx| {
 8214            // Escape percent-encoded string.
 8215            let current_scheme = abs_path.scheme().to_owned();
 8216            // Uri is immutable, so we can't modify the scheme
 8217
 8218            let abs_path = abs_path
 8219                .to_file_path()
 8220                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8221            let p = abs_path.clone();
 8222            let yarn_worktree = lsp_store
 8223                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8224                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8225                        cx.spawn(async move |this, cx| {
 8226                            let t = this
 8227                                .update(cx, |this, cx| this.process_path(&p, ¤t_scheme, cx))
 8228                                .ok()?;
 8229                            t.await
 8230                        })
 8231                    }),
 8232                    None => Task::ready(None),
 8233                })?
 8234                .await;
 8235            let (worktree_root_target, known_relative_path) =
 8236                if let Some((zip_root, relative_path)) = yarn_worktree {
 8237                    (zip_root, Some(relative_path))
 8238                } else {
 8239                    (Arc::<Path>::from(abs_path.as_path()), None)
 8240                };
 8241            let (worktree, relative_path) = if let Some(result) =
 8242                lsp_store.update(cx, |lsp_store, cx| {
 8243                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8244                        worktree_store.find_worktree(&worktree_root_target, cx)
 8245                    })
 8246                })? {
 8247                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8248                (result.0, relative_path)
 8249            } else {
 8250                let worktree = lsp_store
 8251                    .update(cx, |lsp_store, cx| {
 8252                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8253                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8254                        })
 8255                    })?
 8256                    .await?;
 8257                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8258                    lsp_store
 8259                        .update(cx, |lsp_store, cx| {
 8260                            if let Some(local) = lsp_store.as_local_mut() {
 8261                                local.register_language_server_for_invisible_worktree(
 8262                                    &worktree,
 8263                                    language_server_id,
 8264                                    cx,
 8265                                )
 8266                            }
 8267                        })
 8268                        .ok();
 8269                }
 8270                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8271                let relative_path = if let Some(known_path) = known_relative_path {
 8272                    known_path
 8273                } else {
 8274                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8275                        .into_arc()
 8276                };
 8277                (worktree, relative_path)
 8278            };
 8279            let project_path = ProjectPath {
 8280                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8281                path: relative_path,
 8282            };
 8283            lsp_store
 8284                .update(cx, |lsp_store, cx| {
 8285                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8286                        buffer_store.open_buffer(project_path, cx)
 8287                    })
 8288                })?
 8289                .await
 8290        })
 8291    }
 8292
 8293    fn request_multiple_lsp_locally<P, R>(
 8294        &mut self,
 8295        buffer: &Entity<Buffer>,
 8296        position: Option<P>,
 8297        request: R,
 8298        cx: &mut Context<Self>,
 8299    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8300    where
 8301        P: ToOffset,
 8302        R: LspCommand + Clone,
 8303        <R::LspRequest as lsp::request::Request>::Result: Send,
 8304        <R::LspRequest as lsp::request::Request>::Params: Send,
 8305    {
 8306        let Some(local) = self.as_local() else {
 8307            return Task::ready(Vec::new());
 8308        };
 8309
 8310        let snapshot = buffer.read(cx).snapshot();
 8311        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8312
 8313        let server_ids = buffer.update(cx, |buffer, cx| {
 8314            local
 8315                .language_servers_for_buffer(buffer, cx)
 8316                .filter(|(adapter, _)| {
 8317                    scope
 8318                        .as_ref()
 8319                        .map(|scope| scope.language_allowed(&adapter.name))
 8320                        .unwrap_or(true)
 8321                })
 8322                .map(|(_, server)| server.server_id())
 8323                .filter(|server_id| {
 8324                    self.as_local().is_none_or(|local| {
 8325                        local
 8326                            .buffers_opened_in_servers
 8327                            .get(&snapshot.remote_id())
 8328                            .is_some_and(|servers| servers.contains(server_id))
 8329                    })
 8330                })
 8331                .collect::<Vec<_>>()
 8332        });
 8333
 8334        let mut response_results = server_ids
 8335            .into_iter()
 8336            .map(|server_id| {
 8337                let task = self.request_lsp(
 8338                    buffer.clone(),
 8339                    LanguageServerToQuery::Other(server_id),
 8340                    request.clone(),
 8341                    cx,
 8342                );
 8343                async move { (server_id, task.await) }
 8344            })
 8345            .collect::<FuturesUnordered<_>>();
 8346
 8347        cx.background_spawn(async move {
 8348            let mut responses = Vec::with_capacity(response_results.len());
 8349            while let Some((server_id, response_result)) = response_results.next().await {
 8350                match response_result {
 8351                    Ok(response) => responses.push((server_id, response)),
 8352                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8353                }
 8354            }
 8355            responses
 8356        })
 8357    }
 8358
 8359    async fn handle_lsp_command<T: LspCommand>(
 8360        this: Entity<Self>,
 8361        envelope: TypedEnvelope<T::ProtoRequest>,
 8362        mut cx: AsyncApp,
 8363    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8364    where
 8365        <T::LspRequest as lsp::request::Request>::Params: Send,
 8366        <T::LspRequest as lsp::request::Request>::Result: Send,
 8367    {
 8368        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8369        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8370        let buffer_handle = this.update(&mut cx, |this, cx| {
 8371            this.buffer_store.read(cx).get_existing(buffer_id)
 8372        })??;
 8373        let request = T::from_proto(
 8374            envelope.payload,
 8375            this.clone(),
 8376            buffer_handle.clone(),
 8377            cx.clone(),
 8378        )
 8379        .await?;
 8380        let response = this
 8381            .update(&mut cx, |this, cx| {
 8382                this.request_lsp(
 8383                    buffer_handle.clone(),
 8384                    LanguageServerToQuery::FirstCapable,
 8385                    request,
 8386                    cx,
 8387                )
 8388            })?
 8389            .await?;
 8390        this.update(&mut cx, |this, cx| {
 8391            Ok(T::response_to_proto(
 8392                response,
 8393                this,
 8394                sender_id,
 8395                &buffer_handle.read(cx).version(),
 8396                cx,
 8397            ))
 8398        })?
 8399    }
 8400
 8401    async fn handle_lsp_query(
 8402        lsp_store: Entity<Self>,
 8403        envelope: TypedEnvelope<proto::LspQuery>,
 8404        mut cx: AsyncApp,
 8405    ) -> Result<proto::Ack> {
 8406        use proto::lsp_query::Request;
 8407        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8408        let lsp_query = envelope.payload;
 8409        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8410        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8411        match lsp_query.request.context("invalid LSP query request")? {
 8412            Request::GetReferences(get_references) => {
 8413                let position = get_references.position.clone().and_then(deserialize_anchor);
 8414                Self::query_lsp_locally::<GetReferences>(
 8415                    lsp_store,
 8416                    server_id,
 8417                    sender_id,
 8418                    lsp_request_id,
 8419                    get_references,
 8420                    position,
 8421                    &mut cx,
 8422                )
 8423                .await?;
 8424            }
 8425            Request::GetDocumentColor(get_document_color) => {
 8426                Self::query_lsp_locally::<GetDocumentColor>(
 8427                    lsp_store,
 8428                    server_id,
 8429                    sender_id,
 8430                    lsp_request_id,
 8431                    get_document_color,
 8432                    None,
 8433                    &mut cx,
 8434                )
 8435                .await?;
 8436            }
 8437            Request::GetHover(get_hover) => {
 8438                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8439                Self::query_lsp_locally::<GetHover>(
 8440                    lsp_store,
 8441                    server_id,
 8442                    sender_id,
 8443                    lsp_request_id,
 8444                    get_hover,
 8445                    position,
 8446                    &mut cx,
 8447                )
 8448                .await?;
 8449            }
 8450            Request::GetCodeActions(get_code_actions) => {
 8451                Self::query_lsp_locally::<GetCodeActions>(
 8452                    lsp_store,
 8453                    server_id,
 8454                    sender_id,
 8455                    lsp_request_id,
 8456                    get_code_actions,
 8457                    None,
 8458                    &mut cx,
 8459                )
 8460                .await?;
 8461            }
 8462            Request::GetSignatureHelp(get_signature_help) => {
 8463                let position = get_signature_help
 8464                    .position
 8465                    .clone()
 8466                    .and_then(deserialize_anchor);
 8467                Self::query_lsp_locally::<GetSignatureHelp>(
 8468                    lsp_store,
 8469                    server_id,
 8470                    sender_id,
 8471                    lsp_request_id,
 8472                    get_signature_help,
 8473                    position,
 8474                    &mut cx,
 8475                )
 8476                .await?;
 8477            }
 8478            Request::GetCodeLens(get_code_lens) => {
 8479                Self::query_lsp_locally::<GetCodeLens>(
 8480                    lsp_store,
 8481                    server_id,
 8482                    sender_id,
 8483                    lsp_request_id,
 8484                    get_code_lens,
 8485                    None,
 8486                    &mut cx,
 8487                )
 8488                .await?;
 8489            }
 8490            Request::GetDefinition(get_definition) => {
 8491                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8492                Self::query_lsp_locally::<GetDefinitions>(
 8493                    lsp_store,
 8494                    server_id,
 8495                    sender_id,
 8496                    lsp_request_id,
 8497                    get_definition,
 8498                    position,
 8499                    &mut cx,
 8500                )
 8501                .await?;
 8502            }
 8503            Request::GetDeclaration(get_declaration) => {
 8504                let position = get_declaration
 8505                    .position
 8506                    .clone()
 8507                    .and_then(deserialize_anchor);
 8508                Self::query_lsp_locally::<GetDeclarations>(
 8509                    lsp_store,
 8510                    server_id,
 8511                    sender_id,
 8512                    lsp_request_id,
 8513                    get_declaration,
 8514                    position,
 8515                    &mut cx,
 8516                )
 8517                .await?;
 8518            }
 8519            Request::GetTypeDefinition(get_type_definition) => {
 8520                let position = get_type_definition
 8521                    .position
 8522                    .clone()
 8523                    .and_then(deserialize_anchor);
 8524                Self::query_lsp_locally::<GetTypeDefinitions>(
 8525                    lsp_store,
 8526                    server_id,
 8527                    sender_id,
 8528                    lsp_request_id,
 8529                    get_type_definition,
 8530                    position,
 8531                    &mut cx,
 8532                )
 8533                .await?;
 8534            }
 8535            Request::GetImplementation(get_implementation) => {
 8536                let position = get_implementation
 8537                    .position
 8538                    .clone()
 8539                    .and_then(deserialize_anchor);
 8540                Self::query_lsp_locally::<GetImplementations>(
 8541                    lsp_store,
 8542                    server_id,
 8543                    sender_id,
 8544                    lsp_request_id,
 8545                    get_implementation,
 8546                    position,
 8547                    &mut cx,
 8548                )
 8549                .await?;
 8550            }
 8551            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8552                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8553                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8554                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8555                    this.buffer_store.read(cx).get_existing(buffer_id)
 8556                })??;
 8557                buffer
 8558                    .update(&mut cx, |buffer, _| {
 8559                        buffer.wait_for_version(version.clone())
 8560                    })?
 8561                    .await?;
 8562                lsp_store.update(&mut cx, |lsp_store, cx| {
 8563                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8564                    let key = LspKey {
 8565                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8566                        server_queried: server_id,
 8567                    };
 8568                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8569                    ) {
 8570                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8571                            lsp_requests.clear();
 8572                        };
 8573                    }
 8574
 8575                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8576                    existing_queries.insert(
 8577                        lsp_request_id,
 8578                        cx.spawn(async move |lsp_store, cx| {
 8579                            let diagnostics_pull = lsp_store
 8580                                .update(cx, |lsp_store, cx| {
 8581                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8582                                })
 8583                                .ok();
 8584                            if let Some(diagnostics_pull) = diagnostics_pull {
 8585                                match diagnostics_pull.await {
 8586                                    Ok(()) => {}
 8587                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8588                                };
 8589                            }
 8590                        }),
 8591                    );
 8592                })?;
 8593            }
 8594            Request::InlayHints(inlay_hints) => {
 8595                let query_start = inlay_hints
 8596                    .start
 8597                    .clone()
 8598                    .and_then(deserialize_anchor)
 8599                    .context("invalid inlay hints range start")?;
 8600                let query_end = inlay_hints
 8601                    .end
 8602                    .clone()
 8603                    .and_then(deserialize_anchor)
 8604                    .context("invalid inlay hints range end")?;
 8605                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8606                    &lsp_store,
 8607                    server_id,
 8608                    lsp_request_id,
 8609                    &inlay_hints,
 8610                    query_start..query_end,
 8611                    &mut cx,
 8612                )
 8613                .await
 8614                .context("preparing inlay hints request")?;
 8615                Self::query_lsp_locally::<InlayHints>(
 8616                    lsp_store,
 8617                    server_id,
 8618                    sender_id,
 8619                    lsp_request_id,
 8620                    inlay_hints,
 8621                    None,
 8622                    &mut cx,
 8623                )
 8624                .await
 8625                .context("querying for inlay hints")?
 8626            }
 8627        }
 8628        Ok(proto::Ack {})
 8629    }
 8630
 8631    async fn handle_lsp_query_response(
 8632        lsp_store: Entity<Self>,
 8633        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8634        cx: AsyncApp,
 8635    ) -> Result<()> {
 8636        lsp_store.read_with(&cx, |lsp_store, _| {
 8637            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8638                upstream_client.handle_lsp_response(envelope.clone());
 8639            }
 8640        })?;
 8641        Ok(())
 8642    }
 8643
 8644    async fn handle_apply_code_action(
 8645        this: Entity<Self>,
 8646        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8647        mut cx: AsyncApp,
 8648    ) -> Result<proto::ApplyCodeActionResponse> {
 8649        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8650        let action =
 8651            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8652        let apply_code_action = this.update(&mut cx, |this, cx| {
 8653            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8654            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8655            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8656        })??;
 8657
 8658        let project_transaction = apply_code_action.await?;
 8659        let project_transaction = this.update(&mut cx, |this, cx| {
 8660            this.buffer_store.update(cx, |buffer_store, cx| {
 8661                buffer_store.serialize_project_transaction_for_peer(
 8662                    project_transaction,
 8663                    sender_id,
 8664                    cx,
 8665                )
 8666            })
 8667        })?;
 8668        Ok(proto::ApplyCodeActionResponse {
 8669            transaction: Some(project_transaction),
 8670        })
 8671    }
 8672
 8673    async fn handle_register_buffer_with_language_servers(
 8674        this: Entity<Self>,
 8675        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8676        mut cx: AsyncApp,
 8677    ) -> Result<proto::Ack> {
 8678        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8679        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8680        this.update(&mut cx, |this, cx| {
 8681            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8682                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8683                    project_id: upstream_project_id,
 8684                    buffer_id: buffer_id.to_proto(),
 8685                    only_servers: envelope.payload.only_servers,
 8686                });
 8687            }
 8688
 8689            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8690                anyhow::bail!("buffer is not open");
 8691            };
 8692
 8693            let handle = this.register_buffer_with_language_servers(
 8694                &buffer,
 8695                envelope
 8696                    .payload
 8697                    .only_servers
 8698                    .into_iter()
 8699                    .filter_map(|selector| {
 8700                        Some(match selector.selector? {
 8701                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8702                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8703                            }
 8704                            proto::language_server_selector::Selector::Name(name) => {
 8705                                LanguageServerSelector::Name(LanguageServerName(
 8706                                    SharedString::from(name),
 8707                                ))
 8708                            }
 8709                        })
 8710                    })
 8711                    .collect(),
 8712                false,
 8713                cx,
 8714            );
 8715            this.buffer_store().update(cx, |buffer_store, _| {
 8716                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8717            });
 8718
 8719            Ok(())
 8720        })??;
 8721        Ok(proto::Ack {})
 8722    }
 8723
 8724    async fn handle_rename_project_entry(
 8725        this: Entity<Self>,
 8726        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8727        mut cx: AsyncApp,
 8728    ) -> Result<proto::ProjectEntryResponse> {
 8729        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8730        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8731        let new_path =
 8732            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8733
 8734        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8735            .update(&mut cx, |this, cx| {
 8736                let (worktree, entry) = this
 8737                    .worktree_store
 8738                    .read(cx)
 8739                    .worktree_and_entry_for_id(entry_id, cx)?;
 8740                let new_worktree = this
 8741                    .worktree_store
 8742                    .read(cx)
 8743                    .worktree_for_id(new_worktree_id, cx)?;
 8744                Some((
 8745                    this.worktree_store.clone(),
 8746                    worktree,
 8747                    new_worktree,
 8748                    entry.clone(),
 8749                ))
 8750            })?
 8751            .context("worktree not found")?;
 8752        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8753            (worktree.absolutize(&old_entry.path), worktree.id())
 8754        })?;
 8755        let new_abs_path =
 8756            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8757
 8758        let _transaction = Self::will_rename_entry(
 8759            this.downgrade(),
 8760            old_worktree_id,
 8761            &old_abs_path,
 8762            &new_abs_path,
 8763            old_entry.is_dir(),
 8764            cx.clone(),
 8765        )
 8766        .await;
 8767        let response = WorktreeStore::handle_rename_project_entry(
 8768            worktree_store,
 8769            envelope.payload,
 8770            cx.clone(),
 8771        )
 8772        .await;
 8773        this.read_with(&cx, |this, _| {
 8774            this.did_rename_entry(
 8775                old_worktree_id,
 8776                &old_abs_path,
 8777                &new_abs_path,
 8778                old_entry.is_dir(),
 8779            );
 8780        })
 8781        .ok();
 8782        response
 8783    }
 8784
 8785    async fn handle_update_diagnostic_summary(
 8786        this: Entity<Self>,
 8787        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8788        mut cx: AsyncApp,
 8789    ) -> Result<()> {
 8790        this.update(&mut cx, |lsp_store, cx| {
 8791            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8792            let mut updated_diagnostics_paths = HashMap::default();
 8793            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8794            for message_summary in envelope
 8795                .payload
 8796                .summary
 8797                .into_iter()
 8798                .chain(envelope.payload.more_summaries)
 8799            {
 8800                let project_path = ProjectPath {
 8801                    worktree_id,
 8802                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8803                };
 8804                let path = project_path.path.clone();
 8805                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8806                let summary = DiagnosticSummary {
 8807                    error_count: message_summary.error_count as usize,
 8808                    warning_count: message_summary.warning_count as usize,
 8809                };
 8810
 8811                if summary.is_empty() {
 8812                    if let Some(worktree_summaries) =
 8813                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8814                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8815                    {
 8816                        summaries.remove(&server_id);
 8817                        if summaries.is_empty() {
 8818                            worktree_summaries.remove(&path);
 8819                        }
 8820                    }
 8821                } else {
 8822                    lsp_store
 8823                        .diagnostic_summaries
 8824                        .entry(worktree_id)
 8825                        .or_default()
 8826                        .entry(path)
 8827                        .or_default()
 8828                        .insert(server_id, summary);
 8829                }
 8830
 8831                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8832                    match &mut diagnostics_summary {
 8833                        Some(diagnostics_summary) => {
 8834                            diagnostics_summary
 8835                                .more_summaries
 8836                                .push(proto::DiagnosticSummary {
 8837                                    path: project_path.path.as_ref().to_proto(),
 8838                                    language_server_id: server_id.0 as u64,
 8839                                    error_count: summary.error_count as u32,
 8840                                    warning_count: summary.warning_count as u32,
 8841                                })
 8842                        }
 8843                        None => {
 8844                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8845                                project_id: *project_id,
 8846                                worktree_id: worktree_id.to_proto(),
 8847                                summary: Some(proto::DiagnosticSummary {
 8848                                    path: project_path.path.as_ref().to_proto(),
 8849                                    language_server_id: server_id.0 as u64,
 8850                                    error_count: summary.error_count as u32,
 8851                                    warning_count: summary.warning_count as u32,
 8852                                }),
 8853                                more_summaries: Vec::new(),
 8854                            })
 8855                        }
 8856                    }
 8857                }
 8858                updated_diagnostics_paths
 8859                    .entry(server_id)
 8860                    .or_insert_with(Vec::new)
 8861                    .push(project_path);
 8862            }
 8863
 8864            if let Some((diagnostics_summary, (downstream_client, _))) =
 8865                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8866            {
 8867                downstream_client.send(diagnostics_summary).log_err();
 8868            }
 8869            for (server_id, paths) in updated_diagnostics_paths {
 8870                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8871            }
 8872            Ok(())
 8873        })?
 8874    }
 8875
 8876    async fn handle_start_language_server(
 8877        lsp_store: Entity<Self>,
 8878        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8879        mut cx: AsyncApp,
 8880    ) -> Result<()> {
 8881        let server = envelope.payload.server.context("invalid server")?;
 8882        let server_capabilities =
 8883            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8884                .with_context(|| {
 8885                    format!(
 8886                        "incorrect server capabilities {}",
 8887                        envelope.payload.capabilities
 8888                    )
 8889                })?;
 8890        lsp_store.update(&mut cx, |lsp_store, cx| {
 8891            let server_id = LanguageServerId(server.id as usize);
 8892            let server_name = LanguageServerName::from_proto(server.name.clone());
 8893            lsp_store
 8894                .lsp_server_capabilities
 8895                .insert(server_id, server_capabilities);
 8896            lsp_store.language_server_statuses.insert(
 8897                server_id,
 8898                LanguageServerStatus {
 8899                    name: server_name.clone(),
 8900                    pending_work: Default::default(),
 8901                    has_pending_diagnostic_updates: false,
 8902                    progress_tokens: Default::default(),
 8903                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8904                },
 8905            );
 8906            cx.emit(LspStoreEvent::LanguageServerAdded(
 8907                server_id,
 8908                server_name,
 8909                server.worktree_id.map(WorktreeId::from_proto),
 8910            ));
 8911            cx.notify();
 8912        })?;
 8913        Ok(())
 8914    }
 8915
 8916    async fn handle_update_language_server(
 8917        lsp_store: Entity<Self>,
 8918        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8919        mut cx: AsyncApp,
 8920    ) -> Result<()> {
 8921        lsp_store.update(&mut cx, |lsp_store, cx| {
 8922            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8923
 8924            match envelope.payload.variant.context("invalid variant")? {
 8925                proto::update_language_server::Variant::WorkStart(payload) => {
 8926                    lsp_store.on_lsp_work_start(
 8927                        language_server_id,
 8928                        payload.token,
 8929                        LanguageServerProgress {
 8930                            title: payload.title,
 8931                            is_disk_based_diagnostics_progress: false,
 8932                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8933                            message: payload.message,
 8934                            percentage: payload.percentage.map(|p| p as usize),
 8935                            last_update_at: cx.background_executor().now(),
 8936                        },
 8937                        cx,
 8938                    );
 8939                }
 8940                proto::update_language_server::Variant::WorkProgress(payload) => {
 8941                    lsp_store.on_lsp_work_progress(
 8942                        language_server_id,
 8943                        payload.token,
 8944                        LanguageServerProgress {
 8945                            title: None,
 8946                            is_disk_based_diagnostics_progress: false,
 8947                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8948                            message: payload.message,
 8949                            percentage: payload.percentage.map(|p| p as usize),
 8950                            last_update_at: cx.background_executor().now(),
 8951                        },
 8952                        cx,
 8953                    );
 8954                }
 8955
 8956                proto::update_language_server::Variant::WorkEnd(payload) => {
 8957                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8958                }
 8959
 8960                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8961                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8962                }
 8963
 8964                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8965                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8966                }
 8967
 8968                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8969                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8970                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8971                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 8972                        language_server_id,
 8973                        name: envelope
 8974                            .payload
 8975                            .server_name
 8976                            .map(SharedString::new)
 8977                            .map(LanguageServerName),
 8978                        message: non_lsp,
 8979                    });
 8980                }
 8981            }
 8982
 8983            Ok(())
 8984        })?
 8985    }
 8986
 8987    async fn handle_language_server_log(
 8988        this: Entity<Self>,
 8989        envelope: TypedEnvelope<proto::LanguageServerLog>,
 8990        mut cx: AsyncApp,
 8991    ) -> Result<()> {
 8992        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8993        let log_type = envelope
 8994            .payload
 8995            .log_type
 8996            .map(LanguageServerLogType::from_proto)
 8997            .context("invalid language server log type")?;
 8998
 8999        let message = envelope.payload.message;
 9000
 9001        this.update(&mut cx, |_, cx| {
 9002            cx.emit(LspStoreEvent::LanguageServerLog(
 9003                language_server_id,
 9004                log_type,
 9005                message,
 9006            ));
 9007        })
 9008    }
 9009
 9010    async fn handle_lsp_ext_cancel_flycheck(
 9011        lsp_store: Entity<Self>,
 9012        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9013        cx: AsyncApp,
 9014    ) -> Result<proto::Ack> {
 9015        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9016        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9017            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9018                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9019            } else {
 9020                None
 9021            }
 9022        })?;
 9023        if let Some(task) = task {
 9024            task.context("handling lsp ext cancel flycheck")?;
 9025        }
 9026
 9027        Ok(proto::Ack {})
 9028    }
 9029
 9030    async fn handle_lsp_ext_run_flycheck(
 9031        lsp_store: Entity<Self>,
 9032        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9033        mut cx: AsyncApp,
 9034    ) -> Result<proto::Ack> {
 9035        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9036        lsp_store.update(&mut cx, |lsp_store, cx| {
 9037            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9038                let text_document = if envelope.payload.current_file_only {
 9039                    let buffer_id = envelope
 9040                        .payload
 9041                        .buffer_id
 9042                        .map(|id| BufferId::new(id))
 9043                        .transpose()?;
 9044                    buffer_id
 9045                        .and_then(|buffer_id| {
 9046                            lsp_store
 9047                                .buffer_store()
 9048                                .read(cx)
 9049                                .get(buffer_id)
 9050                                .and_then(|buffer| {
 9051                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9052                                })
 9053                                .map(|path| make_text_document_identifier(&path))
 9054                        })
 9055                        .transpose()?
 9056                } else {
 9057                    None
 9058                };
 9059                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9060                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9061                )?;
 9062            }
 9063            anyhow::Ok(())
 9064        })??;
 9065
 9066        Ok(proto::Ack {})
 9067    }
 9068
 9069    async fn handle_lsp_ext_clear_flycheck(
 9070        lsp_store: Entity<Self>,
 9071        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9072        cx: AsyncApp,
 9073    ) -> Result<proto::Ack> {
 9074        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9075        lsp_store
 9076            .read_with(&cx, |lsp_store, _| {
 9077                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9078                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9079                } else {
 9080                    None
 9081                }
 9082            })
 9083            .context("handling lsp ext clear flycheck")?;
 9084
 9085        Ok(proto::Ack {})
 9086    }
 9087
 9088    pub fn disk_based_diagnostics_started(
 9089        &mut self,
 9090        language_server_id: LanguageServerId,
 9091        cx: &mut Context<Self>,
 9092    ) {
 9093        if let Some(language_server_status) =
 9094            self.language_server_statuses.get_mut(&language_server_id)
 9095        {
 9096            language_server_status.has_pending_diagnostic_updates = true;
 9097        }
 9098
 9099        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9100        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9101            language_server_id,
 9102            name: self
 9103                .language_server_adapter_for_id(language_server_id)
 9104                .map(|adapter| adapter.name()),
 9105            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9106                Default::default(),
 9107            ),
 9108        })
 9109    }
 9110
 9111    pub fn disk_based_diagnostics_finished(
 9112        &mut self,
 9113        language_server_id: LanguageServerId,
 9114        cx: &mut Context<Self>,
 9115    ) {
 9116        if let Some(language_server_status) =
 9117            self.language_server_statuses.get_mut(&language_server_id)
 9118        {
 9119            language_server_status.has_pending_diagnostic_updates = false;
 9120        }
 9121
 9122        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9123        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9124            language_server_id,
 9125            name: self
 9126                .language_server_adapter_for_id(language_server_id)
 9127                .map(|adapter| adapter.name()),
 9128            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9129                Default::default(),
 9130            ),
 9131        })
 9132    }
 9133
 9134    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9135    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9136    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9137    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9138    // the language server might take some time to publish diagnostics.
 9139    fn simulate_disk_based_diagnostics_events_if_needed(
 9140        &mut self,
 9141        language_server_id: LanguageServerId,
 9142        cx: &mut Context<Self>,
 9143    ) {
 9144        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9145
 9146        let Some(LanguageServerState::Running {
 9147            simulate_disk_based_diagnostics_completion,
 9148            adapter,
 9149            ..
 9150        }) = self
 9151            .as_local_mut()
 9152            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9153        else {
 9154            return;
 9155        };
 9156
 9157        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9158            return;
 9159        }
 9160
 9161        let prev_task =
 9162            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9163                cx.background_executor()
 9164                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9165                    .await;
 9166
 9167                this.update(cx, |this, cx| {
 9168                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9169
 9170                    if let Some(LanguageServerState::Running {
 9171                        simulate_disk_based_diagnostics_completion,
 9172                        ..
 9173                    }) = this.as_local_mut().and_then(|local_store| {
 9174                        local_store.language_servers.get_mut(&language_server_id)
 9175                    }) {
 9176                        *simulate_disk_based_diagnostics_completion = None;
 9177                    }
 9178                })
 9179                .ok();
 9180            }));
 9181
 9182        if prev_task.is_none() {
 9183            self.disk_based_diagnostics_started(language_server_id, cx);
 9184        }
 9185    }
 9186
 9187    pub fn language_server_statuses(
 9188        &self,
 9189    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9190        self.language_server_statuses
 9191            .iter()
 9192            .map(|(key, value)| (*key, value))
 9193    }
 9194
 9195    pub(super) fn did_rename_entry(
 9196        &self,
 9197        worktree_id: WorktreeId,
 9198        old_path: &Path,
 9199        new_path: &Path,
 9200        is_dir: bool,
 9201    ) {
 9202        maybe!({
 9203            let local_store = self.as_local()?;
 9204
 9205            let old_uri = lsp::Uri::from_file_path(old_path)
 9206                .ok()
 9207                .map(|uri| uri.to_string())?;
 9208            let new_uri = lsp::Uri::from_file_path(new_path)
 9209                .ok()
 9210                .map(|uri| uri.to_string())?;
 9211
 9212            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9213                let Some(filter) = local_store
 9214                    .language_server_paths_watched_for_rename
 9215                    .get(&language_server.server_id())
 9216                else {
 9217                    continue;
 9218                };
 9219
 9220                if filter.should_send_did_rename(&old_uri, is_dir) {
 9221                    language_server
 9222                        .notify::<DidRenameFiles>(RenameFilesParams {
 9223                            files: vec![FileRename {
 9224                                old_uri: old_uri.clone(),
 9225                                new_uri: new_uri.clone(),
 9226                            }],
 9227                        })
 9228                        .ok();
 9229                }
 9230            }
 9231            Some(())
 9232        });
 9233    }
 9234
 9235    pub(super) fn will_rename_entry(
 9236        this: WeakEntity<Self>,
 9237        worktree_id: WorktreeId,
 9238        old_path: &Path,
 9239        new_path: &Path,
 9240        is_dir: bool,
 9241        cx: AsyncApp,
 9242    ) -> Task<ProjectTransaction> {
 9243        let old_uri = lsp::Uri::from_file_path(old_path)
 9244            .ok()
 9245            .map(|uri| uri.to_string());
 9246        let new_uri = lsp::Uri::from_file_path(new_path)
 9247            .ok()
 9248            .map(|uri| uri.to_string());
 9249        cx.spawn(async move |cx| {
 9250            let mut tasks = vec![];
 9251            this.update(cx, |this, cx| {
 9252                let local_store = this.as_local()?;
 9253                let old_uri = old_uri?;
 9254                let new_uri = new_uri?;
 9255                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9256                    let Some(filter) = local_store
 9257                        .language_server_paths_watched_for_rename
 9258                        .get(&language_server.server_id())
 9259                    else {
 9260                        continue;
 9261                    };
 9262
 9263                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9264                        let apply_edit = cx.spawn({
 9265                            let old_uri = old_uri.clone();
 9266                            let new_uri = new_uri.clone();
 9267                            let language_server = language_server.clone();
 9268                            async move |this, cx| {
 9269                                let edit = language_server
 9270                                    .request::<WillRenameFiles>(RenameFilesParams {
 9271                                        files: vec![FileRename { old_uri, new_uri }],
 9272                                    })
 9273                                    .await
 9274                                    .into_response()
 9275                                    .context("will rename files")
 9276                                    .log_err()
 9277                                    .flatten()?;
 9278
 9279                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9280                                    this.upgrade()?,
 9281                                    edit,
 9282                                    false,
 9283                                    language_server.clone(),
 9284                                    cx,
 9285                                )
 9286                                .await
 9287                                .ok()?;
 9288                                Some(transaction)
 9289                            }
 9290                        });
 9291                        tasks.push(apply_edit);
 9292                    }
 9293                }
 9294                Some(())
 9295            })
 9296            .ok()
 9297            .flatten();
 9298            let mut merged_transaction = ProjectTransaction::default();
 9299            for task in tasks {
 9300                // Await on tasks sequentially so that the order of application of edits is deterministic
 9301                // (at least with regards to the order of registration of language servers)
 9302                if let Some(transaction) = task.await {
 9303                    for (buffer, buffer_transaction) in transaction.0 {
 9304                        merged_transaction.0.insert(buffer, buffer_transaction);
 9305                    }
 9306                }
 9307            }
 9308            merged_transaction
 9309        })
 9310    }
 9311
 9312    fn lsp_notify_abs_paths_changed(
 9313        &mut self,
 9314        server_id: LanguageServerId,
 9315        changes: Vec<PathEvent>,
 9316    ) {
 9317        maybe!({
 9318            let server = self.language_server_for_id(server_id)?;
 9319            let changes = changes
 9320                .into_iter()
 9321                .filter_map(|event| {
 9322                    let typ = match event.kind? {
 9323                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9324                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9325                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9326                    };
 9327                    Some(lsp::FileEvent {
 9328                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9329                        typ,
 9330                    })
 9331                })
 9332                .collect::<Vec<_>>();
 9333            if !changes.is_empty() {
 9334                server
 9335                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9336                        lsp::DidChangeWatchedFilesParams { changes },
 9337                    )
 9338                    .ok();
 9339            }
 9340            Some(())
 9341        });
 9342    }
 9343
 9344    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9345        self.as_local()?.language_server_for_id(id)
 9346    }
 9347
 9348    fn on_lsp_progress(
 9349        &mut self,
 9350        progress: lsp::ProgressParams,
 9351        language_server_id: LanguageServerId,
 9352        disk_based_diagnostics_progress_token: Option<String>,
 9353        cx: &mut Context<Self>,
 9354    ) {
 9355        let token = match progress.token {
 9356            lsp::NumberOrString::String(token) => token,
 9357            lsp::NumberOrString::Number(token) => {
 9358                log::info!("skipping numeric progress token {}", token);
 9359                return;
 9360            }
 9361        };
 9362
 9363        match progress.value {
 9364            lsp::ProgressParamsValue::WorkDone(progress) => {
 9365                self.handle_work_done_progress(
 9366                    progress,
 9367                    language_server_id,
 9368                    disk_based_diagnostics_progress_token,
 9369                    token,
 9370                    cx,
 9371                );
 9372            }
 9373            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9374                let identifier = token.split_once("id:").map(|(_, id)| id.to_owned());
 9375                if let Some(LanguageServerState::Running {
 9376                    workspace_diagnostics_refresh_tasks,
 9377                    ..
 9378                }) = self
 9379                    .as_local_mut()
 9380                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9381                    && let Some(workspace_diagnostics) =
 9382                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9383                {
 9384                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9385                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9386                }
 9387            }
 9388        }
 9389    }
 9390
 9391    fn handle_work_done_progress(
 9392        &mut self,
 9393        progress: lsp::WorkDoneProgress,
 9394        language_server_id: LanguageServerId,
 9395        disk_based_diagnostics_progress_token: Option<String>,
 9396        token: String,
 9397        cx: &mut Context<Self>,
 9398    ) {
 9399        let language_server_status =
 9400            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9401                status
 9402            } else {
 9403                return;
 9404            };
 9405
 9406        if !language_server_status.progress_tokens.contains(&token) {
 9407            return;
 9408        }
 9409
 9410        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9411            .as_ref()
 9412            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9413
 9414        match progress {
 9415            lsp::WorkDoneProgress::Begin(report) => {
 9416                if is_disk_based_diagnostics_progress {
 9417                    self.disk_based_diagnostics_started(language_server_id, cx);
 9418                }
 9419                self.on_lsp_work_start(
 9420                    language_server_id,
 9421                    token.clone(),
 9422                    LanguageServerProgress {
 9423                        title: Some(report.title),
 9424                        is_disk_based_diagnostics_progress,
 9425                        is_cancellable: report.cancellable.unwrap_or(false),
 9426                        message: report.message.clone(),
 9427                        percentage: report.percentage.map(|p| p as usize),
 9428                        last_update_at: cx.background_executor().now(),
 9429                    },
 9430                    cx,
 9431                );
 9432            }
 9433            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9434                language_server_id,
 9435                token,
 9436                LanguageServerProgress {
 9437                    title: None,
 9438                    is_disk_based_diagnostics_progress,
 9439                    is_cancellable: report.cancellable.unwrap_or(false),
 9440                    message: report.message,
 9441                    percentage: report.percentage.map(|p| p as usize),
 9442                    last_update_at: cx.background_executor().now(),
 9443                },
 9444                cx,
 9445            ),
 9446            lsp::WorkDoneProgress::End(_) => {
 9447                language_server_status.progress_tokens.remove(&token);
 9448                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9449                if is_disk_based_diagnostics_progress {
 9450                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9451                }
 9452            }
 9453        }
 9454    }
 9455
 9456    fn on_lsp_work_start(
 9457        &mut self,
 9458        language_server_id: LanguageServerId,
 9459        token: String,
 9460        progress: LanguageServerProgress,
 9461        cx: &mut Context<Self>,
 9462    ) {
 9463        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9464            status.pending_work.insert(token.clone(), progress.clone());
 9465            cx.notify();
 9466        }
 9467        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9468            language_server_id,
 9469            name: self
 9470                .language_server_adapter_for_id(language_server_id)
 9471                .map(|adapter| adapter.name()),
 9472            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9473                token,
 9474                title: progress.title,
 9475                message: progress.message,
 9476                percentage: progress.percentage.map(|p| p as u32),
 9477                is_cancellable: Some(progress.is_cancellable),
 9478            }),
 9479        })
 9480    }
 9481
 9482    fn on_lsp_work_progress(
 9483        &mut self,
 9484        language_server_id: LanguageServerId,
 9485        token: String,
 9486        progress: LanguageServerProgress,
 9487        cx: &mut Context<Self>,
 9488    ) {
 9489        let mut did_update = false;
 9490        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9491            match status.pending_work.entry(token.clone()) {
 9492                btree_map::Entry::Vacant(entry) => {
 9493                    entry.insert(progress.clone());
 9494                    did_update = true;
 9495                }
 9496                btree_map::Entry::Occupied(mut entry) => {
 9497                    let entry = entry.get_mut();
 9498                    if (progress.last_update_at - entry.last_update_at)
 9499                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9500                    {
 9501                        entry.last_update_at = progress.last_update_at;
 9502                        if progress.message.is_some() {
 9503                            entry.message = progress.message.clone();
 9504                        }
 9505                        if progress.percentage.is_some() {
 9506                            entry.percentage = progress.percentage;
 9507                        }
 9508                        if progress.is_cancellable != entry.is_cancellable {
 9509                            entry.is_cancellable = progress.is_cancellable;
 9510                        }
 9511                        did_update = true;
 9512                    }
 9513                }
 9514            }
 9515        }
 9516
 9517        if did_update {
 9518            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9519                language_server_id,
 9520                name: self
 9521                    .language_server_adapter_for_id(language_server_id)
 9522                    .map(|adapter| adapter.name()),
 9523                message: proto::update_language_server::Variant::WorkProgress(
 9524                    proto::LspWorkProgress {
 9525                        token,
 9526                        message: progress.message,
 9527                        percentage: progress.percentage.map(|p| p as u32),
 9528                        is_cancellable: Some(progress.is_cancellable),
 9529                    },
 9530                ),
 9531            })
 9532        }
 9533    }
 9534
 9535    fn on_lsp_work_end(
 9536        &mut self,
 9537        language_server_id: LanguageServerId,
 9538        token: String,
 9539        cx: &mut Context<Self>,
 9540    ) {
 9541        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9542            if let Some(work) = status.pending_work.remove(&token)
 9543                && !work.is_disk_based_diagnostics_progress
 9544            {
 9545                cx.emit(LspStoreEvent::RefreshInlayHints(language_server_id));
 9546            }
 9547            cx.notify();
 9548        }
 9549
 9550        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9551            language_server_id,
 9552            name: self
 9553                .language_server_adapter_for_id(language_server_id)
 9554                .map(|adapter| adapter.name()),
 9555            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9556        })
 9557    }
 9558
 9559    pub async fn handle_resolve_completion_documentation(
 9560        this: Entity<Self>,
 9561        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9562        mut cx: AsyncApp,
 9563    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9564        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9565
 9566        let completion = this
 9567            .read_with(&cx, |this, cx| {
 9568                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9569                let server = this
 9570                    .language_server_for_id(id)
 9571                    .with_context(|| format!("No language server {id}"))?;
 9572
 9573                anyhow::Ok(cx.background_spawn(async move {
 9574                    let can_resolve = server
 9575                        .capabilities()
 9576                        .completion_provider
 9577                        .as_ref()
 9578                        .and_then(|options| options.resolve_provider)
 9579                        .unwrap_or(false);
 9580                    if can_resolve {
 9581                        server
 9582                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9583                            .await
 9584                            .into_response()
 9585                            .context("resolve completion item")
 9586                    } else {
 9587                        anyhow::Ok(lsp_completion)
 9588                    }
 9589                }))
 9590            })??
 9591            .await?;
 9592
 9593        let mut documentation_is_markdown = false;
 9594        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9595        let documentation = match completion.documentation {
 9596            Some(lsp::Documentation::String(text)) => text,
 9597
 9598            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9599                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9600                value
 9601            }
 9602
 9603            _ => String::new(),
 9604        };
 9605
 9606        // If we have a new buffer_id, that means we're talking to a new client
 9607        // and want to check for new text_edits in the completion too.
 9608        let mut old_replace_start = None;
 9609        let mut old_replace_end = None;
 9610        let mut old_insert_start = None;
 9611        let mut old_insert_end = None;
 9612        let mut new_text = String::default();
 9613        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9614            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9615                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9616                anyhow::Ok(buffer.read(cx).snapshot())
 9617            })??;
 9618
 9619            if let Some(text_edit) = completion.text_edit.as_ref() {
 9620                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9621
 9622                if let Some(mut edit) = edit {
 9623                    LineEnding::normalize(&mut edit.new_text);
 9624
 9625                    new_text = edit.new_text;
 9626                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9627                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9628                    if let Some(insert_range) = edit.insert_range {
 9629                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9630                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9631                    }
 9632                }
 9633            }
 9634        }
 9635
 9636        Ok(proto::ResolveCompletionDocumentationResponse {
 9637            documentation,
 9638            documentation_is_markdown,
 9639            old_replace_start,
 9640            old_replace_end,
 9641            new_text,
 9642            lsp_completion,
 9643            old_insert_start,
 9644            old_insert_end,
 9645        })
 9646    }
 9647
 9648    async fn handle_on_type_formatting(
 9649        this: Entity<Self>,
 9650        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9651        mut cx: AsyncApp,
 9652    ) -> Result<proto::OnTypeFormattingResponse> {
 9653        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9654            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9655            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9656            let position = envelope
 9657                .payload
 9658                .position
 9659                .and_then(deserialize_anchor)
 9660                .context("invalid position")?;
 9661            anyhow::Ok(this.apply_on_type_formatting(
 9662                buffer,
 9663                position,
 9664                envelope.payload.trigger.clone(),
 9665                cx,
 9666            ))
 9667        })??;
 9668
 9669        let transaction = on_type_formatting
 9670            .await?
 9671            .as_ref()
 9672            .map(language::proto::serialize_transaction);
 9673        Ok(proto::OnTypeFormattingResponse { transaction })
 9674    }
 9675
 9676    async fn handle_refresh_inlay_hints(
 9677        lsp_store: Entity<Self>,
 9678        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9679        mut cx: AsyncApp,
 9680    ) -> Result<proto::Ack> {
 9681        lsp_store.update(&mut cx, |_, cx| {
 9682            cx.emit(LspStoreEvent::RefreshInlayHints(
 9683                LanguageServerId::from_proto(envelope.payload.server_id),
 9684            ));
 9685        })?;
 9686        Ok(proto::Ack {})
 9687    }
 9688
 9689    async fn handle_pull_workspace_diagnostics(
 9690        lsp_store: Entity<Self>,
 9691        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9692        mut cx: AsyncApp,
 9693    ) -> Result<proto::Ack> {
 9694        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9695        lsp_store.update(&mut cx, |lsp_store, _| {
 9696            lsp_store.pull_workspace_diagnostics(server_id);
 9697        })?;
 9698        Ok(proto::Ack {})
 9699    }
 9700
 9701    async fn handle_get_color_presentation(
 9702        lsp_store: Entity<Self>,
 9703        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9704        mut cx: AsyncApp,
 9705    ) -> Result<proto::GetColorPresentationResponse> {
 9706        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9707        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9708            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9709        })??;
 9710
 9711        let color = envelope
 9712            .payload
 9713            .color
 9714            .context("invalid color resolve request")?;
 9715        let start = color
 9716            .lsp_range_start
 9717            .context("invalid color resolve request")?;
 9718        let end = color
 9719            .lsp_range_end
 9720            .context("invalid color resolve request")?;
 9721
 9722        let color = DocumentColor {
 9723            lsp_range: lsp::Range {
 9724                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9725                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9726            },
 9727            color: lsp::Color {
 9728                red: color.red,
 9729                green: color.green,
 9730                blue: color.blue,
 9731                alpha: color.alpha,
 9732            },
 9733            resolved: false,
 9734            color_presentations: Vec::new(),
 9735        };
 9736        let resolved_color = lsp_store
 9737            .update(&mut cx, |lsp_store, cx| {
 9738                lsp_store.resolve_color_presentation(
 9739                    color,
 9740                    buffer.clone(),
 9741                    LanguageServerId(envelope.payload.server_id as usize),
 9742                    cx,
 9743                )
 9744            })?
 9745            .await
 9746            .context("resolving color presentation")?;
 9747
 9748        Ok(proto::GetColorPresentationResponse {
 9749            presentations: resolved_color
 9750                .color_presentations
 9751                .into_iter()
 9752                .map(|presentation| proto::ColorPresentation {
 9753                    label: presentation.label.to_string(),
 9754                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9755                    additional_text_edits: presentation
 9756                        .additional_text_edits
 9757                        .into_iter()
 9758                        .map(serialize_lsp_edit)
 9759                        .collect(),
 9760                })
 9761                .collect(),
 9762        })
 9763    }
 9764
 9765    async fn handle_resolve_inlay_hint(
 9766        lsp_store: Entity<Self>,
 9767        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9768        mut cx: AsyncApp,
 9769    ) -> Result<proto::ResolveInlayHintResponse> {
 9770        let proto_hint = envelope
 9771            .payload
 9772            .hint
 9773            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9774        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9775            .context("resolved proto inlay hint conversion")?;
 9776        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9777            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9778            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9779        })??;
 9780        let response_hint = lsp_store
 9781            .update(&mut cx, |lsp_store, cx| {
 9782                lsp_store.resolve_inlay_hint(
 9783                    hint,
 9784                    buffer,
 9785                    LanguageServerId(envelope.payload.language_server_id as usize),
 9786                    cx,
 9787                )
 9788            })?
 9789            .await
 9790            .context("inlay hints fetch")?;
 9791        Ok(proto::ResolveInlayHintResponse {
 9792            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9793        })
 9794    }
 9795
 9796    async fn handle_refresh_code_lens(
 9797        this: Entity<Self>,
 9798        _: TypedEnvelope<proto::RefreshCodeLens>,
 9799        mut cx: AsyncApp,
 9800    ) -> Result<proto::Ack> {
 9801        this.update(&mut cx, |_, cx| {
 9802            cx.emit(LspStoreEvent::RefreshCodeLens);
 9803        })?;
 9804        Ok(proto::Ack {})
 9805    }
 9806
 9807    async fn handle_open_buffer_for_symbol(
 9808        this: Entity<Self>,
 9809        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9810        mut cx: AsyncApp,
 9811    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9812        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9813        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9814        let symbol = Self::deserialize_symbol(symbol)?;
 9815        this.read_with(&cx, |this, _| {
 9816            if let SymbolLocation::OutsideProject {
 9817                abs_path,
 9818                signature,
 9819            } = &symbol.path
 9820            {
 9821                let new_signature = this.symbol_signature(&abs_path);
 9822                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9823            }
 9824            Ok(())
 9825        })??;
 9826        let buffer = this
 9827            .update(&mut cx, |this, cx| {
 9828                this.open_buffer_for_symbol(
 9829                    &Symbol {
 9830                        language_server_name: symbol.language_server_name,
 9831                        source_worktree_id: symbol.source_worktree_id,
 9832                        source_language_server_id: symbol.source_language_server_id,
 9833                        path: symbol.path,
 9834                        name: symbol.name,
 9835                        kind: symbol.kind,
 9836                        range: symbol.range,
 9837                        label: CodeLabel::default(),
 9838                    },
 9839                    cx,
 9840                )
 9841            })?
 9842            .await?;
 9843
 9844        this.update(&mut cx, |this, cx| {
 9845            let is_private = buffer
 9846                .read(cx)
 9847                .file()
 9848                .map(|f| f.is_private())
 9849                .unwrap_or_default();
 9850            if is_private {
 9851                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9852            } else {
 9853                this.buffer_store
 9854                    .update(cx, |buffer_store, cx| {
 9855                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9856                    })
 9857                    .detach_and_log_err(cx);
 9858                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9859                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9860            }
 9861        })?
 9862    }
 9863
 9864    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9865        let mut hasher = Sha256::new();
 9866        hasher.update(abs_path.to_string_lossy().as_bytes());
 9867        hasher.update(self.nonce.to_be_bytes());
 9868        hasher.finalize().as_slice().try_into().unwrap()
 9869    }
 9870
 9871    pub async fn handle_get_project_symbols(
 9872        this: Entity<Self>,
 9873        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9874        mut cx: AsyncApp,
 9875    ) -> Result<proto::GetProjectSymbolsResponse> {
 9876        let symbols = this
 9877            .update(&mut cx, |this, cx| {
 9878                this.symbols(&envelope.payload.query, cx)
 9879            })?
 9880            .await?;
 9881
 9882        Ok(proto::GetProjectSymbolsResponse {
 9883            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9884        })
 9885    }
 9886
 9887    pub async fn handle_restart_language_servers(
 9888        this: Entity<Self>,
 9889        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9890        mut cx: AsyncApp,
 9891    ) -> Result<proto::Ack> {
 9892        this.update(&mut cx, |lsp_store, cx| {
 9893            let buffers =
 9894                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9895            lsp_store.restart_language_servers_for_buffers(
 9896                buffers,
 9897                envelope
 9898                    .payload
 9899                    .only_servers
 9900                    .into_iter()
 9901                    .filter_map(|selector| {
 9902                        Some(match selector.selector? {
 9903                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9904                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9905                            }
 9906                            proto::language_server_selector::Selector::Name(name) => {
 9907                                LanguageServerSelector::Name(LanguageServerName(
 9908                                    SharedString::from(name),
 9909                                ))
 9910                            }
 9911                        })
 9912                    })
 9913                    .collect(),
 9914                cx,
 9915            );
 9916        })?;
 9917
 9918        Ok(proto::Ack {})
 9919    }
 9920
 9921    pub async fn handle_stop_language_servers(
 9922        lsp_store: Entity<Self>,
 9923        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9924        mut cx: AsyncApp,
 9925    ) -> Result<proto::Ack> {
 9926        lsp_store.update(&mut cx, |lsp_store, cx| {
 9927            if envelope.payload.all
 9928                && envelope.payload.also_servers.is_empty()
 9929                && envelope.payload.buffer_ids.is_empty()
 9930            {
 9931                lsp_store.stop_all_language_servers(cx);
 9932            } else {
 9933                let buffers =
 9934                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9935                lsp_store
 9936                    .stop_language_servers_for_buffers(
 9937                        buffers,
 9938                        envelope
 9939                            .payload
 9940                            .also_servers
 9941                            .into_iter()
 9942                            .filter_map(|selector| {
 9943                                Some(match selector.selector? {
 9944                                    proto::language_server_selector::Selector::ServerId(
 9945                                        server_id,
 9946                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9947                                        server_id,
 9948                                    )),
 9949                                    proto::language_server_selector::Selector::Name(name) => {
 9950                                        LanguageServerSelector::Name(LanguageServerName(
 9951                                            SharedString::from(name),
 9952                                        ))
 9953                                    }
 9954                                })
 9955                            })
 9956                            .collect(),
 9957                        cx,
 9958                    )
 9959                    .detach_and_log_err(cx);
 9960            }
 9961        })?;
 9962
 9963        Ok(proto::Ack {})
 9964    }
 9965
 9966    pub async fn handle_cancel_language_server_work(
 9967        this: Entity<Self>,
 9968        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
 9969        mut cx: AsyncApp,
 9970    ) -> Result<proto::Ack> {
 9971        this.update(&mut cx, |this, cx| {
 9972            if let Some(work) = envelope.payload.work {
 9973                match work {
 9974                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
 9975                        let buffers =
 9976                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
 9977                        this.cancel_language_server_work_for_buffers(buffers, cx);
 9978                    }
 9979                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
 9980                        let server_id = LanguageServerId::from_proto(work.language_server_id);
 9981                        this.cancel_language_server_work(server_id, work.token, cx);
 9982                    }
 9983                }
 9984            }
 9985        })?;
 9986
 9987        Ok(proto::Ack {})
 9988    }
 9989
 9990    fn buffer_ids_to_buffers(
 9991        &mut self,
 9992        buffer_ids: impl Iterator<Item = u64>,
 9993        cx: &mut Context<Self>,
 9994    ) -> Vec<Entity<Buffer>> {
 9995        buffer_ids
 9996            .into_iter()
 9997            .flat_map(|buffer_id| {
 9998                self.buffer_store
 9999                    .read(cx)
10000                    .get(BufferId::new(buffer_id).log_err()?)
10001            })
10002            .collect::<Vec<_>>()
10003    }
10004
10005    async fn handle_apply_additional_edits_for_completion(
10006        this: Entity<Self>,
10007        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10008        mut cx: AsyncApp,
10009    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10010        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10011            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10012            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10013            let completion = Self::deserialize_completion(
10014                envelope.payload.completion.context("invalid completion")?,
10015            )?;
10016            anyhow::Ok((buffer, completion))
10017        })??;
10018
10019        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10020            this.apply_additional_edits_for_completion(
10021                buffer,
10022                Rc::new(RefCell::new(Box::new([Completion {
10023                    replace_range: completion.replace_range,
10024                    new_text: completion.new_text,
10025                    source: completion.source,
10026                    documentation: None,
10027                    label: CodeLabel::default(),
10028                    insert_text_mode: None,
10029                    icon_path: None,
10030                    confirm: None,
10031                }]))),
10032                0,
10033                false,
10034                cx,
10035            )
10036        })?;
10037
10038        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10039            transaction: apply_additional_edits
10040                .await?
10041                .as_ref()
10042                .map(language::proto::serialize_transaction),
10043        })
10044    }
10045
10046    pub fn last_formatting_failure(&self) -> Option<&str> {
10047        self.last_formatting_failure.as_deref()
10048    }
10049
10050    pub fn reset_last_formatting_failure(&mut self) {
10051        self.last_formatting_failure = None;
10052    }
10053
10054    pub fn environment_for_buffer(
10055        &self,
10056        buffer: &Entity<Buffer>,
10057        cx: &mut Context<Self>,
10058    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10059        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10060            environment.update(cx, |env, cx| {
10061                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10062            })
10063        } else {
10064            Task::ready(None).shared()
10065        }
10066    }
10067
10068    pub fn format(
10069        &mut self,
10070        buffers: HashSet<Entity<Buffer>>,
10071        target: LspFormatTarget,
10072        push_to_history: bool,
10073        trigger: FormatTrigger,
10074        cx: &mut Context<Self>,
10075    ) -> Task<anyhow::Result<ProjectTransaction>> {
10076        let logger = zlog::scoped!("format");
10077        if self.as_local().is_some() {
10078            zlog::trace!(logger => "Formatting locally");
10079            let logger = zlog::scoped!(logger => "local");
10080            let buffers = buffers
10081                .into_iter()
10082                .map(|buffer_handle| {
10083                    let buffer = buffer_handle.read(cx);
10084                    let buffer_abs_path = File::from_dyn(buffer.file())
10085                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10086
10087                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10088                })
10089                .collect::<Vec<_>>();
10090
10091            cx.spawn(async move |lsp_store, cx| {
10092                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10093
10094                for (handle, abs_path, id) in buffers {
10095                    let env = lsp_store
10096                        .update(cx, |lsp_store, cx| {
10097                            lsp_store.environment_for_buffer(&handle, cx)
10098                        })?
10099                        .await;
10100
10101                    let ranges = match &target {
10102                        LspFormatTarget::Buffers => None,
10103                        LspFormatTarget::Ranges(ranges) => {
10104                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10105                        }
10106                    };
10107
10108                    formattable_buffers.push(FormattableBuffer {
10109                        handle,
10110                        abs_path,
10111                        env,
10112                        ranges,
10113                    });
10114                }
10115                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10116
10117                let format_timer = zlog::time!(logger => "Formatting buffers");
10118                let result = LocalLspStore::format_locally(
10119                    lsp_store.clone(),
10120                    formattable_buffers,
10121                    push_to_history,
10122                    trigger,
10123                    logger,
10124                    cx,
10125                )
10126                .await;
10127                format_timer.end();
10128
10129                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10130
10131                lsp_store.update(cx, |lsp_store, _| {
10132                    lsp_store.update_last_formatting_failure(&result);
10133                })?;
10134
10135                result
10136            })
10137        } else if let Some((client, project_id)) = self.upstream_client() {
10138            zlog::trace!(logger => "Formatting remotely");
10139            let logger = zlog::scoped!(logger => "remote");
10140            // Don't support formatting ranges via remote
10141            match target {
10142                LspFormatTarget::Buffers => {}
10143                LspFormatTarget::Ranges(_) => {
10144                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10145                    return Task::ready(Ok(ProjectTransaction::default()));
10146                }
10147            }
10148
10149            let buffer_store = self.buffer_store();
10150            cx.spawn(async move |lsp_store, cx| {
10151                zlog::trace!(logger => "Sending remote format request");
10152                let request_timer = zlog::time!(logger => "remote format request");
10153                let result = client
10154                    .request(proto::FormatBuffers {
10155                        project_id,
10156                        trigger: trigger as i32,
10157                        buffer_ids: buffers
10158                            .iter()
10159                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10160                            .collect::<Result<_>>()?,
10161                    })
10162                    .await
10163                    .and_then(|result| result.transaction.context("missing transaction"));
10164                request_timer.end();
10165
10166                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10167
10168                lsp_store.update(cx, |lsp_store, _| {
10169                    lsp_store.update_last_formatting_failure(&result);
10170                })?;
10171
10172                let transaction_response = result?;
10173                let _timer = zlog::time!(logger => "deserializing project transaction");
10174                buffer_store
10175                    .update(cx, |buffer_store, cx| {
10176                        buffer_store.deserialize_project_transaction(
10177                            transaction_response,
10178                            push_to_history,
10179                            cx,
10180                        )
10181                    })?
10182                    .await
10183            })
10184        } else {
10185            zlog::trace!(logger => "Not formatting");
10186            Task::ready(Ok(ProjectTransaction::default()))
10187        }
10188    }
10189
10190    async fn handle_format_buffers(
10191        this: Entity<Self>,
10192        envelope: TypedEnvelope<proto::FormatBuffers>,
10193        mut cx: AsyncApp,
10194    ) -> Result<proto::FormatBuffersResponse> {
10195        let sender_id = envelope.original_sender_id().unwrap_or_default();
10196        let format = this.update(&mut cx, |this, cx| {
10197            let mut buffers = HashSet::default();
10198            for buffer_id in &envelope.payload.buffer_ids {
10199                let buffer_id = BufferId::new(*buffer_id)?;
10200                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10201            }
10202            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10203            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10204        })??;
10205
10206        let project_transaction = format.await?;
10207        let project_transaction = this.update(&mut cx, |this, cx| {
10208            this.buffer_store.update(cx, |buffer_store, cx| {
10209                buffer_store.serialize_project_transaction_for_peer(
10210                    project_transaction,
10211                    sender_id,
10212                    cx,
10213                )
10214            })
10215        })?;
10216        Ok(proto::FormatBuffersResponse {
10217            transaction: Some(project_transaction),
10218        })
10219    }
10220
10221    async fn handle_apply_code_action_kind(
10222        this: Entity<Self>,
10223        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10224        mut cx: AsyncApp,
10225    ) -> Result<proto::ApplyCodeActionKindResponse> {
10226        let sender_id = envelope.original_sender_id().unwrap_or_default();
10227        let format = this.update(&mut cx, |this, cx| {
10228            let mut buffers = HashSet::default();
10229            for buffer_id in &envelope.payload.buffer_ids {
10230                let buffer_id = BufferId::new(*buffer_id)?;
10231                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10232            }
10233            let kind = match envelope.payload.kind.as_str() {
10234                "" => CodeActionKind::EMPTY,
10235                "quickfix" => CodeActionKind::QUICKFIX,
10236                "refactor" => CodeActionKind::REFACTOR,
10237                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10238                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10239                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10240                "source" => CodeActionKind::SOURCE,
10241                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10242                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10243                _ => anyhow::bail!(
10244                    "Invalid code action kind {}",
10245                    envelope.payload.kind.as_str()
10246                ),
10247            };
10248            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10249        })??;
10250
10251        let project_transaction = format.await?;
10252        let project_transaction = this.update(&mut cx, |this, cx| {
10253            this.buffer_store.update(cx, |buffer_store, cx| {
10254                buffer_store.serialize_project_transaction_for_peer(
10255                    project_transaction,
10256                    sender_id,
10257                    cx,
10258                )
10259            })
10260        })?;
10261        Ok(proto::ApplyCodeActionKindResponse {
10262            transaction: Some(project_transaction),
10263        })
10264    }
10265
10266    async fn shutdown_language_server(
10267        server_state: Option<LanguageServerState>,
10268        name: LanguageServerName,
10269        cx: &mut AsyncApp,
10270    ) {
10271        let server = match server_state {
10272            Some(LanguageServerState::Starting { startup, .. }) => {
10273                let mut timer = cx
10274                    .background_executor()
10275                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10276                    .fuse();
10277
10278                select! {
10279                    server = startup.fuse() => server,
10280                    () = timer => {
10281                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10282                        None
10283                    },
10284                }
10285            }
10286
10287            Some(LanguageServerState::Running { server, .. }) => Some(server),
10288
10289            None => None,
10290        };
10291
10292        if let Some(server) = server
10293            && let Some(shutdown) = server.shutdown()
10294        {
10295            shutdown.await;
10296        }
10297    }
10298
10299    // Returns a list of all of the worktrees which no longer have a language server and the root path
10300    // for the stopped server
10301    fn stop_local_language_server(
10302        &mut self,
10303        server_id: LanguageServerId,
10304        cx: &mut Context<Self>,
10305    ) -> Task<()> {
10306        let local = match &mut self.mode {
10307            LspStoreMode::Local(local) => local,
10308            _ => {
10309                return Task::ready(());
10310            }
10311        };
10312
10313        // Remove this server ID from all entries in the given worktree.
10314        local
10315            .language_server_ids
10316            .retain(|_, state| state.id != server_id);
10317        self.buffer_store.update(cx, |buffer_store, cx| {
10318            for buffer in buffer_store.buffers() {
10319                buffer.update(cx, |buffer, cx| {
10320                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10321                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10322                });
10323            }
10324        });
10325
10326        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10327            summaries.retain(|path, summaries_by_server_id| {
10328                if summaries_by_server_id.remove(&server_id).is_some() {
10329                    if let Some((client, project_id)) = self.downstream_client.clone() {
10330                        client
10331                            .send(proto::UpdateDiagnosticSummary {
10332                                project_id,
10333                                worktree_id: worktree_id.to_proto(),
10334                                summary: Some(proto::DiagnosticSummary {
10335                                    path: path.as_ref().to_proto(),
10336                                    language_server_id: server_id.0 as u64,
10337                                    error_count: 0,
10338                                    warning_count: 0,
10339                                }),
10340                                more_summaries: Vec::new(),
10341                            })
10342                            .log_err();
10343                    }
10344                    !summaries_by_server_id.is_empty()
10345                } else {
10346                    true
10347                }
10348            });
10349        }
10350
10351        let local = self.as_local_mut().unwrap();
10352        for diagnostics in local.diagnostics.values_mut() {
10353            diagnostics.retain(|_, diagnostics_by_server_id| {
10354                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10355                    diagnostics_by_server_id.remove(ix);
10356                    !diagnostics_by_server_id.is_empty()
10357                } else {
10358                    true
10359                }
10360            });
10361        }
10362        local.language_server_watched_paths.remove(&server_id);
10363
10364        let server_state = local.language_servers.remove(&server_id);
10365        self.cleanup_lsp_data(server_id);
10366        let name = self
10367            .language_server_statuses
10368            .remove(&server_id)
10369            .map(|status| status.name)
10370            .or_else(|| {
10371                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10372                    Some(adapter.name())
10373                } else {
10374                    None
10375                }
10376            });
10377
10378        if let Some(name) = name {
10379            log::info!("stopping language server {name}");
10380            self.languages
10381                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10382            cx.notify();
10383
10384            return cx.spawn(async move |lsp_store, cx| {
10385                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10386                lsp_store
10387                    .update(cx, |lsp_store, cx| {
10388                        lsp_store
10389                            .languages
10390                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10391                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10392                        cx.notify();
10393                    })
10394                    .ok();
10395            });
10396        }
10397
10398        if server_state.is_some() {
10399            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10400        }
10401        Task::ready(())
10402    }
10403
10404    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10405        if let Some((client, project_id)) = self.upstream_client() {
10406            let request = client.request(proto::StopLanguageServers {
10407                project_id,
10408                buffer_ids: Vec::new(),
10409                also_servers: Vec::new(),
10410                all: true,
10411            });
10412            cx.background_spawn(request).detach_and_log_err(cx);
10413        } else {
10414            let Some(local) = self.as_local_mut() else {
10415                return;
10416            };
10417            let language_servers_to_stop = local
10418                .language_server_ids
10419                .values()
10420                .map(|state| state.id)
10421                .collect();
10422            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10423            let tasks = language_servers_to_stop
10424                .into_iter()
10425                .map(|server| self.stop_local_language_server(server, cx))
10426                .collect::<Vec<_>>();
10427            cx.background_spawn(async move {
10428                futures::future::join_all(tasks).await;
10429            })
10430            .detach();
10431        }
10432    }
10433
10434    pub fn restart_language_servers_for_buffers(
10435        &mut self,
10436        buffers: Vec<Entity<Buffer>>,
10437        only_restart_servers: HashSet<LanguageServerSelector>,
10438        cx: &mut Context<Self>,
10439    ) {
10440        if let Some((client, project_id)) = self.upstream_client() {
10441            let request = client.request(proto::RestartLanguageServers {
10442                project_id,
10443                buffer_ids: buffers
10444                    .into_iter()
10445                    .map(|b| b.read(cx).remote_id().to_proto())
10446                    .collect(),
10447                only_servers: only_restart_servers
10448                    .into_iter()
10449                    .map(|selector| {
10450                        let selector = match selector {
10451                            LanguageServerSelector::Id(language_server_id) => {
10452                                proto::language_server_selector::Selector::ServerId(
10453                                    language_server_id.to_proto(),
10454                                )
10455                            }
10456                            LanguageServerSelector::Name(language_server_name) => {
10457                                proto::language_server_selector::Selector::Name(
10458                                    language_server_name.to_string(),
10459                                )
10460                            }
10461                        };
10462                        proto::LanguageServerSelector {
10463                            selector: Some(selector),
10464                        }
10465                    })
10466                    .collect(),
10467                all: false,
10468            });
10469            cx.background_spawn(request).detach_and_log_err(cx);
10470        } else {
10471            let stop_task = if only_restart_servers.is_empty() {
10472                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10473            } else {
10474                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10475            };
10476            cx.spawn(async move |lsp_store, cx| {
10477                stop_task.await;
10478                lsp_store
10479                    .update(cx, |lsp_store, cx| {
10480                        for buffer in buffers {
10481                            lsp_store.register_buffer_with_language_servers(
10482                                &buffer,
10483                                only_restart_servers.clone(),
10484                                true,
10485                                cx,
10486                            );
10487                        }
10488                    })
10489                    .ok()
10490            })
10491            .detach();
10492        }
10493    }
10494
10495    pub fn stop_language_servers_for_buffers(
10496        &mut self,
10497        buffers: Vec<Entity<Buffer>>,
10498        also_stop_servers: HashSet<LanguageServerSelector>,
10499        cx: &mut Context<Self>,
10500    ) -> Task<Result<()>> {
10501        if let Some((client, project_id)) = self.upstream_client() {
10502            let request = client.request(proto::StopLanguageServers {
10503                project_id,
10504                buffer_ids: buffers
10505                    .into_iter()
10506                    .map(|b| b.read(cx).remote_id().to_proto())
10507                    .collect(),
10508                also_servers: also_stop_servers
10509                    .into_iter()
10510                    .map(|selector| {
10511                        let selector = match selector {
10512                            LanguageServerSelector::Id(language_server_id) => {
10513                                proto::language_server_selector::Selector::ServerId(
10514                                    language_server_id.to_proto(),
10515                                )
10516                            }
10517                            LanguageServerSelector::Name(language_server_name) => {
10518                                proto::language_server_selector::Selector::Name(
10519                                    language_server_name.to_string(),
10520                                )
10521                            }
10522                        };
10523                        proto::LanguageServerSelector {
10524                            selector: Some(selector),
10525                        }
10526                    })
10527                    .collect(),
10528                all: false,
10529            });
10530            cx.background_spawn(async move {
10531                let _ = request.await?;
10532                Ok(())
10533            })
10534        } else {
10535            let task =
10536                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10537            cx.background_spawn(async move {
10538                task.await;
10539                Ok(())
10540            })
10541        }
10542    }
10543
10544    fn stop_local_language_servers_for_buffers(
10545        &mut self,
10546        buffers: &[Entity<Buffer>],
10547        also_stop_servers: HashSet<LanguageServerSelector>,
10548        cx: &mut Context<Self>,
10549    ) -> Task<()> {
10550        let Some(local) = self.as_local_mut() else {
10551            return Task::ready(());
10552        };
10553        let mut language_server_names_to_stop = BTreeSet::default();
10554        let mut language_servers_to_stop = also_stop_servers
10555            .into_iter()
10556            .flat_map(|selector| match selector {
10557                LanguageServerSelector::Id(id) => Some(id),
10558                LanguageServerSelector::Name(name) => {
10559                    language_server_names_to_stop.insert(name);
10560                    None
10561                }
10562            })
10563            .collect::<BTreeSet<_>>();
10564
10565        let mut covered_worktrees = HashSet::default();
10566        for buffer in buffers {
10567            buffer.update(cx, |buffer, cx| {
10568                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10569                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10570                    && covered_worktrees.insert(worktree_id)
10571                {
10572                    language_server_names_to_stop.retain(|name| {
10573                        let old_ids_count = language_servers_to_stop.len();
10574                        let all_language_servers_with_this_name = local
10575                            .language_server_ids
10576                            .iter()
10577                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10578                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10579                        old_ids_count == language_servers_to_stop.len()
10580                    });
10581                }
10582            });
10583        }
10584        for name in language_server_names_to_stop {
10585            language_servers_to_stop.extend(
10586                local
10587                    .language_server_ids
10588                    .iter()
10589                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10590            );
10591        }
10592
10593        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10594        let tasks = language_servers_to_stop
10595            .into_iter()
10596            .map(|server| self.stop_local_language_server(server, cx))
10597            .collect::<Vec<_>>();
10598
10599        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10600    }
10601
10602    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10603        let (worktree, relative_path) =
10604            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10605
10606        let project_path = ProjectPath {
10607            worktree_id: worktree.read(cx).id(),
10608            path: relative_path,
10609        };
10610
10611        Some(
10612            self.buffer_store()
10613                .read(cx)
10614                .get_by_path(&project_path)?
10615                .read(cx),
10616        )
10617    }
10618
10619    #[cfg(any(test, feature = "test-support"))]
10620    pub fn update_diagnostics(
10621        &mut self,
10622        server_id: LanguageServerId,
10623        diagnostics: lsp::PublishDiagnosticsParams,
10624        result_id: Option<String>,
10625        source_kind: DiagnosticSourceKind,
10626        disk_based_sources: &[String],
10627        cx: &mut Context<Self>,
10628    ) -> Result<()> {
10629        self.merge_lsp_diagnostics(
10630            source_kind,
10631            vec![DocumentDiagnosticsUpdate {
10632                diagnostics,
10633                result_id,
10634                server_id,
10635                disk_based_sources: Cow::Borrowed(disk_based_sources),
10636            }],
10637            |_, _, _| false,
10638            cx,
10639        )
10640    }
10641
10642    pub fn merge_lsp_diagnostics(
10643        &mut self,
10644        source_kind: DiagnosticSourceKind,
10645        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10646        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10647        cx: &mut Context<Self>,
10648    ) -> Result<()> {
10649        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10650        let updates = lsp_diagnostics
10651            .into_iter()
10652            .filter_map(|update| {
10653                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10654                Some(DocumentDiagnosticsUpdate {
10655                    diagnostics: self.lsp_to_document_diagnostics(
10656                        abs_path,
10657                        source_kind,
10658                        update.server_id,
10659                        update.diagnostics,
10660                        &update.disk_based_sources,
10661                    ),
10662                    result_id: update.result_id,
10663                    server_id: update.server_id,
10664                    disk_based_sources: update.disk_based_sources,
10665                })
10666            })
10667            .collect();
10668        self.merge_diagnostic_entries(updates, merge, cx)?;
10669        Ok(())
10670    }
10671
10672    fn lsp_to_document_diagnostics(
10673        &mut self,
10674        document_abs_path: PathBuf,
10675        source_kind: DiagnosticSourceKind,
10676        server_id: LanguageServerId,
10677        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10678        disk_based_sources: &[String],
10679    ) -> DocumentDiagnostics {
10680        let mut diagnostics = Vec::default();
10681        let mut primary_diagnostic_group_ids = HashMap::default();
10682        let mut sources_by_group_id = HashMap::default();
10683        let mut supporting_diagnostics = HashMap::default();
10684
10685        let adapter = self.language_server_adapter_for_id(server_id);
10686
10687        // Ensure that primary diagnostics are always the most severe
10688        lsp_diagnostics
10689            .diagnostics
10690            .sort_by_key(|item| item.severity);
10691
10692        for diagnostic in &lsp_diagnostics.diagnostics {
10693            let source = diagnostic.source.as_ref();
10694            let range = range_from_lsp(diagnostic.range);
10695            let is_supporting = diagnostic
10696                .related_information
10697                .as_ref()
10698                .is_some_and(|infos| {
10699                    infos.iter().any(|info| {
10700                        primary_diagnostic_group_ids.contains_key(&(
10701                            source,
10702                            diagnostic.code.clone(),
10703                            range_from_lsp(info.location.range),
10704                        ))
10705                    })
10706                });
10707
10708            let is_unnecessary = diagnostic
10709                .tags
10710                .as_ref()
10711                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10712
10713            let underline = self
10714                .language_server_adapter_for_id(server_id)
10715                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10716
10717            if is_supporting {
10718                supporting_diagnostics.insert(
10719                    (source, diagnostic.code.clone(), range),
10720                    (diagnostic.severity, is_unnecessary),
10721                );
10722            } else {
10723                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10724                let is_disk_based =
10725                    source.is_some_and(|source| disk_based_sources.contains(source));
10726
10727                sources_by_group_id.insert(group_id, source);
10728                primary_diagnostic_group_ids
10729                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10730
10731                diagnostics.push(DiagnosticEntry {
10732                    range,
10733                    diagnostic: Diagnostic {
10734                        source: diagnostic.source.clone(),
10735                        source_kind,
10736                        code: diagnostic.code.clone(),
10737                        code_description: diagnostic
10738                            .code_description
10739                            .as_ref()
10740                            .and_then(|d| d.href.clone()),
10741                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10742                        markdown: adapter.as_ref().and_then(|adapter| {
10743                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10744                        }),
10745                        message: diagnostic.message.trim().to_string(),
10746                        group_id,
10747                        is_primary: true,
10748                        is_disk_based,
10749                        is_unnecessary,
10750                        underline,
10751                        data: diagnostic.data.clone(),
10752                    },
10753                });
10754                if let Some(infos) = &diagnostic.related_information {
10755                    for info in infos {
10756                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10757                            let range = range_from_lsp(info.location.range);
10758                            diagnostics.push(DiagnosticEntry {
10759                                range,
10760                                diagnostic: Diagnostic {
10761                                    source: diagnostic.source.clone(),
10762                                    source_kind,
10763                                    code: diagnostic.code.clone(),
10764                                    code_description: diagnostic
10765                                        .code_description
10766                                        .as_ref()
10767                                        .and_then(|d| d.href.clone()),
10768                                    severity: DiagnosticSeverity::INFORMATION,
10769                                    markdown: adapter.as_ref().and_then(|adapter| {
10770                                        adapter.diagnostic_message_to_markdown(&info.message)
10771                                    }),
10772                                    message: info.message.trim().to_string(),
10773                                    group_id,
10774                                    is_primary: false,
10775                                    is_disk_based,
10776                                    is_unnecessary: false,
10777                                    underline,
10778                                    data: diagnostic.data.clone(),
10779                                },
10780                            });
10781                        }
10782                    }
10783                }
10784            }
10785        }
10786
10787        for entry in &mut diagnostics {
10788            let diagnostic = &mut entry.diagnostic;
10789            if !diagnostic.is_primary {
10790                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10791                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10792                    source,
10793                    diagnostic.code.clone(),
10794                    entry.range.clone(),
10795                )) {
10796                    if let Some(severity) = severity {
10797                        diagnostic.severity = severity;
10798                    }
10799                    diagnostic.is_unnecessary = is_unnecessary;
10800                }
10801            }
10802        }
10803
10804        DocumentDiagnostics {
10805            diagnostics,
10806            document_abs_path,
10807            version: lsp_diagnostics.version,
10808        }
10809    }
10810
10811    fn insert_newly_running_language_server(
10812        &mut self,
10813        adapter: Arc<CachedLspAdapter>,
10814        language_server: Arc<LanguageServer>,
10815        server_id: LanguageServerId,
10816        key: LanguageServerSeed,
10817        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10818        cx: &mut Context<Self>,
10819    ) {
10820        let Some(local) = self.as_local_mut() else {
10821            return;
10822        };
10823        // If the language server for this key doesn't match the server id, don't store the
10824        // server. Which will cause it to be dropped, killing the process
10825        if local
10826            .language_server_ids
10827            .get(&key)
10828            .map(|state| state.id != server_id)
10829            .unwrap_or(false)
10830        {
10831            return;
10832        }
10833
10834        // Update language_servers collection with Running variant of LanguageServerState
10835        // indicating that the server is up and running and ready
10836        let workspace_folders = workspace_folders.lock().clone();
10837        language_server.set_workspace_folders(workspace_folders);
10838
10839        let workspace_diagnostics_refresh_tasks = language_server
10840            .capabilities()
10841            .diagnostic_provider
10842            .and_then(|provider| {
10843                let workspace_refresher = lsp_workspace_diagnostics_refresh(
10844                    None,
10845                    provider.clone(),
10846                    language_server.clone(),
10847                    cx,
10848                )?;
10849                local
10850                    .language_server_dynamic_registrations
10851                    .entry(server_id)
10852                    .or_default()
10853                    .diagnostics
10854                    .entry(None)
10855                    .or_insert(provider);
10856                Some((None, workspace_refresher))
10857            })
10858            .into_iter()
10859            .collect();
10860        local.language_servers.insert(
10861            server_id,
10862            LanguageServerState::Running {
10863                workspace_diagnostics_refresh_tasks,
10864                adapter: adapter.clone(),
10865                server: language_server.clone(),
10866                simulate_disk_based_diagnostics_completion: None,
10867            },
10868        );
10869        local
10870            .languages
10871            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10872        if let Some(file_ops_caps) = language_server
10873            .capabilities()
10874            .workspace
10875            .as_ref()
10876            .and_then(|ws| ws.file_operations.as_ref())
10877        {
10878            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10879            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10880            if did_rename_caps.or(will_rename_caps).is_some() {
10881                let watcher = RenamePathsWatchedForServer::default()
10882                    .with_did_rename_patterns(did_rename_caps)
10883                    .with_will_rename_patterns(will_rename_caps);
10884                local
10885                    .language_server_paths_watched_for_rename
10886                    .insert(server_id, watcher);
10887            }
10888        }
10889
10890        self.language_server_statuses.insert(
10891            server_id,
10892            LanguageServerStatus {
10893                name: language_server.name(),
10894                pending_work: Default::default(),
10895                has_pending_diagnostic_updates: false,
10896                progress_tokens: Default::default(),
10897                worktree: Some(key.worktree_id),
10898            },
10899        );
10900
10901        cx.emit(LspStoreEvent::LanguageServerAdded(
10902            server_id,
10903            language_server.name(),
10904            Some(key.worktree_id),
10905        ));
10906        cx.emit(LspStoreEvent::RefreshInlayHints(server_id));
10907
10908        let server_capabilities = language_server.capabilities();
10909        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10910            downstream_client
10911                .send(proto::StartLanguageServer {
10912                    project_id: *project_id,
10913                    server: Some(proto::LanguageServer {
10914                        id: server_id.to_proto(),
10915                        name: language_server.name().to_string(),
10916                        worktree_id: Some(key.worktree_id.to_proto()),
10917                    }),
10918                    capabilities: serde_json::to_string(&server_capabilities)
10919                        .expect("serializing server LSP capabilities"),
10920                })
10921                .log_err();
10922        }
10923        self.lsp_server_capabilities
10924            .insert(server_id, server_capabilities);
10925
10926        // Tell the language server about every open buffer in the worktree that matches the language.
10927        // Also check for buffers in worktrees that reused this server
10928        let mut worktrees_using_server = vec![key.worktree_id];
10929        if let Some(local) = self.as_local() {
10930            // Find all worktrees that have this server in their language server tree
10931            for (worktree_id, servers) in &local.lsp_tree.instances {
10932                if *worktree_id != key.worktree_id {
10933                    for server_map in servers.roots.values() {
10934                        if server_map
10935                            .values()
10936                            .any(|(node, _)| node.id() == Some(server_id))
10937                        {
10938                            worktrees_using_server.push(*worktree_id);
10939                        }
10940                    }
10941                }
10942            }
10943        }
10944
10945        let mut buffer_paths_registered = Vec::new();
10946        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10947            let mut lsp_adapters = HashMap::default();
10948            for buffer_handle in buffer_store.buffers() {
10949                let buffer = buffer_handle.read(cx);
10950                let file = match File::from_dyn(buffer.file()) {
10951                    Some(file) => file,
10952                    None => continue,
10953                };
10954                let language = match buffer.language() {
10955                    Some(language) => language,
10956                    None => continue,
10957                };
10958
10959                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10960                    || !lsp_adapters
10961                        .entry(language.name())
10962                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
10963                        .iter()
10964                        .any(|a| a.name == key.name)
10965                {
10966                    continue;
10967                }
10968                // didOpen
10969                let file = match file.as_local() {
10970                    Some(file) => file,
10971                    None => continue,
10972                };
10973
10974                let local = self.as_local_mut().unwrap();
10975
10976                let buffer_id = buffer.remote_id();
10977                if local.registered_buffers.contains_key(&buffer_id) {
10978                    let versions = local
10979                        .buffer_snapshots
10980                        .entry(buffer_id)
10981                        .or_default()
10982                        .entry(server_id)
10983                        .and_modify(|_| {
10984                            assert!(
10985                            false,
10986                            "There should not be an existing snapshot for a newly inserted buffer"
10987                        )
10988                        })
10989                        .or_insert_with(|| {
10990                            vec![LspBufferSnapshot {
10991                                version: 0,
10992                                snapshot: buffer.text_snapshot(),
10993                            }]
10994                        });
10995
10996                    let snapshot = versions.last().unwrap();
10997                    let version = snapshot.version;
10998                    let initial_snapshot = &snapshot.snapshot;
10999                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11000                    language_server.register_buffer(
11001                        uri,
11002                        adapter.language_id(&language.name()),
11003                        version,
11004                        initial_snapshot.text(),
11005                    );
11006                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11007                    local
11008                        .buffers_opened_in_servers
11009                        .entry(buffer_id)
11010                        .or_default()
11011                        .insert(server_id);
11012                }
11013                buffer_handle.update(cx, |buffer, cx| {
11014                    buffer.set_completion_triggers(
11015                        server_id,
11016                        language_server
11017                            .capabilities()
11018                            .completion_provider
11019                            .as_ref()
11020                            .and_then(|provider| {
11021                                provider
11022                                    .trigger_characters
11023                                    .as_ref()
11024                                    .map(|characters| characters.iter().cloned().collect())
11025                            })
11026                            .unwrap_or_default(),
11027                        cx,
11028                    )
11029                });
11030            }
11031        });
11032
11033        for (buffer_id, abs_path) in buffer_paths_registered {
11034            cx.emit(LspStoreEvent::LanguageServerUpdate {
11035                language_server_id: server_id,
11036                name: Some(adapter.name()),
11037                message: proto::update_language_server::Variant::RegisteredForBuffer(
11038                    proto::RegisteredForBuffer {
11039                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11040                        buffer_id: buffer_id.to_proto(),
11041                    },
11042                ),
11043            });
11044        }
11045
11046        cx.notify();
11047    }
11048
11049    pub fn language_servers_running_disk_based_diagnostics(
11050        &self,
11051    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11052        self.language_server_statuses
11053            .iter()
11054            .filter_map(|(id, status)| {
11055                if status.has_pending_diagnostic_updates {
11056                    Some(*id)
11057                } else {
11058                    None
11059                }
11060            })
11061    }
11062
11063    pub(crate) fn cancel_language_server_work_for_buffers(
11064        &mut self,
11065        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11066        cx: &mut Context<Self>,
11067    ) {
11068        if let Some((client, project_id)) = self.upstream_client() {
11069            let request = client.request(proto::CancelLanguageServerWork {
11070                project_id,
11071                work: Some(proto::cancel_language_server_work::Work::Buffers(
11072                    proto::cancel_language_server_work::Buffers {
11073                        buffer_ids: buffers
11074                            .into_iter()
11075                            .map(|b| b.read(cx).remote_id().to_proto())
11076                            .collect(),
11077                    },
11078                )),
11079            });
11080            cx.background_spawn(request).detach_and_log_err(cx);
11081        } else if let Some(local) = self.as_local() {
11082            let servers = buffers
11083                .into_iter()
11084                .flat_map(|buffer| {
11085                    buffer.update(cx, |buffer, cx| {
11086                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11087                    })
11088                })
11089                .collect::<HashSet<_>>();
11090            for server_id in servers {
11091                self.cancel_language_server_work(server_id, None, cx);
11092            }
11093        }
11094    }
11095
11096    pub(crate) fn cancel_language_server_work(
11097        &mut self,
11098        server_id: LanguageServerId,
11099        token_to_cancel: Option<String>,
11100        cx: &mut Context<Self>,
11101    ) {
11102        if let Some(local) = self.as_local() {
11103            let status = self.language_server_statuses.get(&server_id);
11104            let server = local.language_servers.get(&server_id);
11105            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11106            {
11107                for (token, progress) in &status.pending_work {
11108                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11109                        && token != token_to_cancel
11110                    {
11111                        continue;
11112                    }
11113                    if progress.is_cancellable {
11114                        server
11115                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11116                                WorkDoneProgressCancelParams {
11117                                    token: lsp::NumberOrString::String(token.clone()),
11118                                },
11119                            )
11120                            .ok();
11121                    }
11122                }
11123            }
11124        } else if let Some((client, project_id)) = self.upstream_client() {
11125            let request = client.request(proto::CancelLanguageServerWork {
11126                project_id,
11127                work: Some(
11128                    proto::cancel_language_server_work::Work::LanguageServerWork(
11129                        proto::cancel_language_server_work::LanguageServerWork {
11130                            language_server_id: server_id.to_proto(),
11131                            token: token_to_cancel,
11132                        },
11133                    ),
11134                ),
11135            });
11136            cx.background_spawn(request).detach_and_log_err(cx);
11137        }
11138    }
11139
11140    fn register_supplementary_language_server(
11141        &mut self,
11142        id: LanguageServerId,
11143        name: LanguageServerName,
11144        server: Arc<LanguageServer>,
11145        cx: &mut Context<Self>,
11146    ) {
11147        if let Some(local) = self.as_local_mut() {
11148            local
11149                .supplementary_language_servers
11150                .insert(id, (name.clone(), server));
11151            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11152        }
11153    }
11154
11155    fn unregister_supplementary_language_server(
11156        &mut self,
11157        id: LanguageServerId,
11158        cx: &mut Context<Self>,
11159    ) {
11160        if let Some(local) = self.as_local_mut() {
11161            local.supplementary_language_servers.remove(&id);
11162            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11163        }
11164    }
11165
11166    pub(crate) fn supplementary_language_servers(
11167        &self,
11168    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11169        self.as_local().into_iter().flat_map(|local| {
11170            local
11171                .supplementary_language_servers
11172                .iter()
11173                .map(|(id, (name, _))| (*id, name.clone()))
11174        })
11175    }
11176
11177    pub fn language_server_adapter_for_id(
11178        &self,
11179        id: LanguageServerId,
11180    ) -> Option<Arc<CachedLspAdapter>> {
11181        self.as_local()
11182            .and_then(|local| local.language_servers.get(&id))
11183            .and_then(|language_server_state| match language_server_state {
11184                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11185                _ => None,
11186            })
11187    }
11188
11189    pub(super) fn update_local_worktree_language_servers(
11190        &mut self,
11191        worktree_handle: &Entity<Worktree>,
11192        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11193        cx: &mut Context<Self>,
11194    ) {
11195        if changes.is_empty() {
11196            return;
11197        }
11198
11199        let Some(local) = self.as_local() else { return };
11200
11201        local.prettier_store.update(cx, |prettier_store, cx| {
11202            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11203        });
11204
11205        let worktree_id = worktree_handle.read(cx).id();
11206        let mut language_server_ids = local
11207            .language_server_ids
11208            .iter()
11209            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11210            .collect::<Vec<_>>();
11211        language_server_ids.sort();
11212        language_server_ids.dedup();
11213
11214        // let abs_path = worktree_handle.read(cx).abs_path();
11215        for server_id in &language_server_ids {
11216            if let Some(LanguageServerState::Running { server, .. }) =
11217                local.language_servers.get(server_id)
11218                && let Some(watched_paths) = local
11219                    .language_server_watched_paths
11220                    .get(server_id)
11221                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11222            {
11223                let params = lsp::DidChangeWatchedFilesParams {
11224                    changes: changes
11225                        .iter()
11226                        .filter_map(|(path, _, change)| {
11227                            if !watched_paths.is_match(path.as_std_path()) {
11228                                return None;
11229                            }
11230                            let typ = match change {
11231                                PathChange::Loaded => return None,
11232                                PathChange::Added => lsp::FileChangeType::CREATED,
11233                                PathChange::Removed => lsp::FileChangeType::DELETED,
11234                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11235                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11236                            };
11237                            let uri = lsp::Uri::from_file_path(
11238                                worktree_handle.read(cx).absolutize(&path),
11239                            )
11240                            .ok()?;
11241                            Some(lsp::FileEvent { uri, typ })
11242                        })
11243                        .collect(),
11244                };
11245                if !params.changes.is_empty() {
11246                    server
11247                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11248                        .ok();
11249                }
11250            }
11251        }
11252        for (path, _, _) in changes {
11253            if let Some(file_name) = path.file_name()
11254                && local.watched_manifest_filenames.contains(file_name)
11255            {
11256                self.request_workspace_config_refresh();
11257                break;
11258            }
11259        }
11260    }
11261
11262    pub fn wait_for_remote_buffer(
11263        &mut self,
11264        id: BufferId,
11265        cx: &mut Context<Self>,
11266    ) -> Task<Result<Entity<Buffer>>> {
11267        self.buffer_store.update(cx, |buffer_store, cx| {
11268            buffer_store.wait_for_remote_buffer(id, cx)
11269        })
11270    }
11271
11272    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11273        let mut result = proto::Symbol {
11274            language_server_name: symbol.language_server_name.0.to_string(),
11275            source_worktree_id: symbol.source_worktree_id.to_proto(),
11276            language_server_id: symbol.source_language_server_id.to_proto(),
11277            name: symbol.name.clone(),
11278            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11279            start: Some(proto::PointUtf16 {
11280                row: symbol.range.start.0.row,
11281                column: symbol.range.start.0.column,
11282            }),
11283            end: Some(proto::PointUtf16 {
11284                row: symbol.range.end.0.row,
11285                column: symbol.range.end.0.column,
11286            }),
11287            worktree_id: Default::default(),
11288            path: Default::default(),
11289            signature: Default::default(),
11290        };
11291        match &symbol.path {
11292            SymbolLocation::InProject(path) => {
11293                result.worktree_id = path.worktree_id.to_proto();
11294                result.path = path.path.to_proto();
11295            }
11296            SymbolLocation::OutsideProject {
11297                abs_path,
11298                signature,
11299            } => {
11300                result.path = abs_path.to_string_lossy().into_owned();
11301                result.signature = signature.to_vec();
11302            }
11303        }
11304        result
11305    }
11306
11307    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11308        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11309        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11310        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11311
11312        let path = if serialized_symbol.signature.is_empty() {
11313            SymbolLocation::InProject(ProjectPath {
11314                worktree_id,
11315                path: RelPath::from_proto(&serialized_symbol.path)
11316                    .context("invalid symbol path")?,
11317            })
11318        } else {
11319            SymbolLocation::OutsideProject {
11320                abs_path: Path::new(&serialized_symbol.path).into(),
11321                signature: serialized_symbol
11322                    .signature
11323                    .try_into()
11324                    .map_err(|_| anyhow!("invalid signature"))?,
11325            }
11326        };
11327
11328        let start = serialized_symbol.start.context("invalid start")?;
11329        let end = serialized_symbol.end.context("invalid end")?;
11330        Ok(CoreSymbol {
11331            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11332            source_worktree_id,
11333            source_language_server_id: LanguageServerId::from_proto(
11334                serialized_symbol.language_server_id,
11335            ),
11336            path,
11337            name: serialized_symbol.name,
11338            range: Unclipped(PointUtf16::new(start.row, start.column))
11339                ..Unclipped(PointUtf16::new(end.row, end.column)),
11340            kind,
11341        })
11342    }
11343
11344    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11345        let mut serialized_completion = proto::Completion {
11346            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11347            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11348            new_text: completion.new_text.clone(),
11349            ..proto::Completion::default()
11350        };
11351        match &completion.source {
11352            CompletionSource::Lsp {
11353                insert_range,
11354                server_id,
11355                lsp_completion,
11356                lsp_defaults,
11357                resolved,
11358            } => {
11359                let (old_insert_start, old_insert_end) = insert_range
11360                    .as_ref()
11361                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11362                    .unzip();
11363
11364                serialized_completion.old_insert_start = old_insert_start;
11365                serialized_completion.old_insert_end = old_insert_end;
11366                serialized_completion.source = proto::completion::Source::Lsp as i32;
11367                serialized_completion.server_id = server_id.0 as u64;
11368                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11369                serialized_completion.lsp_defaults = lsp_defaults
11370                    .as_deref()
11371                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11372                serialized_completion.resolved = *resolved;
11373            }
11374            CompletionSource::BufferWord {
11375                word_range,
11376                resolved,
11377            } => {
11378                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11379                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11380                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11381                serialized_completion.resolved = *resolved;
11382            }
11383            CompletionSource::Custom => {
11384                serialized_completion.source = proto::completion::Source::Custom as i32;
11385                serialized_completion.resolved = true;
11386            }
11387            CompletionSource::Dap { sort_text } => {
11388                serialized_completion.source = proto::completion::Source::Dap as i32;
11389                serialized_completion.sort_text = Some(sort_text.clone());
11390            }
11391        }
11392
11393        serialized_completion
11394    }
11395
11396    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11397        let old_replace_start = completion
11398            .old_replace_start
11399            .and_then(deserialize_anchor)
11400            .context("invalid old start")?;
11401        let old_replace_end = completion
11402            .old_replace_end
11403            .and_then(deserialize_anchor)
11404            .context("invalid old end")?;
11405        let insert_range = {
11406            match completion.old_insert_start.zip(completion.old_insert_end) {
11407                Some((start, end)) => {
11408                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11409                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11410                    Some(start..end)
11411                }
11412                None => None,
11413            }
11414        };
11415        Ok(CoreCompletion {
11416            replace_range: old_replace_start..old_replace_end,
11417            new_text: completion.new_text,
11418            source: match proto::completion::Source::from_i32(completion.source) {
11419                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11420                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11421                    insert_range,
11422                    server_id: LanguageServerId::from_proto(completion.server_id),
11423                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11424                    lsp_defaults: completion
11425                        .lsp_defaults
11426                        .as_deref()
11427                        .map(serde_json::from_slice)
11428                        .transpose()?,
11429                    resolved: completion.resolved,
11430                },
11431                Some(proto::completion::Source::BufferWord) => {
11432                    let word_range = completion
11433                        .buffer_word_start
11434                        .and_then(deserialize_anchor)
11435                        .context("invalid buffer word start")?
11436                        ..completion
11437                            .buffer_word_end
11438                            .and_then(deserialize_anchor)
11439                            .context("invalid buffer word end")?;
11440                    CompletionSource::BufferWord {
11441                        word_range,
11442                        resolved: completion.resolved,
11443                    }
11444                }
11445                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11446                    sort_text: completion
11447                        .sort_text
11448                        .context("expected sort text to exist")?,
11449                },
11450                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11451            },
11452        })
11453    }
11454
11455    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11456        let (kind, lsp_action) = match &action.lsp_action {
11457            LspAction::Action(code_action) => (
11458                proto::code_action::Kind::Action as i32,
11459                serde_json::to_vec(code_action).unwrap(),
11460            ),
11461            LspAction::Command(command) => (
11462                proto::code_action::Kind::Command as i32,
11463                serde_json::to_vec(command).unwrap(),
11464            ),
11465            LspAction::CodeLens(code_lens) => (
11466                proto::code_action::Kind::CodeLens as i32,
11467                serde_json::to_vec(code_lens).unwrap(),
11468            ),
11469        };
11470
11471        proto::CodeAction {
11472            server_id: action.server_id.0 as u64,
11473            start: Some(serialize_anchor(&action.range.start)),
11474            end: Some(serialize_anchor(&action.range.end)),
11475            lsp_action,
11476            kind,
11477            resolved: action.resolved,
11478        }
11479    }
11480
11481    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11482        let start = action
11483            .start
11484            .and_then(deserialize_anchor)
11485            .context("invalid start")?;
11486        let end = action
11487            .end
11488            .and_then(deserialize_anchor)
11489            .context("invalid end")?;
11490        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11491            Some(proto::code_action::Kind::Action) => {
11492                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11493            }
11494            Some(proto::code_action::Kind::Command) => {
11495                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11496            }
11497            Some(proto::code_action::Kind::CodeLens) => {
11498                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11499            }
11500            None => anyhow::bail!("Unknown action kind {}", action.kind),
11501        };
11502        Ok(CodeAction {
11503            server_id: LanguageServerId(action.server_id as usize),
11504            range: start..end,
11505            resolved: action.resolved,
11506            lsp_action,
11507        })
11508    }
11509
11510    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11511        match &formatting_result {
11512            Ok(_) => self.last_formatting_failure = None,
11513            Err(error) => {
11514                let error_string = format!("{error:#}");
11515                log::error!("Formatting failed: {error_string}");
11516                self.last_formatting_failure
11517                    .replace(error_string.lines().join(" "));
11518            }
11519        }
11520    }
11521
11522    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11523        self.lsp_server_capabilities.remove(&for_server);
11524        for lsp_data in self.lsp_data.values_mut() {
11525            lsp_data.remove_server_data(for_server);
11526        }
11527        if let Some(local) = self.as_local_mut() {
11528            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11529            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11530                buffer_servers.remove(&for_server);
11531            }
11532        }
11533    }
11534
11535    pub fn result_id(
11536        &self,
11537        server_id: LanguageServerId,
11538        buffer_id: BufferId,
11539        cx: &App,
11540    ) -> Option<String> {
11541        let abs_path = self
11542            .buffer_store
11543            .read(cx)
11544            .get(buffer_id)
11545            .and_then(|b| File::from_dyn(b.read(cx).file()))
11546            .map(|f| f.abs_path(cx))?;
11547        self.as_local()?
11548            .buffer_pull_diagnostics_result_ids
11549            .get(&server_id)?
11550            .get(&abs_path)?
11551            .clone()
11552    }
11553
11554    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11555        let Some(local) = self.as_local() else {
11556            return HashMap::default();
11557        };
11558        local
11559            .buffer_pull_diagnostics_result_ids
11560            .get(&server_id)
11561            .into_iter()
11562            .flatten()
11563            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11564            .collect()
11565    }
11566
11567    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11568        if let Some(LanguageServerState::Running {
11569            workspace_diagnostics_refresh_tasks,
11570            ..
11571        }) = self
11572            .as_local_mut()
11573            .and_then(|local| local.language_servers.get_mut(&server_id))
11574        {
11575            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11576                diagnostics.refresh_tx.try_send(()).ok();
11577            }
11578        }
11579    }
11580
11581    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11582        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11583            return;
11584        };
11585        let Some(local) = self.as_local_mut() else {
11586            return;
11587        };
11588
11589        for server_id in buffer.update(cx, |buffer, cx| {
11590            local.language_server_ids_for_buffer(buffer, cx)
11591        }) {
11592            if let Some(LanguageServerState::Running {
11593                workspace_diagnostics_refresh_tasks,
11594                ..
11595            }) = local.language_servers.get_mut(&server_id)
11596            {
11597                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11598                    diagnostics.refresh_tx.try_send(()).ok();
11599                }
11600            }
11601        }
11602    }
11603
11604    fn apply_workspace_diagnostic_report(
11605        &mut self,
11606        server_id: LanguageServerId,
11607        report: lsp::WorkspaceDiagnosticReportResult,
11608        cx: &mut Context<Self>,
11609    ) {
11610        let workspace_diagnostics =
11611            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11612        let mut unchanged_buffers = HashSet::default();
11613        let mut changed_buffers = HashSet::default();
11614        let workspace_diagnostics_updates = workspace_diagnostics
11615            .into_iter()
11616            .filter_map(
11617                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11618                    LspPullDiagnostics::Response {
11619                        server_id,
11620                        uri,
11621                        diagnostics,
11622                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11623                    LspPullDiagnostics::Default => None,
11624                },
11625            )
11626            .fold(
11627                HashMap::default(),
11628                |mut acc, (server_id, uri, diagnostics, version)| {
11629                    let (result_id, diagnostics) = match diagnostics {
11630                        PulledDiagnostics::Unchanged { result_id } => {
11631                            unchanged_buffers.insert(uri.clone());
11632                            (Some(result_id), Vec::new())
11633                        }
11634                        PulledDiagnostics::Changed {
11635                            result_id,
11636                            diagnostics,
11637                        } => {
11638                            changed_buffers.insert(uri.clone());
11639                            (result_id, diagnostics)
11640                        }
11641                    };
11642                    let disk_based_sources = Cow::Owned(
11643                        self.language_server_adapter_for_id(server_id)
11644                            .as_ref()
11645                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11646                            .unwrap_or(&[])
11647                            .to_vec(),
11648                    );
11649                    acc.entry(server_id)
11650                        .or_insert_with(Vec::new)
11651                        .push(DocumentDiagnosticsUpdate {
11652                            server_id,
11653                            diagnostics: lsp::PublishDiagnosticsParams {
11654                                uri,
11655                                diagnostics,
11656                                version,
11657                            },
11658                            result_id,
11659                            disk_based_sources,
11660                        });
11661                    acc
11662                },
11663            );
11664
11665        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11666            self.merge_lsp_diagnostics(
11667                DiagnosticSourceKind::Pulled,
11668                diagnostic_updates,
11669                |buffer, old_diagnostic, cx| {
11670                    File::from_dyn(buffer.file())
11671                        .and_then(|file| {
11672                            let abs_path = file.as_local()?.abs_path(cx);
11673                            lsp::Uri::from_file_path(abs_path).ok()
11674                        })
11675                        .is_none_or(|buffer_uri| {
11676                            unchanged_buffers.contains(&buffer_uri)
11677                                || match old_diagnostic.source_kind {
11678                                    DiagnosticSourceKind::Pulled => {
11679                                        !changed_buffers.contains(&buffer_uri)
11680                                    }
11681                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11682                                        true
11683                                    }
11684                                }
11685                        })
11686                },
11687                cx,
11688            )
11689            .log_err();
11690        }
11691    }
11692
11693    fn register_server_capabilities(
11694        &mut self,
11695        server_id: LanguageServerId,
11696        params: lsp::RegistrationParams,
11697        cx: &mut Context<Self>,
11698    ) -> anyhow::Result<()> {
11699        let server = self
11700            .language_server_for_id(server_id)
11701            .with_context(|| format!("no server {server_id} found"))?;
11702        for reg in params.registrations {
11703            match reg.method.as_str() {
11704                "workspace/didChangeWatchedFiles" => {
11705                    if let Some(options) = reg.register_options {
11706                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11707                            let caps = serde_json::from_value(options)?;
11708                            local_lsp_store
11709                                .on_lsp_did_change_watched_files(server_id, ®.id, caps, cx);
11710                            true
11711                        } else {
11712                            false
11713                        };
11714                        if notify {
11715                            notify_server_capabilities_updated(&server, cx);
11716                        }
11717                    }
11718                }
11719                "workspace/didChangeConfiguration" => {
11720                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11721                }
11722                "workspace/didChangeWorkspaceFolders" => {
11723                    // In this case register options is an empty object, we can ignore it
11724                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11725                        supported: Some(true),
11726                        change_notifications: Some(OneOf::Right(reg.id)),
11727                    };
11728                    server.update_capabilities(|capabilities| {
11729                        capabilities
11730                            .workspace
11731                            .get_or_insert_default()
11732                            .workspace_folders = Some(caps);
11733                    });
11734                    notify_server_capabilities_updated(&server, cx);
11735                }
11736                "workspace/symbol" => {
11737                    let options = parse_register_capabilities(reg)?;
11738                    server.update_capabilities(|capabilities| {
11739                        capabilities.workspace_symbol_provider = Some(options);
11740                    });
11741                    notify_server_capabilities_updated(&server, cx);
11742                }
11743                "workspace/fileOperations" => {
11744                    if let Some(options) = reg.register_options {
11745                        let caps = serde_json::from_value(options)?;
11746                        server.update_capabilities(|capabilities| {
11747                            capabilities
11748                                .workspace
11749                                .get_or_insert_default()
11750                                .file_operations = Some(caps);
11751                        });
11752                        notify_server_capabilities_updated(&server, cx);
11753                    }
11754                }
11755                "workspace/executeCommand" => {
11756                    if let Some(options) = reg.register_options {
11757                        let options = serde_json::from_value(options)?;
11758                        server.update_capabilities(|capabilities| {
11759                            capabilities.execute_command_provider = Some(options);
11760                        });
11761                        notify_server_capabilities_updated(&server, cx);
11762                    }
11763                }
11764                "textDocument/rangeFormatting" => {
11765                    let options = parse_register_capabilities(reg)?;
11766                    server.update_capabilities(|capabilities| {
11767                        capabilities.document_range_formatting_provider = Some(options);
11768                    });
11769                    notify_server_capabilities_updated(&server, cx);
11770                }
11771                "textDocument/onTypeFormatting" => {
11772                    if let Some(options) = reg
11773                        .register_options
11774                        .map(serde_json::from_value)
11775                        .transpose()?
11776                    {
11777                        server.update_capabilities(|capabilities| {
11778                            capabilities.document_on_type_formatting_provider = Some(options);
11779                        });
11780                        notify_server_capabilities_updated(&server, cx);
11781                    }
11782                }
11783                "textDocument/formatting" => {
11784                    let options = parse_register_capabilities(reg)?;
11785                    server.update_capabilities(|capabilities| {
11786                        capabilities.document_formatting_provider = Some(options);
11787                    });
11788                    notify_server_capabilities_updated(&server, cx);
11789                }
11790                "textDocument/rename" => {
11791                    let options = parse_register_capabilities(reg)?;
11792                    server.update_capabilities(|capabilities| {
11793                        capabilities.rename_provider = Some(options);
11794                    });
11795                    notify_server_capabilities_updated(&server, cx);
11796                }
11797                "textDocument/inlayHint" => {
11798                    let options = parse_register_capabilities(reg)?;
11799                    server.update_capabilities(|capabilities| {
11800                        capabilities.inlay_hint_provider = Some(options);
11801                    });
11802                    notify_server_capabilities_updated(&server, cx);
11803                }
11804                "textDocument/documentSymbol" => {
11805                    let options = parse_register_capabilities(reg)?;
11806                    server.update_capabilities(|capabilities| {
11807                        capabilities.document_symbol_provider = Some(options);
11808                    });
11809                    notify_server_capabilities_updated(&server, cx);
11810                }
11811                "textDocument/codeAction" => {
11812                    let options = parse_register_capabilities(reg)?;
11813                    let provider = match options {
11814                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11815                        OneOf::Right(caps) => caps,
11816                    };
11817                    server.update_capabilities(|capabilities| {
11818                        capabilities.code_action_provider = Some(provider);
11819                    });
11820                    notify_server_capabilities_updated(&server, cx);
11821                }
11822                "textDocument/definition" => {
11823                    let options = parse_register_capabilities(reg)?;
11824                    server.update_capabilities(|capabilities| {
11825                        capabilities.definition_provider = Some(options);
11826                    });
11827                    notify_server_capabilities_updated(&server, cx);
11828                }
11829                "textDocument/completion" => {
11830                    if let Some(caps) = reg
11831                        .register_options
11832                        .map(serde_json::from_value)
11833                        .transpose()?
11834                    {
11835                        server.update_capabilities(|capabilities| {
11836                            capabilities.completion_provider = Some(caps);
11837                        });
11838                        notify_server_capabilities_updated(&server, cx);
11839                    }
11840                }
11841                "textDocument/hover" => {
11842                    let options = parse_register_capabilities(reg)?;
11843                    let provider = match options {
11844                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11845                        OneOf::Right(caps) => caps,
11846                    };
11847                    server.update_capabilities(|capabilities| {
11848                        capabilities.hover_provider = Some(provider);
11849                    });
11850                    notify_server_capabilities_updated(&server, cx);
11851                }
11852                "textDocument/signatureHelp" => {
11853                    if let Some(caps) = reg
11854                        .register_options
11855                        .map(serde_json::from_value)
11856                        .transpose()?
11857                    {
11858                        server.update_capabilities(|capabilities| {
11859                            capabilities.signature_help_provider = Some(caps);
11860                        });
11861                        notify_server_capabilities_updated(&server, cx);
11862                    }
11863                }
11864                "textDocument/didChange" => {
11865                    if let Some(sync_kind) = reg
11866                        .register_options
11867                        .and_then(|opts| opts.get("syncKind").cloned())
11868                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11869                        .transpose()?
11870                    {
11871                        server.update_capabilities(|capabilities| {
11872                            let mut sync_options =
11873                                Self::take_text_document_sync_options(capabilities);
11874                            sync_options.change = Some(sync_kind);
11875                            capabilities.text_document_sync =
11876                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11877                        });
11878                        notify_server_capabilities_updated(&server, cx);
11879                    }
11880                }
11881                "textDocument/didSave" => {
11882                    if let Some(include_text) = reg
11883                        .register_options
11884                        .map(|opts| {
11885                            let transpose = opts
11886                                .get("includeText")
11887                                .cloned()
11888                                .map(serde_json::from_value::<Option<bool>>)
11889                                .transpose();
11890                            match transpose {
11891                                Ok(value) => Ok(value.flatten()),
11892                                Err(e) => Err(e),
11893                            }
11894                        })
11895                        .transpose()?
11896                    {
11897                        server.update_capabilities(|capabilities| {
11898                            let mut sync_options =
11899                                Self::take_text_document_sync_options(capabilities);
11900                            sync_options.save =
11901                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11902                                    include_text,
11903                                }));
11904                            capabilities.text_document_sync =
11905                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11906                        });
11907                        notify_server_capabilities_updated(&server, cx);
11908                    }
11909                }
11910                "textDocument/codeLens" => {
11911                    if let Some(caps) = reg
11912                        .register_options
11913                        .map(serde_json::from_value)
11914                        .transpose()?
11915                    {
11916                        server.update_capabilities(|capabilities| {
11917                            capabilities.code_lens_provider = Some(caps);
11918                        });
11919                        notify_server_capabilities_updated(&server, cx);
11920                    }
11921                }
11922                "textDocument/diagnostic" => {
11923                    if let Some(caps) = reg
11924                        .register_options
11925                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
11926                        .transpose()?
11927                    {
11928                        let local = self
11929                            .as_local_mut()
11930                            .context("Expected LSP Store to be local")?;
11931                        let state = local
11932                            .language_servers
11933                            .get_mut(&server_id)
11934                            .context("Could not obtain Language Servers state")?;
11935                        local
11936                            .language_server_dynamic_registrations
11937                            .get_mut(&server_id)
11938                            .and_then(|registrations| {
11939                                registrations
11940                                    .diagnostics
11941                                    .insert(Some(reg.id.clone()), caps.clone())
11942                            });
11943
11944                        let mut can_now_provide_diagnostics = false;
11945                        if let LanguageServerState::Running {
11946                            workspace_diagnostics_refresh_tasks,
11947                            ..
11948                        } = state
11949                            && let Some(task) = lsp_workspace_diagnostics_refresh(
11950                                Some(reg.id.clone()),
11951                                caps.clone(),
11952                                server.clone(),
11953                                cx,
11954                            )
11955                        {
11956                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
11957                            can_now_provide_diagnostics = true;
11958                        }
11959
11960                        // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
11961                        // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
11962                        // as it'll think that they're not supported.
11963                        if can_now_provide_diagnostics {
11964                            server.update_capabilities(|capabilities| {
11965                                debug_assert!(capabilities.diagnostic_provider.is_none());
11966                                capabilities.diagnostic_provider = Some(caps);
11967                            });
11968                        }
11969
11970                        notify_server_capabilities_updated(&server, cx);
11971                    }
11972                }
11973                "textDocument/documentColor" => {
11974                    let options = parse_register_capabilities(reg)?;
11975                    let provider = match options {
11976                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
11977                        OneOf::Right(caps) => caps,
11978                    };
11979                    server.update_capabilities(|capabilities| {
11980                        capabilities.color_provider = Some(provider);
11981                    });
11982                    notify_server_capabilities_updated(&server, cx);
11983                }
11984                _ => log::warn!("unhandled capability registration: {reg:?}"),
11985            }
11986        }
11987
11988        Ok(())
11989    }
11990
11991    fn unregister_server_capabilities(
11992        &mut self,
11993        server_id: LanguageServerId,
11994        params: lsp::UnregistrationParams,
11995        cx: &mut Context<Self>,
11996    ) -> anyhow::Result<()> {
11997        let server = self
11998            .language_server_for_id(server_id)
11999            .with_context(|| format!("no server {server_id} found"))?;
12000        for unreg in params.unregisterations.iter() {
12001            match unreg.method.as_str() {
12002                "workspace/didChangeWatchedFiles" => {
12003                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12004                        local_lsp_store
12005                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12006                        true
12007                    } else {
12008                        false
12009                    };
12010                    if notify {
12011                        notify_server_capabilities_updated(&server, cx);
12012                    }
12013                }
12014                "workspace/didChangeConfiguration" => {
12015                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12016                }
12017                "workspace/didChangeWorkspaceFolders" => {
12018                    server.update_capabilities(|capabilities| {
12019                        capabilities
12020                            .workspace
12021                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12022                                workspace_folders: None,
12023                                file_operations: None,
12024                            })
12025                            .workspace_folders = None;
12026                    });
12027                    notify_server_capabilities_updated(&server, cx);
12028                }
12029                "workspace/symbol" => {
12030                    server.update_capabilities(|capabilities| {
12031                        capabilities.workspace_symbol_provider = None
12032                    });
12033                    notify_server_capabilities_updated(&server, cx);
12034                }
12035                "workspace/fileOperations" => {
12036                    server.update_capabilities(|capabilities| {
12037                        capabilities
12038                            .workspace
12039                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12040                                workspace_folders: None,
12041                                file_operations: None,
12042                            })
12043                            .file_operations = None;
12044                    });
12045                    notify_server_capabilities_updated(&server, cx);
12046                }
12047                "workspace/executeCommand" => {
12048                    server.update_capabilities(|capabilities| {
12049                        capabilities.execute_command_provider = None;
12050                    });
12051                    notify_server_capabilities_updated(&server, cx);
12052                }
12053                "textDocument/rangeFormatting" => {
12054                    server.update_capabilities(|capabilities| {
12055                        capabilities.document_range_formatting_provider = None
12056                    });
12057                    notify_server_capabilities_updated(&server, cx);
12058                }
12059                "textDocument/onTypeFormatting" => {
12060                    server.update_capabilities(|capabilities| {
12061                        capabilities.document_on_type_formatting_provider = None;
12062                    });
12063                    notify_server_capabilities_updated(&server, cx);
12064                }
12065                "textDocument/formatting" => {
12066                    server.update_capabilities(|capabilities| {
12067                        capabilities.document_formatting_provider = None;
12068                    });
12069                    notify_server_capabilities_updated(&server, cx);
12070                }
12071                "textDocument/rename" => {
12072                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12073                    notify_server_capabilities_updated(&server, cx);
12074                }
12075                "textDocument/codeAction" => {
12076                    server.update_capabilities(|capabilities| {
12077                        capabilities.code_action_provider = None;
12078                    });
12079                    notify_server_capabilities_updated(&server, cx);
12080                }
12081                "textDocument/definition" => {
12082                    server.update_capabilities(|capabilities| {
12083                        capabilities.definition_provider = None;
12084                    });
12085                    notify_server_capabilities_updated(&server, cx);
12086                }
12087                "textDocument/completion" => {
12088                    server.update_capabilities(|capabilities| {
12089                        capabilities.completion_provider = None;
12090                    });
12091                    notify_server_capabilities_updated(&server, cx);
12092                }
12093                "textDocument/hover" => {
12094                    server.update_capabilities(|capabilities| {
12095                        capabilities.hover_provider = None;
12096                    });
12097                    notify_server_capabilities_updated(&server, cx);
12098                }
12099                "textDocument/signatureHelp" => {
12100                    server.update_capabilities(|capabilities| {
12101                        capabilities.signature_help_provider = None;
12102                    });
12103                    notify_server_capabilities_updated(&server, cx);
12104                }
12105                "textDocument/didChange" => {
12106                    server.update_capabilities(|capabilities| {
12107                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12108                        sync_options.change = None;
12109                        capabilities.text_document_sync =
12110                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12111                    });
12112                    notify_server_capabilities_updated(&server, cx);
12113                }
12114                "textDocument/didSave" => {
12115                    server.update_capabilities(|capabilities| {
12116                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12117                        sync_options.save = None;
12118                        capabilities.text_document_sync =
12119                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12120                    });
12121                    notify_server_capabilities_updated(&server, cx);
12122                }
12123                "textDocument/codeLens" => {
12124                    server.update_capabilities(|capabilities| {
12125                        capabilities.code_lens_provider = None;
12126                    });
12127                    notify_server_capabilities_updated(&server, cx);
12128                }
12129                "textDocument/diagnostic" => {
12130                    let local = self
12131                        .as_local_mut()
12132                        .context("Expected LSP Store to be local")?;
12133
12134                    let state = local
12135                        .language_servers
12136                        .get_mut(&server_id)
12137                        .context("Could not obtain Language Servers state")?;
12138                    let options = local
12139                        .language_server_dynamic_registrations
12140                        .get_mut(&server_id)
12141                        .with_context(|| {
12142                            format!("Expected dynamic registration to exist for server {server_id}")
12143                        })?.diagnostics
12144                        .remove(&Some(unreg.id.clone()))
12145                        .with_context(|| format!(
12146                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12147                            unreg.id)
12148                        )?;
12149
12150                    let mut has_any_diagnostic_providers_still = true;
12151                    if let Some(identifier) = diagnostic_identifier(&options)
12152                        && let LanguageServerState::Running {
12153                            workspace_diagnostics_refresh_tasks,
12154                            ..
12155                        } = state
12156                    {
12157                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12158                        has_any_diagnostic_providers_still =
12159                            !workspace_diagnostics_refresh_tasks.is_empty();
12160                    }
12161
12162                    if !has_any_diagnostic_providers_still {
12163                        server.update_capabilities(|capabilities| {
12164                            debug_assert!(capabilities.diagnostic_provider.is_some());
12165                            capabilities.diagnostic_provider = None;
12166                        });
12167                    }
12168
12169                    notify_server_capabilities_updated(&server, cx);
12170                }
12171                "textDocument/documentColor" => {
12172                    server.update_capabilities(|capabilities| {
12173                        capabilities.color_provider = None;
12174                    });
12175                    notify_server_capabilities_updated(&server, cx);
12176                }
12177                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12178            }
12179        }
12180
12181        Ok(())
12182    }
12183
12184    async fn deduplicate_range_based_lsp_requests<T>(
12185        lsp_store: &Entity<Self>,
12186        server_id: Option<LanguageServerId>,
12187        lsp_request_id: LspRequestId,
12188        proto_request: &T::ProtoRequest,
12189        range: Range<Anchor>,
12190        cx: &mut AsyncApp,
12191    ) -> Result<()>
12192    where
12193        T: LspCommand,
12194        T::ProtoRequest: proto::LspRequestMessage,
12195    {
12196        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12197        let version = deserialize_version(proto_request.buffer_version());
12198        let buffer = lsp_store.update(cx, |this, cx| {
12199            this.buffer_store.read(cx).get_existing(buffer_id)
12200        })??;
12201        buffer
12202            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12203            .await?;
12204        lsp_store.update(cx, |lsp_store, cx| {
12205            let lsp_data = lsp_store
12206                .lsp_data
12207                .entry(buffer_id)
12208                .or_insert_with(|| BufferLspData::new(&buffer, cx));
12209            let chunks_queried_for = lsp_data
12210                .inlay_hints
12211                .applicable_chunks(&[range])
12212                .collect::<Vec<_>>();
12213            match chunks_queried_for.as_slice() {
12214                &[chunk] => {
12215                    let key = LspKey {
12216                        request_type: TypeId::of::<T>(),
12217                        server_queried: server_id,
12218                    };
12219                    let previous_request = lsp_data
12220                        .chunk_lsp_requests
12221                        .entry(key)
12222                        .or_default()
12223                        .insert(chunk, lsp_request_id);
12224                    if let Some((previous_request, running_requests)) =
12225                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12226                    {
12227                        running_requests.remove(&previous_request);
12228                    }
12229                }
12230                _ambiguous_chunks => {
12231                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12232                    // there, a buffer version-based check will be performed and outdated requests discarded.
12233                }
12234            }
12235            anyhow::Ok(())
12236        })??;
12237
12238        Ok(())
12239    }
12240
12241    async fn query_lsp_locally<T>(
12242        lsp_store: Entity<Self>,
12243        for_server_id: Option<LanguageServerId>,
12244        sender_id: proto::PeerId,
12245        lsp_request_id: LspRequestId,
12246        proto_request: T::ProtoRequest,
12247        position: Option<Anchor>,
12248        cx: &mut AsyncApp,
12249    ) -> Result<()>
12250    where
12251        T: LspCommand + Clone,
12252        T::ProtoRequest: proto::LspRequestMessage,
12253        <T::ProtoRequest as proto::RequestMessage>::Response:
12254            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12255    {
12256        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12257        let version = deserialize_version(proto_request.buffer_version());
12258        let buffer = lsp_store.update(cx, |this, cx| {
12259            this.buffer_store.read(cx).get_existing(buffer_id)
12260        })??;
12261        buffer
12262            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12263            .await?;
12264        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12265        let request =
12266            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12267        let key = LspKey {
12268            request_type: TypeId::of::<T>(),
12269            server_queried: for_server_id,
12270        };
12271        lsp_store.update(cx, |lsp_store, cx| {
12272            let request_task = match for_server_id {
12273                Some(server_id) => {
12274                    let server_task = lsp_store.request_lsp(
12275                        buffer.clone(),
12276                        LanguageServerToQuery::Other(server_id),
12277                        request.clone(),
12278                        cx,
12279                    );
12280                    cx.background_spawn(async move {
12281                        let mut responses = Vec::new();
12282                        match server_task.await {
12283                            Ok(response) => responses.push((server_id, response)),
12284                            Err(e) => log::error!(
12285                                "Error handling response for request {request:?}: {e:#}"
12286                            ),
12287                        }
12288                        responses
12289                    })
12290                }
12291                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12292            };
12293            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12294            if T::ProtoRequest::stop_previous_requests() {
12295                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12296                    lsp_requests.clear();
12297                }
12298            }
12299            lsp_data.lsp_requests.entry(key).or_default().insert(
12300                lsp_request_id,
12301                cx.spawn(async move |lsp_store, cx| {
12302                    let response = request_task.await;
12303                    lsp_store
12304                        .update(cx, |lsp_store, cx| {
12305                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12306                            {
12307                                let response = response
12308                                    .into_iter()
12309                                    .map(|(server_id, response)| {
12310                                        (
12311                                            server_id.to_proto(),
12312                                            T::response_to_proto(
12313                                                response,
12314                                                lsp_store,
12315                                                sender_id,
12316                                                &buffer_version,
12317                                                cx,
12318                                            )
12319                                            .into(),
12320                                        )
12321                                    })
12322                                    .collect::<HashMap<_, _>>();
12323                                match client.send_lsp_response::<T::ProtoRequest>(
12324                                    project_id,
12325                                    lsp_request_id,
12326                                    response,
12327                                ) {
12328                                    Ok(()) => {}
12329                                    Err(e) => {
12330                                        log::error!("Failed to send LSP response: {e:#}",)
12331                                    }
12332                                }
12333                            }
12334                        })
12335                        .ok();
12336                }),
12337            );
12338        })?;
12339        Ok(())
12340    }
12341
12342    fn take_text_document_sync_options(
12343        capabilities: &mut lsp::ServerCapabilities,
12344    ) -> lsp::TextDocumentSyncOptions {
12345        match capabilities.text_document_sync.take() {
12346            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12347            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12348                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12349                sync_options.change = Some(sync_kind);
12350                sync_options
12351            }
12352            None => lsp::TextDocumentSyncOptions::default(),
12353        }
12354    }
12355
12356    #[cfg(any(test, feature = "test-support"))]
12357    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12358        Some(
12359            self.lsp_data
12360                .get_mut(&buffer_id)?
12361                .code_lens
12362                .take()?
12363                .update
12364                .take()?
12365                .1,
12366        )
12367    }
12368
12369    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12370        self.downstream_client.clone()
12371    }
12372
12373    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12374        self.worktree_store.clone()
12375    }
12376
12377    /// Gets what's stored in the LSP data for the given buffer.
12378    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12379        self.lsp_data.get_mut(&buffer_id)
12380    }
12381
12382    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12383    /// new [`BufferLspData`] will be created to replace the previous state.
12384    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12385        let (buffer_id, buffer_version) =
12386            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12387        let lsp_data = self
12388            .lsp_data
12389            .entry(buffer_id)
12390            .or_insert_with(|| BufferLspData::new(buffer, cx));
12391        if buffer_version.changed_since(&lsp_data.buffer_version) {
12392            *lsp_data = BufferLspData::new(buffer, cx);
12393        }
12394        lsp_data
12395    }
12396}
12397
12398// Registration with registerOptions as null, should fallback to true.
12399// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12400fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12401    reg: lsp::Registration,
12402) -> Result<OneOf<bool, T>> {
12403    Ok(match reg.register_options {
12404        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12405        None => OneOf::Left(true),
12406    })
12407}
12408
12409fn subscribe_to_binary_statuses(
12410    languages: &Arc<LanguageRegistry>,
12411    cx: &mut Context<'_, LspStore>,
12412) -> Task<()> {
12413    let mut server_statuses = languages.language_server_binary_statuses();
12414    cx.spawn(async move |lsp_store, cx| {
12415        while let Some((server_name, binary_status)) = server_statuses.next().await {
12416            if lsp_store
12417                .update(cx, |_, cx| {
12418                    let mut message = None;
12419                    let binary_status = match binary_status {
12420                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12421                        BinaryStatus::CheckingForUpdate => {
12422                            proto::ServerBinaryStatus::CheckingForUpdate
12423                        }
12424                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12425                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12426                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12427                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12428                        BinaryStatus::Failed { error } => {
12429                            message = Some(error);
12430                            proto::ServerBinaryStatus::Failed
12431                        }
12432                    };
12433                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12434                        // Binary updates are about the binary that might not have any language server id at that point.
12435                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12436                        language_server_id: LanguageServerId(0),
12437                        name: Some(server_name),
12438                        message: proto::update_language_server::Variant::StatusUpdate(
12439                            proto::StatusUpdate {
12440                                message,
12441                                status: Some(proto::status_update::Status::Binary(
12442                                    binary_status as i32,
12443                                )),
12444                            },
12445                        ),
12446                    });
12447                })
12448                .is_err()
12449            {
12450                break;
12451            }
12452        }
12453    })
12454}
12455
12456fn lsp_workspace_diagnostics_refresh(
12457    registration_id: Option<String>,
12458    options: DiagnosticServerCapabilities,
12459    server: Arc<LanguageServer>,
12460    cx: &mut Context<'_, LspStore>,
12461) -> Option<WorkspaceRefreshTask> {
12462    let identifier = diagnostic_identifier(&options)?;
12463
12464    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12465    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12466    refresh_tx.try_send(()).ok();
12467
12468    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12469        let mut attempts = 0;
12470        let max_attempts = 50;
12471        let mut requests = 0;
12472
12473        loop {
12474            let Some(()) = refresh_rx.recv().await else {
12475                return;
12476            };
12477
12478            'request: loop {
12479                requests += 1;
12480                if attempts > max_attempts {
12481                    log::error!(
12482                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12483                    );
12484                    return;
12485                }
12486                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12487                cx.background_executor()
12488                    .timer(Duration::from_millis(backoff_millis))
12489                    .await;
12490                attempts += 1;
12491
12492                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12493                    lsp_store
12494                        .all_result_ids(server.server_id())
12495                        .into_iter()
12496                        .filter_map(|(abs_path, result_id)| {
12497                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12498                            Some(lsp::PreviousResultId {
12499                                uri,
12500                                value: result_id,
12501                            })
12502                        })
12503                        .collect()
12504                }) else {
12505                    return;
12506                };
12507
12508                let token = if let Some(identifier) = ®istration_id {
12509                    format!(
12510                        "workspace/diagnostic/{}/{requests}/id:{identifier}",
12511                        server.server_id(),
12512                    )
12513                } else {
12514                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12515                };
12516
12517                progress_rx.try_recv().ok();
12518                let timer =
12519                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12520                let progress = pin!(progress_rx.recv().fuse());
12521                let response_result = server
12522                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12523                        lsp::WorkspaceDiagnosticParams {
12524                            previous_result_ids,
12525                            identifier: identifier.clone(),
12526                            work_done_progress_params: Default::default(),
12527                            partial_result_params: lsp::PartialResultParams {
12528                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12529                            },
12530                        },
12531                        select(timer, progress).then(|either| match either {
12532                            Either::Left((message, ..)) => ready(message).left_future(),
12533                            Either::Right(..) => pending::<String>().right_future(),
12534                        }),
12535                    )
12536                    .await;
12537
12538                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12539                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12540                match response_result {
12541                    ConnectionResult::Timeout => {
12542                        log::error!("Timeout during workspace diagnostics pull");
12543                        continue 'request;
12544                    }
12545                    ConnectionResult::ConnectionReset => {
12546                        log::error!("Server closed a workspace diagnostics pull request");
12547                        continue 'request;
12548                    }
12549                    ConnectionResult::Result(Err(e)) => {
12550                        log::error!("Error during workspace diagnostics pull: {e:#}");
12551                        break 'request;
12552                    }
12553                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12554                        attempts = 0;
12555                        if lsp_store
12556                            .update(cx, |lsp_store, cx| {
12557                                lsp_store.apply_workspace_diagnostic_report(
12558                                    server.server_id(),
12559                                    pulled_diagnostics,
12560                                    cx,
12561                                )
12562                            })
12563                            .is_err()
12564                        {
12565                            return;
12566                        }
12567                        break 'request;
12568                    }
12569                }
12570            }
12571        }
12572    });
12573
12574    Some(WorkspaceRefreshTask {
12575        refresh_tx,
12576        progress_tx,
12577        task: workspace_query_language_server,
12578    })
12579}
12580
12581fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12582    match &options {
12583        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12584            if !diagnostic_options.workspace_diagnostics {
12585                return None;
12586            }
12587            Some(diagnostic_options.identifier.clone())
12588        }
12589        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12590            let diagnostic_options = ®istration_options.diagnostic_options;
12591            if !diagnostic_options.workspace_diagnostics {
12592                return None;
12593            }
12594            Some(diagnostic_options.identifier.clone())
12595        }
12596    }
12597}
12598
12599fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12600    let CompletionSource::BufferWord {
12601        word_range,
12602        resolved,
12603    } = &mut completion.source
12604    else {
12605        return;
12606    };
12607    if *resolved {
12608        return;
12609    }
12610
12611    if completion.new_text
12612        != snapshot
12613            .text_for_range(word_range.clone())
12614            .collect::<String>()
12615    {
12616        return;
12617    }
12618
12619    let mut offset = 0;
12620    for chunk in snapshot.chunks(word_range.clone(), true) {
12621        let end_offset = offset + chunk.text.len();
12622        if let Some(highlight_id) = chunk.syntax_highlight_id {
12623            completion
12624                .label
12625                .runs
12626                .push((offset..end_offset, highlight_id));
12627        }
12628        offset = end_offset;
12629    }
12630    *resolved = true;
12631}
12632
12633impl EventEmitter<LspStoreEvent> for LspStore {}
12634
12635fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12636    hover
12637        .contents
12638        .retain(|hover_block| !hover_block.text.trim().is_empty());
12639    if hover.contents.is_empty() {
12640        None
12641    } else {
12642        Some(hover)
12643    }
12644}
12645
12646async fn populate_labels_for_completions(
12647    new_completions: Vec<CoreCompletion>,
12648    language: Option<Arc<Language>>,
12649    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12650) -> Vec<Completion> {
12651    let lsp_completions = new_completions
12652        .iter()
12653        .filter_map(|new_completion| {
12654            new_completion
12655                .source
12656                .lsp_completion(true)
12657                .map(|lsp_completion| lsp_completion.into_owned())
12658        })
12659        .collect::<Vec<_>>();
12660
12661    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12662        lsp_adapter
12663            .labels_for_completions(&lsp_completions, language)
12664            .await
12665            .log_err()
12666            .unwrap_or_default()
12667    } else {
12668        Vec::new()
12669    }
12670    .into_iter()
12671    .fuse();
12672
12673    let mut completions = Vec::new();
12674    for completion in new_completions {
12675        match completion.source.lsp_completion(true) {
12676            Some(lsp_completion) => {
12677                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12678
12679                let mut label = labels.next().flatten().unwrap_or_else(|| {
12680                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12681                });
12682                ensure_uniform_list_compatible_label(&mut label);
12683                completions.push(Completion {
12684                    label,
12685                    documentation,
12686                    replace_range: completion.replace_range,
12687                    new_text: completion.new_text,
12688                    insert_text_mode: lsp_completion.insert_text_mode,
12689                    source: completion.source,
12690                    icon_path: None,
12691                    confirm: None,
12692                });
12693            }
12694            None => {
12695                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12696                ensure_uniform_list_compatible_label(&mut label);
12697                completions.push(Completion {
12698                    label,
12699                    documentation: None,
12700                    replace_range: completion.replace_range,
12701                    new_text: completion.new_text,
12702                    source: completion.source,
12703                    insert_text_mode: None,
12704                    icon_path: None,
12705                    confirm: None,
12706                });
12707            }
12708        }
12709    }
12710    completions
12711}
12712
12713#[derive(Debug)]
12714pub enum LanguageServerToQuery {
12715    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12716    FirstCapable,
12717    /// Query a specific language server.
12718    Other(LanguageServerId),
12719}
12720
12721#[derive(Default)]
12722struct RenamePathsWatchedForServer {
12723    did_rename: Vec<RenameActionPredicate>,
12724    will_rename: Vec<RenameActionPredicate>,
12725}
12726
12727impl RenamePathsWatchedForServer {
12728    fn with_did_rename_patterns(
12729        mut self,
12730        did_rename: Option<&FileOperationRegistrationOptions>,
12731    ) -> Self {
12732        if let Some(did_rename) = did_rename {
12733            self.did_rename = did_rename
12734                .filters
12735                .iter()
12736                .filter_map(|filter| filter.try_into().log_err())
12737                .collect();
12738        }
12739        self
12740    }
12741    fn with_will_rename_patterns(
12742        mut self,
12743        will_rename: Option<&FileOperationRegistrationOptions>,
12744    ) -> Self {
12745        if let Some(will_rename) = will_rename {
12746            self.will_rename = will_rename
12747                .filters
12748                .iter()
12749                .filter_map(|filter| filter.try_into().log_err())
12750                .collect();
12751        }
12752        self
12753    }
12754
12755    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12756        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12757    }
12758    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12759        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12760    }
12761}
12762
12763impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12764    type Error = globset::Error;
12765    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12766        Ok(Self {
12767            kind: ops.pattern.matches.clone(),
12768            glob: GlobBuilder::new(&ops.pattern.glob)
12769                .case_insensitive(
12770                    ops.pattern
12771                        .options
12772                        .as_ref()
12773                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12774                )
12775                .build()?
12776                .compile_matcher(),
12777        })
12778    }
12779}
12780struct RenameActionPredicate {
12781    glob: GlobMatcher,
12782    kind: Option<FileOperationPatternKind>,
12783}
12784
12785impl RenameActionPredicate {
12786    // Returns true if language server should be notified
12787    fn eval(&self, path: &str, is_dir: bool) -> bool {
12788        self.kind.as_ref().is_none_or(|kind| {
12789            let expected_kind = if is_dir {
12790                FileOperationPatternKind::Folder
12791            } else {
12792                FileOperationPatternKind::File
12793            };
12794            kind == &expected_kind
12795        }) && self.glob.is_match(path)
12796    }
12797}
12798
12799#[derive(Default)]
12800struct LanguageServerWatchedPaths {
12801    worktree_paths: HashMap<WorktreeId, GlobSet>,
12802    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12803}
12804
12805#[derive(Default)]
12806struct LanguageServerWatchedPathsBuilder {
12807    worktree_paths: HashMap<WorktreeId, GlobSet>,
12808    abs_paths: HashMap<Arc<Path>, GlobSet>,
12809}
12810
12811impl LanguageServerWatchedPathsBuilder {
12812    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12813        self.worktree_paths.insert(worktree_id, glob_set);
12814    }
12815    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12816        self.abs_paths.insert(path, glob_set);
12817    }
12818    fn build(
12819        self,
12820        fs: Arc<dyn Fs>,
12821        language_server_id: LanguageServerId,
12822        cx: &mut Context<LspStore>,
12823    ) -> LanguageServerWatchedPaths {
12824        let project = cx.weak_entity();
12825
12826        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12827        let abs_paths = self
12828            .abs_paths
12829            .into_iter()
12830            .map(|(abs_path, globset)| {
12831                let task = cx.spawn({
12832                    let abs_path = abs_path.clone();
12833                    let fs = fs.clone();
12834
12835                    let lsp_store = project.clone();
12836                    async move |_, cx| {
12837                        maybe!(async move {
12838                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12839                            while let Some(update) = push_updates.0.next().await {
12840                                let action = lsp_store
12841                                    .update(cx, |this, _| {
12842                                        let Some(local) = this.as_local() else {
12843                                            return ControlFlow::Break(());
12844                                        };
12845                                        let Some(watcher) = local
12846                                            .language_server_watched_paths
12847                                            .get(&language_server_id)
12848                                        else {
12849                                            return ControlFlow::Break(());
12850                                        };
12851                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12852                                            "Watched abs path is not registered with a watcher",
12853                                        );
12854                                        let matching_entries = update
12855                                            .into_iter()
12856                                            .filter(|event| globs.is_match(&event.path))
12857                                            .collect::<Vec<_>>();
12858                                        this.lsp_notify_abs_paths_changed(
12859                                            language_server_id,
12860                                            matching_entries,
12861                                        );
12862                                        ControlFlow::Continue(())
12863                                    })
12864                                    .ok()?;
12865
12866                                if action.is_break() {
12867                                    break;
12868                                }
12869                            }
12870                            Some(())
12871                        })
12872                        .await;
12873                    }
12874                });
12875                (abs_path, (globset, task))
12876            })
12877            .collect();
12878        LanguageServerWatchedPaths {
12879            worktree_paths: self.worktree_paths,
12880            abs_paths,
12881        }
12882    }
12883}
12884
12885struct LspBufferSnapshot {
12886    version: i32,
12887    snapshot: TextBufferSnapshot,
12888}
12889
12890/// A prompt requested by LSP server.
12891#[derive(Clone, Debug)]
12892pub struct LanguageServerPromptRequest {
12893    pub level: PromptLevel,
12894    pub message: String,
12895    pub actions: Vec<MessageActionItem>,
12896    pub lsp_name: String,
12897    pub(crate) response_channel: Sender<MessageActionItem>,
12898}
12899
12900impl LanguageServerPromptRequest {
12901    pub async fn respond(self, index: usize) -> Option<()> {
12902        if let Some(response) = self.actions.into_iter().nth(index) {
12903            self.response_channel.send(response).await.ok()
12904        } else {
12905            None
12906        }
12907    }
12908}
12909impl PartialEq for LanguageServerPromptRequest {
12910    fn eq(&self, other: &Self) -> bool {
12911        self.message == other.message && self.actions == other.actions
12912    }
12913}
12914
12915#[derive(Clone, Debug, PartialEq)]
12916pub enum LanguageServerLogType {
12917    Log(MessageType),
12918    Trace { verbose_info: Option<String> },
12919    Rpc { received: bool },
12920}
12921
12922impl LanguageServerLogType {
12923    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12924        match self {
12925            Self::Log(log_type) => {
12926                use proto::log_message::LogLevel;
12927                let level = match *log_type {
12928                    MessageType::ERROR => LogLevel::Error,
12929                    MessageType::WARNING => LogLevel::Warning,
12930                    MessageType::INFO => LogLevel::Info,
12931                    MessageType::LOG => LogLevel::Log,
12932                    other => {
12933                        log::warn!("Unknown lsp log message type: {other:?}");
12934                        LogLevel::Log
12935                    }
12936                };
12937                proto::language_server_log::LogType::Log(proto::LogMessage {
12938                    level: level as i32,
12939                })
12940            }
12941            Self::Trace { verbose_info } => {
12942                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12943                    verbose_info: verbose_info.to_owned(),
12944                })
12945            }
12946            Self::Rpc { received } => {
12947                let kind = if *received {
12948                    proto::rpc_message::Kind::Received
12949                } else {
12950                    proto::rpc_message::Kind::Sent
12951                };
12952                let kind = kind as i32;
12953                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12954            }
12955        }
12956    }
12957
12958    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12959        use proto::log_message::LogLevel;
12960        use proto::rpc_message;
12961        match log_type {
12962            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12963                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12964                    LogLevel::Error => MessageType::ERROR,
12965                    LogLevel::Warning => MessageType::WARNING,
12966                    LogLevel::Info => MessageType::INFO,
12967                    LogLevel::Log => MessageType::LOG,
12968                },
12969            ),
12970            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12971                verbose_info: trace_message.verbose_info,
12972            },
12973            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12974                received: match rpc_message::Kind::from_i32(message.kind)
12975                    .unwrap_or(rpc_message::Kind::Received)
12976                {
12977                    rpc_message::Kind::Received => true,
12978                    rpc_message::Kind::Sent => false,
12979                },
12980            },
12981        }
12982    }
12983}
12984
12985pub struct WorkspaceRefreshTask {
12986    refresh_tx: mpsc::Sender<()>,
12987    progress_tx: mpsc::Sender<()>,
12988    #[allow(dead_code)]
12989    task: Task<()>,
12990}
12991
12992pub enum LanguageServerState {
12993    Starting {
12994        startup: Task<Option<Arc<LanguageServer>>>,
12995        /// List of language servers that will be added to the workspace once it's initialization completes.
12996        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
12997    },
12998
12999    Running {
13000        adapter: Arc<CachedLspAdapter>,
13001        server: Arc<LanguageServer>,
13002        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13003        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13004    },
13005}
13006
13007impl LanguageServerState {
13008    fn add_workspace_folder(&self, uri: Uri) {
13009        match self {
13010            LanguageServerState::Starting {
13011                pending_workspace_folders,
13012                ..
13013            } => {
13014                pending_workspace_folders.lock().insert(uri);
13015            }
13016            LanguageServerState::Running { server, .. } => {
13017                server.add_workspace_folder(uri);
13018            }
13019        }
13020    }
13021    fn _remove_workspace_folder(&self, uri: Uri) {
13022        match self {
13023            LanguageServerState::Starting {
13024                pending_workspace_folders,
13025                ..
13026            } => {
13027                pending_workspace_folders.lock().remove(&uri);
13028            }
13029            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13030        }
13031    }
13032}
13033
13034impl std::fmt::Debug for LanguageServerState {
13035    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13036        match self {
13037            LanguageServerState::Starting { .. } => {
13038                f.debug_struct("LanguageServerState::Starting").finish()
13039            }
13040            LanguageServerState::Running { .. } => {
13041                f.debug_struct("LanguageServerState::Running").finish()
13042            }
13043        }
13044    }
13045}
13046
13047#[derive(Clone, Debug, Serialize)]
13048pub struct LanguageServerProgress {
13049    pub is_disk_based_diagnostics_progress: bool,
13050    pub is_cancellable: bool,
13051    pub title: Option<String>,
13052    pub message: Option<String>,
13053    pub percentage: Option<usize>,
13054    #[serde(skip_serializing)]
13055    pub last_update_at: Instant,
13056}
13057
13058#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13059pub struct DiagnosticSummary {
13060    pub error_count: usize,
13061    pub warning_count: usize,
13062}
13063
13064impl DiagnosticSummary {
13065    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13066        let mut this = Self {
13067            error_count: 0,
13068            warning_count: 0,
13069        };
13070
13071        for entry in diagnostics {
13072            if entry.diagnostic.is_primary {
13073                match entry.diagnostic.severity {
13074                    DiagnosticSeverity::ERROR => this.error_count += 1,
13075                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13076                    _ => {}
13077                }
13078            }
13079        }
13080
13081        this
13082    }
13083
13084    pub fn is_empty(&self) -> bool {
13085        self.error_count == 0 && self.warning_count == 0
13086    }
13087
13088    pub fn to_proto(
13089        self,
13090        language_server_id: LanguageServerId,
13091        path: &RelPath,
13092    ) -> proto::DiagnosticSummary {
13093        proto::DiagnosticSummary {
13094            path: path.to_proto(),
13095            language_server_id: language_server_id.0 as u64,
13096            error_count: self.error_count as u32,
13097            warning_count: self.warning_count as u32,
13098        }
13099    }
13100}
13101
13102#[derive(Clone, Debug)]
13103pub enum CompletionDocumentation {
13104    /// There is no documentation for this completion.
13105    Undocumented,
13106    /// A single line of documentation.
13107    SingleLine(SharedString),
13108    /// Multiple lines of plain text documentation.
13109    MultiLinePlainText(SharedString),
13110    /// Markdown documentation.
13111    MultiLineMarkdown(SharedString),
13112    /// Both single line and multiple lines of plain text documentation.
13113    SingleLineAndMultiLinePlainText {
13114        single_line: SharedString,
13115        plain_text: Option<SharedString>,
13116    },
13117}
13118
13119impl CompletionDocumentation {
13120    #[cfg(any(test, feature = "test-support"))]
13121    pub fn text(&self) -> SharedString {
13122        match self {
13123            CompletionDocumentation::Undocumented => "".into(),
13124            CompletionDocumentation::SingleLine(s) => s.clone(),
13125            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13126            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13127            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13128                single_line.clone()
13129            }
13130        }
13131    }
13132}
13133
13134impl From<lsp::Documentation> for CompletionDocumentation {
13135    fn from(docs: lsp::Documentation) -> Self {
13136        match docs {
13137            lsp::Documentation::String(text) => {
13138                if text.lines().count() <= 1 {
13139                    CompletionDocumentation::SingleLine(text.into())
13140                } else {
13141                    CompletionDocumentation::MultiLinePlainText(text.into())
13142                }
13143            }
13144
13145            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13146                lsp::MarkupKind::PlainText => {
13147                    if value.lines().count() <= 1 {
13148                        CompletionDocumentation::SingleLine(value.into())
13149                    } else {
13150                        CompletionDocumentation::MultiLinePlainText(value.into())
13151                    }
13152                }
13153
13154                lsp::MarkupKind::Markdown => {
13155                    CompletionDocumentation::MultiLineMarkdown(value.into())
13156                }
13157            },
13158        }
13159    }
13160}
13161
13162pub enum ResolvedHint {
13163    Resolved(InlayHint),
13164    Resolving(Shared<Task<()>>),
13165}
13166
13167fn glob_literal_prefix(glob: &Path) -> PathBuf {
13168    glob.components()
13169        .take_while(|component| match component {
13170            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13171            _ => true,
13172        })
13173        .collect()
13174}
13175
13176pub struct SshLspAdapter {
13177    name: LanguageServerName,
13178    binary: LanguageServerBinary,
13179    initialization_options: Option<String>,
13180    code_action_kinds: Option<Vec<CodeActionKind>>,
13181}
13182
13183impl SshLspAdapter {
13184    pub fn new(
13185        name: LanguageServerName,
13186        binary: LanguageServerBinary,
13187        initialization_options: Option<String>,
13188        code_action_kinds: Option<String>,
13189    ) -> Self {
13190        Self {
13191            name,
13192            binary,
13193            initialization_options,
13194            code_action_kinds: code_action_kinds
13195                .as_ref()
13196                .and_then(|c| serde_json::from_str(c).ok()),
13197        }
13198    }
13199}
13200
13201impl LspInstaller for SshLspAdapter {
13202    type BinaryVersion = ();
13203    async fn check_if_user_installed(
13204        &self,
13205        _: &dyn LspAdapterDelegate,
13206        _: Option<Toolchain>,
13207        _: &AsyncApp,
13208    ) -> Option<LanguageServerBinary> {
13209        Some(self.binary.clone())
13210    }
13211
13212    async fn cached_server_binary(
13213        &self,
13214        _: PathBuf,
13215        _: &dyn LspAdapterDelegate,
13216    ) -> Option<LanguageServerBinary> {
13217        None
13218    }
13219
13220    async fn fetch_latest_server_version(
13221        &self,
13222        _: &dyn LspAdapterDelegate,
13223        _: bool,
13224        _: &mut AsyncApp,
13225    ) -> Result<()> {
13226        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13227    }
13228
13229    async fn fetch_server_binary(
13230        &self,
13231        _: (),
13232        _: PathBuf,
13233        _: &dyn LspAdapterDelegate,
13234    ) -> Result<LanguageServerBinary> {
13235        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13236    }
13237}
13238
13239#[async_trait(?Send)]
13240impl LspAdapter for SshLspAdapter {
13241    fn name(&self) -> LanguageServerName {
13242        self.name.clone()
13243    }
13244
13245    async fn initialization_options(
13246        self: Arc<Self>,
13247        _: &Arc<dyn LspAdapterDelegate>,
13248    ) -> Result<Option<serde_json::Value>> {
13249        let Some(options) = &self.initialization_options else {
13250            return Ok(None);
13251        };
13252        let result = serde_json::from_str(options)?;
13253        Ok(result)
13254    }
13255
13256    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13257        self.code_action_kinds.clone()
13258    }
13259}
13260
13261pub fn language_server_settings<'a>(
13262    delegate: &'a dyn LspAdapterDelegate,
13263    language: &LanguageServerName,
13264    cx: &'a App,
13265) -> Option<&'a LspSettings> {
13266    language_server_settings_for(
13267        SettingsLocation {
13268            worktree_id: delegate.worktree_id(),
13269            path: RelPath::empty(),
13270        },
13271        language,
13272        cx,
13273    )
13274}
13275
13276pub(crate) fn language_server_settings_for<'a>(
13277    location: SettingsLocation<'a>,
13278    language: &LanguageServerName,
13279    cx: &'a App,
13280) -> Option<&'a LspSettings> {
13281    ProjectSettings::get(Some(location), cx).lsp.get(language)
13282}
13283
13284pub struct LocalLspAdapterDelegate {
13285    lsp_store: WeakEntity<LspStore>,
13286    worktree: worktree::Snapshot,
13287    fs: Arc<dyn Fs>,
13288    http_client: Arc<dyn HttpClient>,
13289    language_registry: Arc<LanguageRegistry>,
13290    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13291}
13292
13293impl LocalLspAdapterDelegate {
13294    pub fn new(
13295        language_registry: Arc<LanguageRegistry>,
13296        environment: &Entity<ProjectEnvironment>,
13297        lsp_store: WeakEntity<LspStore>,
13298        worktree: &Entity<Worktree>,
13299        http_client: Arc<dyn HttpClient>,
13300        fs: Arc<dyn Fs>,
13301        cx: &mut App,
13302    ) -> Arc<Self> {
13303        let load_shell_env_task = environment.update(cx, |env, cx| {
13304            env.get_worktree_environment(worktree.clone(), cx)
13305        });
13306
13307        Arc::new(Self {
13308            lsp_store,
13309            worktree: worktree.read(cx).snapshot(),
13310            fs,
13311            http_client,
13312            language_registry,
13313            load_shell_env_task,
13314        })
13315    }
13316
13317    fn from_local_lsp(
13318        local: &LocalLspStore,
13319        worktree: &Entity<Worktree>,
13320        cx: &mut App,
13321    ) -> Arc<Self> {
13322        Self::new(
13323            local.languages.clone(),
13324            &local.environment,
13325            local.weak.clone(),
13326            worktree,
13327            local.http_client.clone(),
13328            local.fs.clone(),
13329            cx,
13330        )
13331    }
13332}
13333
13334#[async_trait]
13335impl LspAdapterDelegate for LocalLspAdapterDelegate {
13336    fn show_notification(&self, message: &str, cx: &mut App) {
13337        self.lsp_store
13338            .update(cx, |_, cx| {
13339                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13340            })
13341            .ok();
13342    }
13343
13344    fn http_client(&self) -> Arc<dyn HttpClient> {
13345        self.http_client.clone()
13346    }
13347
13348    fn worktree_id(&self) -> WorktreeId {
13349        self.worktree.id()
13350    }
13351
13352    fn worktree_root_path(&self) -> &Path {
13353        self.worktree.abs_path().as_ref()
13354    }
13355
13356    async fn shell_env(&self) -> HashMap<String, String> {
13357        let task = self.load_shell_env_task.clone();
13358        task.await.unwrap_or_default()
13359    }
13360
13361    async fn npm_package_installed_version(
13362        &self,
13363        package_name: &str,
13364    ) -> Result<Option<(PathBuf, String)>> {
13365        let local_package_directory = self.worktree_root_path();
13366        let node_modules_directory = local_package_directory.join("node_modules");
13367
13368        if let Some(version) =
13369            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13370        {
13371            return Ok(Some((node_modules_directory, version)));
13372        }
13373        let Some(npm) = self.which("npm".as_ref()).await else {
13374            log::warn!(
13375                "Failed to find npm executable for {:?}",
13376                local_package_directory
13377            );
13378            return Ok(None);
13379        };
13380
13381        let env = self.shell_env().await;
13382        let output = util::command::new_smol_command(&npm)
13383            .args(["root", "-g"])
13384            .envs(env)
13385            .current_dir(local_package_directory)
13386            .output()
13387            .await?;
13388        let global_node_modules =
13389            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13390
13391        if let Some(version) =
13392            read_package_installed_version(global_node_modules.clone(), package_name).await?
13393        {
13394            return Ok(Some((global_node_modules, version)));
13395        }
13396        return Ok(None);
13397    }
13398
13399    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13400        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13401        if self.fs.is_file(&worktree_abs_path).await {
13402            worktree_abs_path.pop();
13403        }
13404
13405        let env = self.shell_env().await;
13406
13407        let shell_path = env.get("PATH").cloned();
13408
13409        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13410    }
13411
13412    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13413        let mut working_dir = self.worktree_root_path().to_path_buf();
13414        if self.fs.is_file(&working_dir).await {
13415            working_dir.pop();
13416        }
13417        let output = util::command::new_smol_command(&command.path)
13418            .args(command.arguments)
13419            .envs(command.env.clone().unwrap_or_default())
13420            .current_dir(working_dir)
13421            .output()
13422            .await?;
13423
13424        anyhow::ensure!(
13425            output.status.success(),
13426            "{}, stdout: {:?}, stderr: {:?}",
13427            output.status,
13428            String::from_utf8_lossy(&output.stdout),
13429            String::from_utf8_lossy(&output.stderr)
13430        );
13431        Ok(())
13432    }
13433
13434    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13435        self.language_registry
13436            .update_lsp_binary_status(server_name, status);
13437    }
13438
13439    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13440        self.language_registry
13441            .all_lsp_adapters()
13442            .into_iter()
13443            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13444            .collect()
13445    }
13446
13447    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13448        let dir = self.language_registry.language_server_download_dir(name)?;
13449
13450        if !dir.exists() {
13451            smol::fs::create_dir_all(&dir)
13452                .await
13453                .context("failed to create container directory")
13454                .log_err()?;
13455        }
13456
13457        Some(dir)
13458    }
13459
13460    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13461        let entry = self
13462            .worktree
13463            .entry_for_path(path)
13464            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13465        let abs_path = self.worktree.absolutize(&entry.path);
13466        self.fs.load(&abs_path).await
13467    }
13468}
13469
13470async fn populate_labels_for_symbols(
13471    symbols: Vec<CoreSymbol>,
13472    language_registry: &Arc<LanguageRegistry>,
13473    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13474    output: &mut Vec<Symbol>,
13475) {
13476    #[allow(clippy::mutable_key_type)]
13477    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13478
13479    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13480    for symbol in symbols {
13481        let Some(file_name) = symbol.path.file_name() else {
13482            continue;
13483        };
13484        let language = language_registry
13485            .load_language_for_file_path(Path::new(file_name))
13486            .await
13487            .ok()
13488            .or_else(|| {
13489                unknown_paths.insert(file_name.into());
13490                None
13491            });
13492        symbols_by_language
13493            .entry(language)
13494            .or_default()
13495            .push(symbol);
13496    }
13497
13498    for unknown_path in unknown_paths {
13499        log::info!("no language found for symbol in file {unknown_path:?}");
13500    }
13501
13502    let mut label_params = Vec::new();
13503    for (language, mut symbols) in symbols_by_language {
13504        label_params.clear();
13505        label_params.extend(
13506            symbols
13507                .iter_mut()
13508                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13509        );
13510
13511        let mut labels = Vec::new();
13512        if let Some(language) = language {
13513            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13514                language_registry
13515                    .lsp_adapters(&language.name())
13516                    .first()
13517                    .cloned()
13518            });
13519            if let Some(lsp_adapter) = lsp_adapter {
13520                labels = lsp_adapter
13521                    .labels_for_symbols(&label_params, &language)
13522                    .await
13523                    .log_err()
13524                    .unwrap_or_default();
13525            }
13526        }
13527
13528        for ((symbol, (name, _)), label) in symbols
13529            .into_iter()
13530            .zip(label_params.drain(..))
13531            .zip(labels.into_iter().chain(iter::repeat(None)))
13532        {
13533            output.push(Symbol {
13534                language_server_name: symbol.language_server_name,
13535                source_worktree_id: symbol.source_worktree_id,
13536                source_language_server_id: symbol.source_language_server_id,
13537                path: symbol.path,
13538                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13539                name,
13540                kind: symbol.kind,
13541                range: symbol.range,
13542            });
13543        }
13544    }
13545}
13546
13547fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13548    match server.capabilities().text_document_sync.as_ref()? {
13549        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13550            // Server wants didSave but didn't specify includeText.
13551            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13552            // Server doesn't want didSave at all.
13553            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13554            // Server provided SaveOptions.
13555            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13556                Some(save_options.include_text.unwrap_or(false))
13557            }
13558        },
13559        // We do not have any save info. Kind affects didChange only.
13560        lsp::TextDocumentSyncCapability::Kind(_) => None,
13561    }
13562}
13563
13564/// Completion items are displayed in a `UniformList`.
13565/// Usually, those items are single-line strings, but in LSP responses,
13566/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13567/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13568/// 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,
13569/// breaking the completions menu presentation.
13570///
13571/// 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.
13572fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13573    let mut new_text = String::with_capacity(label.text.len());
13574    let mut offset_map = vec![0; label.text.len() + 1];
13575    let mut last_char_was_space = false;
13576    let mut new_idx = 0;
13577    let chars = label.text.char_indices().fuse();
13578    let mut newlines_removed = false;
13579
13580    for (idx, c) in chars {
13581        offset_map[idx] = new_idx;
13582
13583        match c {
13584            '\n' if last_char_was_space => {
13585                newlines_removed = true;
13586            }
13587            '\t' | ' ' if last_char_was_space => {}
13588            '\n' if !last_char_was_space => {
13589                new_text.push(' ');
13590                new_idx += 1;
13591                last_char_was_space = true;
13592                newlines_removed = true;
13593            }
13594            ' ' | '\t' => {
13595                new_text.push(' ');
13596                new_idx += 1;
13597                last_char_was_space = true;
13598            }
13599            _ => {
13600                new_text.push(c);
13601                new_idx += c.len_utf8();
13602                last_char_was_space = false;
13603            }
13604        }
13605    }
13606    offset_map[label.text.len()] = new_idx;
13607
13608    // Only modify the label if newlines were removed.
13609    if !newlines_removed {
13610        return;
13611    }
13612
13613    let last_index = new_idx;
13614    let mut run_ranges_errors = Vec::new();
13615    label.runs.retain_mut(|(range, _)| {
13616        match offset_map.get(range.start) {
13617            Some(&start) => range.start = start,
13618            None => {
13619                run_ranges_errors.push(range.clone());
13620                return false;
13621            }
13622        }
13623
13624        match offset_map.get(range.end) {
13625            Some(&end) => range.end = end,
13626            None => {
13627                run_ranges_errors.push(range.clone());
13628                range.end = last_index;
13629            }
13630        }
13631        true
13632    });
13633    if !run_ranges_errors.is_empty() {
13634        log::error!(
13635            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13636            label.text
13637        );
13638    }
13639
13640    let mut wrong_filter_range = None;
13641    if label.filter_range == (0..label.text.len()) {
13642        label.filter_range = 0..new_text.len();
13643    } else {
13644        let mut original_filter_range = Some(label.filter_range.clone());
13645        match offset_map.get(label.filter_range.start) {
13646            Some(&start) => label.filter_range.start = start,
13647            None => {
13648                wrong_filter_range = original_filter_range.take();
13649                label.filter_range.start = last_index;
13650            }
13651        }
13652
13653        match offset_map.get(label.filter_range.end) {
13654            Some(&end) => label.filter_range.end = end,
13655            None => {
13656                wrong_filter_range = original_filter_range.take();
13657                label.filter_range.end = last_index;
13658            }
13659        }
13660    }
13661    if let Some(wrong_filter_range) = wrong_filter_range {
13662        log::error!(
13663            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13664            label.text
13665        );
13666    }
13667
13668    label.text = new_text;
13669}
13670
13671#[cfg(test)]
13672mod tests {
13673    use language::HighlightId;
13674
13675    use super::*;
13676
13677    #[test]
13678    fn test_glob_literal_prefix() {
13679        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13680        assert_eq!(
13681            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13682            Path::new("node_modules")
13683        );
13684        assert_eq!(
13685            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13686            Path::new("foo")
13687        );
13688        assert_eq!(
13689            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13690            Path::new("foo/bar/baz.js")
13691        );
13692
13693        #[cfg(target_os = "windows")]
13694        {
13695            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13696            assert_eq!(
13697                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13698                Path::new("node_modules")
13699            );
13700            assert_eq!(
13701                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13702                Path::new("foo")
13703            );
13704            assert_eq!(
13705                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13706                Path::new("foo/bar/baz.js")
13707            );
13708        }
13709    }
13710
13711    #[test]
13712    fn test_multi_len_chars_normalization() {
13713        let mut label = CodeLabel::new(
13714            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13715            0..6,
13716            vec![(0..6, HighlightId(1))],
13717        );
13718        ensure_uniform_list_compatible_label(&mut label);
13719        assert_eq!(
13720            label,
13721            CodeLabel::new(
13722                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13723                0..6,
13724                vec![(0..6, HighlightId(1))],
13725            )
13726        );
13727    }
13728}