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_with_original_line_endings(),
 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_le()
 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                let line_ending = next_snapshot.line_ending();
 7578                buffer
 7579                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7580                        previous_snapshot.snapshot.version(),
 7581                    )
 7582                    .map(|edit| {
 7583                        let edit_start = edit.new.start.0;
 7584                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7585                        lsp::TextDocumentContentChangeEvent {
 7586                            range: Some(lsp::Range::new(
 7587                                point_to_lsp(edit_start),
 7588                                point_to_lsp(edit_end),
 7589                            )),
 7590                            range_length: None,
 7591                            // Collect changed text and preserve line endings.
 7592                            // text_for_range returns chunks with normalized \n, so we need to
 7593                            // convert to the buffer's actual line ending for LSP.
 7594                            text: line_ending.into_string(
 7595                                next_snapshot.text_for_range(edit.new.start.1..edit.new.end.1),
 7596                            ),
 7597                        }
 7598                    })
 7599                    .collect()
 7600            };
 7601
 7602            let document_sync_kind = language_server
 7603                .capabilities()
 7604                .text_document_sync
 7605                .as_ref()
 7606                .and_then(|sync| match sync {
 7607                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7608                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7609                });
 7610
 7611            let content_changes: Vec<_> = match document_sync_kind {
 7612                Some(lsp::TextDocumentSyncKind::FULL) => {
 7613                    vec![lsp::TextDocumentContentChangeEvent {
 7614                        range: None,
 7615                        range_length: None,
 7616                        text: next_snapshot.text_with_original_line_endings(),
 7617                    }]
 7618                }
 7619                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7620                _ => {
 7621                    #[cfg(any(test, feature = "test-support"))]
 7622                    {
 7623                        build_incremental_change()
 7624                    }
 7625
 7626                    #[cfg(not(any(test, feature = "test-support")))]
 7627                    {
 7628                        continue;
 7629                    }
 7630                }
 7631            };
 7632
 7633            let next_version = previous_snapshot.version + 1;
 7634            buffer_snapshots.push(LspBufferSnapshot {
 7635                version: next_version,
 7636                snapshot: next_snapshot.clone(),
 7637            });
 7638
 7639            language_server
 7640                .notify::<lsp::notification::DidChangeTextDocument>(
 7641                    lsp::DidChangeTextDocumentParams {
 7642                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7643                            uri.clone(),
 7644                            next_version,
 7645                        ),
 7646                        content_changes,
 7647                    },
 7648                )
 7649                .ok();
 7650            self.pull_workspace_diagnostics(language_server.server_id());
 7651        }
 7652
 7653        None
 7654    }
 7655
 7656    pub fn on_buffer_saved(
 7657        &mut self,
 7658        buffer: Entity<Buffer>,
 7659        cx: &mut Context<Self>,
 7660    ) -> Option<()> {
 7661        let file = File::from_dyn(buffer.read(cx).file())?;
 7662        let worktree_id = file.worktree_id(cx);
 7663        let abs_path = file.as_local()?.abs_path(cx);
 7664        let text_document = lsp::TextDocumentIdentifier {
 7665            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7666        };
 7667        let local = self.as_local()?;
 7668
 7669        for server in local.language_servers_for_worktree(worktree_id) {
 7670            if let Some(include_text) = include_text(server.as_ref()) {
 7671                let text = if include_text {
 7672                    Some(buffer.read(cx).text())
 7673                } else {
 7674                    None
 7675                };
 7676                server
 7677                    .notify::<lsp::notification::DidSaveTextDocument>(
 7678                        lsp::DidSaveTextDocumentParams {
 7679                            text_document: text_document.clone(),
 7680                            text,
 7681                        },
 7682                    )
 7683                    .ok();
 7684            }
 7685        }
 7686
 7687        let language_servers = buffer.update(cx, |buffer, cx| {
 7688            local.language_server_ids_for_buffer(buffer, cx)
 7689        });
 7690        for language_server_id in language_servers {
 7691            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7692        }
 7693
 7694        None
 7695    }
 7696
 7697    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7698        maybe!(async move {
 7699            let mut refreshed_servers = HashSet::default();
 7700            let servers = lsp_store
 7701                .update(cx, |lsp_store, cx| {
 7702                    let local = lsp_store.as_local()?;
 7703
 7704                    let servers = local
 7705                        .language_server_ids
 7706                        .iter()
 7707                        .filter_map(|(seed, state)| {
 7708                            let worktree = lsp_store
 7709                                .worktree_store
 7710                                .read(cx)
 7711                                .worktree_for_id(seed.worktree_id, cx);
 7712                            let delegate: Arc<dyn LspAdapterDelegate> =
 7713                                worktree.map(|worktree| {
 7714                                    LocalLspAdapterDelegate::new(
 7715                                        local.languages.clone(),
 7716                                        &local.environment,
 7717                                        cx.weak_entity(),
 7718                                        &worktree,
 7719                                        local.http_client.clone(),
 7720                                        local.fs.clone(),
 7721                                        cx,
 7722                                    )
 7723                                })?;
 7724                            let server_id = state.id;
 7725
 7726                            let states = local.language_servers.get(&server_id)?;
 7727
 7728                            match states {
 7729                                LanguageServerState::Starting { .. } => None,
 7730                                LanguageServerState::Running {
 7731                                    adapter, server, ..
 7732                                } => {
 7733                                    let adapter = adapter.clone();
 7734                                    let server = server.clone();
 7735                                    refreshed_servers.insert(server.name());
 7736                                    let toolchain = seed.toolchain.clone();
 7737                                    Some(cx.spawn(async move |_, cx| {
 7738                                        let settings =
 7739                                            LocalLspStore::workspace_configuration_for_adapter(
 7740                                                adapter.adapter.clone(),
 7741                                                &delegate,
 7742                                                toolchain,
 7743                                                cx,
 7744                                            )
 7745                                            .await
 7746                                            .ok()?;
 7747                                        server
 7748                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7749                                                lsp::DidChangeConfigurationParams { settings },
 7750                                            )
 7751                                            .ok()?;
 7752                                        Some(())
 7753                                    }))
 7754                                }
 7755                            }
 7756                        })
 7757                        .collect::<Vec<_>>();
 7758
 7759                    Some(servers)
 7760                })
 7761                .ok()
 7762                .flatten()?;
 7763
 7764            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7765            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7766            // to stop and unregister its language server wrapper.
 7767            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7768            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7769            let _: Vec<Option<()>> = join_all(servers).await;
 7770
 7771            Some(())
 7772        })
 7773        .await;
 7774    }
 7775
 7776    fn maintain_workspace_config(
 7777        external_refresh_requests: watch::Receiver<()>,
 7778        cx: &mut Context<Self>,
 7779    ) -> Task<Result<()>> {
 7780        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7781        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7782
 7783        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7784            *settings_changed_tx.borrow_mut() = ();
 7785        });
 7786
 7787        let mut joint_future =
 7788            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7789        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7790        // - 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).
 7791        // - 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.
 7792        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7793        // - 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,
 7794        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7795        cx.spawn(async move |this, cx| {
 7796            while let Some(()) = joint_future.next().await {
 7797                this.update(cx, |this, cx| {
 7798                    this.refresh_server_tree(cx);
 7799                })
 7800                .ok();
 7801
 7802                Self::refresh_workspace_configurations(&this, cx).await;
 7803            }
 7804
 7805            drop(settings_observation);
 7806            anyhow::Ok(())
 7807        })
 7808    }
 7809
 7810    pub fn language_servers_for_local_buffer<'a>(
 7811        &'a self,
 7812        buffer: &Buffer,
 7813        cx: &mut App,
 7814    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7815        let local = self.as_local();
 7816        let language_server_ids = local
 7817            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7818            .unwrap_or_default();
 7819
 7820        language_server_ids
 7821            .into_iter()
 7822            .filter_map(
 7823                move |server_id| match local?.language_servers.get(&server_id)? {
 7824                    LanguageServerState::Running {
 7825                        adapter, server, ..
 7826                    } => Some((adapter, server)),
 7827                    _ => None,
 7828                },
 7829            )
 7830    }
 7831
 7832    pub fn language_server_for_local_buffer<'a>(
 7833        &'a self,
 7834        buffer: &'a Buffer,
 7835        server_id: LanguageServerId,
 7836        cx: &'a mut App,
 7837    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7838        self.as_local()?
 7839            .language_servers_for_buffer(buffer, cx)
 7840            .find(|(_, s)| s.server_id() == server_id)
 7841    }
 7842
 7843    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7844        self.diagnostic_summaries.remove(&id_to_remove);
 7845        if let Some(local) = self.as_local_mut() {
 7846            let to_remove = local.remove_worktree(id_to_remove, cx);
 7847            for server in to_remove {
 7848                self.language_server_statuses.remove(&server);
 7849            }
 7850        }
 7851    }
 7852
 7853    pub fn shared(
 7854        &mut self,
 7855        project_id: u64,
 7856        downstream_client: AnyProtoClient,
 7857        _: &mut Context<Self>,
 7858    ) {
 7859        self.downstream_client = Some((downstream_client.clone(), project_id));
 7860
 7861        for (server_id, status) in &self.language_server_statuses {
 7862            if let Some(server) = self.language_server_for_id(*server_id) {
 7863                downstream_client
 7864                    .send(proto::StartLanguageServer {
 7865                        project_id,
 7866                        server: Some(proto::LanguageServer {
 7867                            id: server_id.to_proto(),
 7868                            name: status.name.to_string(),
 7869                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7870                        }),
 7871                        capabilities: serde_json::to_string(&server.capabilities())
 7872                            .expect("serializing server LSP capabilities"),
 7873                    })
 7874                    .log_err();
 7875            }
 7876        }
 7877    }
 7878
 7879    pub fn disconnected_from_host(&mut self) {
 7880        self.downstream_client.take();
 7881    }
 7882
 7883    pub fn disconnected_from_ssh_remote(&mut self) {
 7884        if let LspStoreMode::Remote(RemoteLspStore {
 7885            upstream_client, ..
 7886        }) = &mut self.mode
 7887        {
 7888            upstream_client.take();
 7889        }
 7890    }
 7891
 7892    pub(crate) fn set_language_server_statuses_from_proto(
 7893        &mut self,
 7894        project: WeakEntity<Project>,
 7895        language_servers: Vec<proto::LanguageServer>,
 7896        server_capabilities: Vec<String>,
 7897        cx: &mut Context<Self>,
 7898    ) {
 7899        let lsp_logs = cx
 7900            .try_global::<GlobalLogStore>()
 7901            .map(|lsp_store| lsp_store.0.clone());
 7902
 7903        self.language_server_statuses = language_servers
 7904            .into_iter()
 7905            .zip(server_capabilities)
 7906            .map(|(server, server_capabilities)| {
 7907                let server_id = LanguageServerId(server.id as usize);
 7908                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7909                    self.lsp_server_capabilities
 7910                        .insert(server_id, server_capabilities);
 7911                }
 7912
 7913                let name = LanguageServerName::from_proto(server.name);
 7914                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7915
 7916                if let Some(lsp_logs) = &lsp_logs {
 7917                    lsp_logs.update(cx, |lsp_logs, cx| {
 7918                        lsp_logs.add_language_server(
 7919                            // Only remote clients get their language servers set from proto
 7920                            LanguageServerKind::Remote {
 7921                                project: project.clone(),
 7922                            },
 7923                            server_id,
 7924                            Some(name.clone()),
 7925                            worktree,
 7926                            None,
 7927                            cx,
 7928                        );
 7929                    });
 7930                }
 7931
 7932                (
 7933                    server_id,
 7934                    LanguageServerStatus {
 7935                        name,
 7936                        pending_work: Default::default(),
 7937                        has_pending_diagnostic_updates: false,
 7938                        progress_tokens: Default::default(),
 7939                        worktree,
 7940                    },
 7941                )
 7942            })
 7943            .collect();
 7944    }
 7945
 7946    #[cfg(test)]
 7947    pub fn update_diagnostic_entries(
 7948        &mut self,
 7949        server_id: LanguageServerId,
 7950        abs_path: PathBuf,
 7951        result_id: Option<String>,
 7952        version: Option<i32>,
 7953        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7954        cx: &mut Context<Self>,
 7955    ) -> anyhow::Result<()> {
 7956        self.merge_diagnostic_entries(
 7957            vec![DocumentDiagnosticsUpdate {
 7958                diagnostics: DocumentDiagnostics {
 7959                    diagnostics,
 7960                    document_abs_path: abs_path,
 7961                    version,
 7962                },
 7963                result_id,
 7964                server_id,
 7965                disk_based_sources: Cow::Borrowed(&[]),
 7966            }],
 7967            |_, _, _| false,
 7968            cx,
 7969        )?;
 7970        Ok(())
 7971    }
 7972
 7973    pub fn merge_diagnostic_entries<'a>(
 7974        &mut self,
 7975        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7976        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7977        cx: &mut Context<Self>,
 7978    ) -> anyhow::Result<()> {
 7979        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7980        let mut updated_diagnostics_paths = HashMap::default();
 7981        for mut update in diagnostic_updates {
 7982            let abs_path = &update.diagnostics.document_abs_path;
 7983            let server_id = update.server_id;
 7984            let Some((worktree, relative_path)) =
 7985                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7986            else {
 7987                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7988                return Ok(());
 7989            };
 7990
 7991            let worktree_id = worktree.read(cx).id();
 7992            let project_path = ProjectPath {
 7993                worktree_id,
 7994                path: relative_path,
 7995            };
 7996
 7997            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7998                let snapshot = buffer_handle.read(cx).snapshot();
 7999                let buffer = buffer_handle.read(cx);
 8000                let reused_diagnostics = buffer
 8001                    .buffer_diagnostics(Some(server_id))
 8002                    .iter()
 8003                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8004                    .map(|v| {
 8005                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8006                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8007                        DiagnosticEntry {
 8008                            range: start..end,
 8009                            diagnostic: v.diagnostic.clone(),
 8010                        }
 8011                    })
 8012                    .collect::<Vec<_>>();
 8013
 8014                self.as_local_mut()
 8015                    .context("cannot merge diagnostics on a remote LspStore")?
 8016                    .update_buffer_diagnostics(
 8017                        &buffer_handle,
 8018                        server_id,
 8019                        update.result_id,
 8020                        update.diagnostics.version,
 8021                        update.diagnostics.diagnostics.clone(),
 8022                        reused_diagnostics.clone(),
 8023                        cx,
 8024                    )?;
 8025
 8026                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8027            }
 8028
 8029            let updated = worktree.update(cx, |worktree, cx| {
 8030                self.update_worktree_diagnostics(
 8031                    worktree.id(),
 8032                    server_id,
 8033                    project_path.path.clone(),
 8034                    update.diagnostics.diagnostics,
 8035                    cx,
 8036                )
 8037            })?;
 8038            match updated {
 8039                ControlFlow::Continue(new_summary) => {
 8040                    if let Some((project_id, new_summary)) = new_summary {
 8041                        match &mut diagnostics_summary {
 8042                            Some(diagnostics_summary) => {
 8043                                diagnostics_summary
 8044                                    .more_summaries
 8045                                    .push(proto::DiagnosticSummary {
 8046                                        path: project_path.path.as_ref().to_proto(),
 8047                                        language_server_id: server_id.0 as u64,
 8048                                        error_count: new_summary.error_count,
 8049                                        warning_count: new_summary.warning_count,
 8050                                    })
 8051                            }
 8052                            None => {
 8053                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8054                                    project_id,
 8055                                    worktree_id: worktree_id.to_proto(),
 8056                                    summary: Some(proto::DiagnosticSummary {
 8057                                        path: project_path.path.as_ref().to_proto(),
 8058                                        language_server_id: server_id.0 as u64,
 8059                                        error_count: new_summary.error_count,
 8060                                        warning_count: new_summary.warning_count,
 8061                                    }),
 8062                                    more_summaries: Vec::new(),
 8063                                })
 8064                            }
 8065                        }
 8066                    }
 8067                    updated_diagnostics_paths
 8068                        .entry(server_id)
 8069                        .or_insert_with(Vec::new)
 8070                        .push(project_path);
 8071                }
 8072                ControlFlow::Break(()) => {}
 8073            }
 8074        }
 8075
 8076        if let Some((diagnostics_summary, (downstream_client, _))) =
 8077            diagnostics_summary.zip(self.downstream_client.as_ref())
 8078        {
 8079            downstream_client.send(diagnostics_summary).log_err();
 8080        }
 8081        for (server_id, paths) in updated_diagnostics_paths {
 8082            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8083        }
 8084        Ok(())
 8085    }
 8086
 8087    fn update_worktree_diagnostics(
 8088        &mut self,
 8089        worktree_id: WorktreeId,
 8090        server_id: LanguageServerId,
 8091        path_in_worktree: Arc<RelPath>,
 8092        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8093        _: &mut Context<Worktree>,
 8094    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8095        let local = match &mut self.mode {
 8096            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8097            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8098        };
 8099
 8100        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8101        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8102        let summaries_by_server_id = summaries_for_tree
 8103            .entry(path_in_worktree.clone())
 8104            .or_default();
 8105
 8106        let old_summary = summaries_by_server_id
 8107            .remove(&server_id)
 8108            .unwrap_or_default();
 8109
 8110        let new_summary = DiagnosticSummary::new(&diagnostics);
 8111        if new_summary.is_empty() {
 8112            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8113            {
 8114                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8115                    diagnostics_by_server_id.remove(ix);
 8116                }
 8117                if diagnostics_by_server_id.is_empty() {
 8118                    diagnostics_for_tree.remove(&path_in_worktree);
 8119                }
 8120            }
 8121        } else {
 8122            summaries_by_server_id.insert(server_id, new_summary);
 8123            let diagnostics_by_server_id = diagnostics_for_tree
 8124                .entry(path_in_worktree.clone())
 8125                .or_default();
 8126            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8127                Ok(ix) => {
 8128                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8129                }
 8130                Err(ix) => {
 8131                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8132                }
 8133            }
 8134        }
 8135
 8136        if !old_summary.is_empty() || !new_summary.is_empty() {
 8137            if let Some((_, project_id)) = &self.downstream_client {
 8138                Ok(ControlFlow::Continue(Some((
 8139                    *project_id,
 8140                    proto::DiagnosticSummary {
 8141                        path: path_in_worktree.to_proto(),
 8142                        language_server_id: server_id.0 as u64,
 8143                        error_count: new_summary.error_count as u32,
 8144                        warning_count: new_summary.warning_count as u32,
 8145                    },
 8146                ))))
 8147            } else {
 8148                Ok(ControlFlow::Continue(None))
 8149            }
 8150        } else {
 8151            Ok(ControlFlow::Break(()))
 8152        }
 8153    }
 8154
 8155    pub fn open_buffer_for_symbol(
 8156        &mut self,
 8157        symbol: &Symbol,
 8158        cx: &mut Context<Self>,
 8159    ) -> Task<Result<Entity<Buffer>>> {
 8160        if let Some((client, project_id)) = self.upstream_client() {
 8161            let request = client.request(proto::OpenBufferForSymbol {
 8162                project_id,
 8163                symbol: Some(Self::serialize_symbol(symbol)),
 8164            });
 8165            cx.spawn(async move |this, cx| {
 8166                let response = request.await?;
 8167                let buffer_id = BufferId::new(response.buffer_id)?;
 8168                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8169                    .await
 8170            })
 8171        } else if let Some(local) = self.as_local() {
 8172            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8173                seed.worktree_id == symbol.source_worktree_id
 8174                    && state.id == symbol.source_language_server_id
 8175                    && symbol.language_server_name == seed.name
 8176            });
 8177            if !is_valid {
 8178                return Task::ready(Err(anyhow!(
 8179                    "language server for worktree and language not found"
 8180                )));
 8181            };
 8182
 8183            let symbol_abs_path = match &symbol.path {
 8184                SymbolLocation::InProject(project_path) => self
 8185                    .worktree_store
 8186                    .read(cx)
 8187                    .absolutize(&project_path, cx)
 8188                    .context("no such worktree"),
 8189                SymbolLocation::OutsideProject {
 8190                    abs_path,
 8191                    signature: _,
 8192                } => Ok(abs_path.to_path_buf()),
 8193            };
 8194            let symbol_abs_path = match symbol_abs_path {
 8195                Ok(abs_path) => abs_path,
 8196                Err(err) => return Task::ready(Err(err)),
 8197            };
 8198            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8199                uri
 8200            } else {
 8201                return Task::ready(Err(anyhow!("invalid symbol path")));
 8202            };
 8203
 8204            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8205        } else {
 8206            Task::ready(Err(anyhow!("no upstream client or local store")))
 8207        }
 8208    }
 8209
 8210    pub(crate) fn open_local_buffer_via_lsp(
 8211        &mut self,
 8212        abs_path: lsp::Uri,
 8213        language_server_id: LanguageServerId,
 8214        cx: &mut Context<Self>,
 8215    ) -> Task<Result<Entity<Buffer>>> {
 8216        cx.spawn(async move |lsp_store, cx| {
 8217            // Escape percent-encoded string.
 8218            let current_scheme = abs_path.scheme().to_owned();
 8219            // Uri is immutable, so we can't modify the scheme
 8220
 8221            let abs_path = abs_path
 8222                .to_file_path()
 8223                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8224            let p = abs_path.clone();
 8225            let yarn_worktree = lsp_store
 8226                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8227                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8228                        cx.spawn(async move |this, cx| {
 8229                            let t = this
 8230                                .update(cx, |this, cx| this.process_path(&p, ¤t_scheme, cx))
 8231                                .ok()?;
 8232                            t.await
 8233                        })
 8234                    }),
 8235                    None => Task::ready(None),
 8236                })?
 8237                .await;
 8238            let (worktree_root_target, known_relative_path) =
 8239                if let Some((zip_root, relative_path)) = yarn_worktree {
 8240                    (zip_root, Some(relative_path))
 8241                } else {
 8242                    (Arc::<Path>::from(abs_path.as_path()), None)
 8243                };
 8244            let (worktree, relative_path) = if let Some(result) =
 8245                lsp_store.update(cx, |lsp_store, cx| {
 8246                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8247                        worktree_store.find_worktree(&worktree_root_target, cx)
 8248                    })
 8249                })? {
 8250                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8251                (result.0, relative_path)
 8252            } else {
 8253                let worktree = lsp_store
 8254                    .update(cx, |lsp_store, cx| {
 8255                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8256                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8257                        })
 8258                    })?
 8259                    .await?;
 8260                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8261                    lsp_store
 8262                        .update(cx, |lsp_store, cx| {
 8263                            if let Some(local) = lsp_store.as_local_mut() {
 8264                                local.register_language_server_for_invisible_worktree(
 8265                                    &worktree,
 8266                                    language_server_id,
 8267                                    cx,
 8268                                )
 8269                            }
 8270                        })
 8271                        .ok();
 8272                }
 8273                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8274                let relative_path = if let Some(known_path) = known_relative_path {
 8275                    known_path
 8276                } else {
 8277                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8278                        .into_arc()
 8279                };
 8280                (worktree, relative_path)
 8281            };
 8282            let project_path = ProjectPath {
 8283                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8284                path: relative_path,
 8285            };
 8286            lsp_store
 8287                .update(cx, |lsp_store, cx| {
 8288                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8289                        buffer_store.open_buffer(project_path, cx)
 8290                    })
 8291                })?
 8292                .await
 8293        })
 8294    }
 8295
 8296    fn request_multiple_lsp_locally<P, R>(
 8297        &mut self,
 8298        buffer: &Entity<Buffer>,
 8299        position: Option<P>,
 8300        request: R,
 8301        cx: &mut Context<Self>,
 8302    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8303    where
 8304        P: ToOffset,
 8305        R: LspCommand + Clone,
 8306        <R::LspRequest as lsp::request::Request>::Result: Send,
 8307        <R::LspRequest as lsp::request::Request>::Params: Send,
 8308    {
 8309        let Some(local) = self.as_local() else {
 8310            return Task::ready(Vec::new());
 8311        };
 8312
 8313        let snapshot = buffer.read(cx).snapshot();
 8314        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8315
 8316        let server_ids = buffer.update(cx, |buffer, cx| {
 8317            local
 8318                .language_servers_for_buffer(buffer, cx)
 8319                .filter(|(adapter, _)| {
 8320                    scope
 8321                        .as_ref()
 8322                        .map(|scope| scope.language_allowed(&adapter.name))
 8323                        .unwrap_or(true)
 8324                })
 8325                .map(|(_, server)| server.server_id())
 8326                .filter(|server_id| {
 8327                    self.as_local().is_none_or(|local| {
 8328                        local
 8329                            .buffers_opened_in_servers
 8330                            .get(&snapshot.remote_id())
 8331                            .is_some_and(|servers| servers.contains(server_id))
 8332                    })
 8333                })
 8334                .collect::<Vec<_>>()
 8335        });
 8336
 8337        let mut response_results = server_ids
 8338            .into_iter()
 8339            .map(|server_id| {
 8340                let task = self.request_lsp(
 8341                    buffer.clone(),
 8342                    LanguageServerToQuery::Other(server_id),
 8343                    request.clone(),
 8344                    cx,
 8345                );
 8346                async move { (server_id, task.await) }
 8347            })
 8348            .collect::<FuturesUnordered<_>>();
 8349
 8350        cx.background_spawn(async move {
 8351            let mut responses = Vec::with_capacity(response_results.len());
 8352            while let Some((server_id, response_result)) = response_results.next().await {
 8353                match response_result {
 8354                    Ok(response) => responses.push((server_id, response)),
 8355                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8356                }
 8357            }
 8358            responses
 8359        })
 8360    }
 8361
 8362    async fn handle_lsp_command<T: LspCommand>(
 8363        this: Entity<Self>,
 8364        envelope: TypedEnvelope<T::ProtoRequest>,
 8365        mut cx: AsyncApp,
 8366    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8367    where
 8368        <T::LspRequest as lsp::request::Request>::Params: Send,
 8369        <T::LspRequest as lsp::request::Request>::Result: Send,
 8370    {
 8371        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8372        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8373        let buffer_handle = this.update(&mut cx, |this, cx| {
 8374            this.buffer_store.read(cx).get_existing(buffer_id)
 8375        })??;
 8376        let request = T::from_proto(
 8377            envelope.payload,
 8378            this.clone(),
 8379            buffer_handle.clone(),
 8380            cx.clone(),
 8381        )
 8382        .await?;
 8383        let response = this
 8384            .update(&mut cx, |this, cx| {
 8385                this.request_lsp(
 8386                    buffer_handle.clone(),
 8387                    LanguageServerToQuery::FirstCapable,
 8388                    request,
 8389                    cx,
 8390                )
 8391            })?
 8392            .await?;
 8393        this.update(&mut cx, |this, cx| {
 8394            Ok(T::response_to_proto(
 8395                response,
 8396                this,
 8397                sender_id,
 8398                &buffer_handle.read(cx).version(),
 8399                cx,
 8400            ))
 8401        })?
 8402    }
 8403
 8404    async fn handle_lsp_query(
 8405        lsp_store: Entity<Self>,
 8406        envelope: TypedEnvelope<proto::LspQuery>,
 8407        mut cx: AsyncApp,
 8408    ) -> Result<proto::Ack> {
 8409        use proto::lsp_query::Request;
 8410        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8411        let lsp_query = envelope.payload;
 8412        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8413        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8414        match lsp_query.request.context("invalid LSP query request")? {
 8415            Request::GetReferences(get_references) => {
 8416                let position = get_references.position.clone().and_then(deserialize_anchor);
 8417                Self::query_lsp_locally::<GetReferences>(
 8418                    lsp_store,
 8419                    server_id,
 8420                    sender_id,
 8421                    lsp_request_id,
 8422                    get_references,
 8423                    position,
 8424                    &mut cx,
 8425                )
 8426                .await?;
 8427            }
 8428            Request::GetDocumentColor(get_document_color) => {
 8429                Self::query_lsp_locally::<GetDocumentColor>(
 8430                    lsp_store,
 8431                    server_id,
 8432                    sender_id,
 8433                    lsp_request_id,
 8434                    get_document_color,
 8435                    None,
 8436                    &mut cx,
 8437                )
 8438                .await?;
 8439            }
 8440            Request::GetHover(get_hover) => {
 8441                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8442                Self::query_lsp_locally::<GetHover>(
 8443                    lsp_store,
 8444                    server_id,
 8445                    sender_id,
 8446                    lsp_request_id,
 8447                    get_hover,
 8448                    position,
 8449                    &mut cx,
 8450                )
 8451                .await?;
 8452            }
 8453            Request::GetCodeActions(get_code_actions) => {
 8454                Self::query_lsp_locally::<GetCodeActions>(
 8455                    lsp_store,
 8456                    server_id,
 8457                    sender_id,
 8458                    lsp_request_id,
 8459                    get_code_actions,
 8460                    None,
 8461                    &mut cx,
 8462                )
 8463                .await?;
 8464            }
 8465            Request::GetSignatureHelp(get_signature_help) => {
 8466                let position = get_signature_help
 8467                    .position
 8468                    .clone()
 8469                    .and_then(deserialize_anchor);
 8470                Self::query_lsp_locally::<GetSignatureHelp>(
 8471                    lsp_store,
 8472                    server_id,
 8473                    sender_id,
 8474                    lsp_request_id,
 8475                    get_signature_help,
 8476                    position,
 8477                    &mut cx,
 8478                )
 8479                .await?;
 8480            }
 8481            Request::GetCodeLens(get_code_lens) => {
 8482                Self::query_lsp_locally::<GetCodeLens>(
 8483                    lsp_store,
 8484                    server_id,
 8485                    sender_id,
 8486                    lsp_request_id,
 8487                    get_code_lens,
 8488                    None,
 8489                    &mut cx,
 8490                )
 8491                .await?;
 8492            }
 8493            Request::GetDefinition(get_definition) => {
 8494                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8495                Self::query_lsp_locally::<GetDefinitions>(
 8496                    lsp_store,
 8497                    server_id,
 8498                    sender_id,
 8499                    lsp_request_id,
 8500                    get_definition,
 8501                    position,
 8502                    &mut cx,
 8503                )
 8504                .await?;
 8505            }
 8506            Request::GetDeclaration(get_declaration) => {
 8507                let position = get_declaration
 8508                    .position
 8509                    .clone()
 8510                    .and_then(deserialize_anchor);
 8511                Self::query_lsp_locally::<GetDeclarations>(
 8512                    lsp_store,
 8513                    server_id,
 8514                    sender_id,
 8515                    lsp_request_id,
 8516                    get_declaration,
 8517                    position,
 8518                    &mut cx,
 8519                )
 8520                .await?;
 8521            }
 8522            Request::GetTypeDefinition(get_type_definition) => {
 8523                let position = get_type_definition
 8524                    .position
 8525                    .clone()
 8526                    .and_then(deserialize_anchor);
 8527                Self::query_lsp_locally::<GetTypeDefinitions>(
 8528                    lsp_store,
 8529                    server_id,
 8530                    sender_id,
 8531                    lsp_request_id,
 8532                    get_type_definition,
 8533                    position,
 8534                    &mut cx,
 8535                )
 8536                .await?;
 8537            }
 8538            Request::GetImplementation(get_implementation) => {
 8539                let position = get_implementation
 8540                    .position
 8541                    .clone()
 8542                    .and_then(deserialize_anchor);
 8543                Self::query_lsp_locally::<GetImplementations>(
 8544                    lsp_store,
 8545                    server_id,
 8546                    sender_id,
 8547                    lsp_request_id,
 8548                    get_implementation,
 8549                    position,
 8550                    &mut cx,
 8551                )
 8552                .await?;
 8553            }
 8554            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8555                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8556                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8557                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8558                    this.buffer_store.read(cx).get_existing(buffer_id)
 8559                })??;
 8560                buffer
 8561                    .update(&mut cx, |buffer, _| {
 8562                        buffer.wait_for_version(version.clone())
 8563                    })?
 8564                    .await?;
 8565                lsp_store.update(&mut cx, |lsp_store, cx| {
 8566                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8567                    let key = LspKey {
 8568                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8569                        server_queried: server_id,
 8570                    };
 8571                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8572                    ) {
 8573                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8574                            lsp_requests.clear();
 8575                        };
 8576                    }
 8577
 8578                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8579                    existing_queries.insert(
 8580                        lsp_request_id,
 8581                        cx.spawn(async move |lsp_store, cx| {
 8582                            let diagnostics_pull = lsp_store
 8583                                .update(cx, |lsp_store, cx| {
 8584                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8585                                })
 8586                                .ok();
 8587                            if let Some(diagnostics_pull) = diagnostics_pull {
 8588                                match diagnostics_pull.await {
 8589                                    Ok(()) => {}
 8590                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8591                                };
 8592                            }
 8593                        }),
 8594                    );
 8595                })?;
 8596            }
 8597            Request::InlayHints(inlay_hints) => {
 8598                let query_start = inlay_hints
 8599                    .start
 8600                    .clone()
 8601                    .and_then(deserialize_anchor)
 8602                    .context("invalid inlay hints range start")?;
 8603                let query_end = inlay_hints
 8604                    .end
 8605                    .clone()
 8606                    .and_then(deserialize_anchor)
 8607                    .context("invalid inlay hints range end")?;
 8608                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8609                    &lsp_store,
 8610                    server_id,
 8611                    lsp_request_id,
 8612                    &inlay_hints,
 8613                    query_start..query_end,
 8614                    &mut cx,
 8615                )
 8616                .await
 8617                .context("preparing inlay hints request")?;
 8618                Self::query_lsp_locally::<InlayHints>(
 8619                    lsp_store,
 8620                    server_id,
 8621                    sender_id,
 8622                    lsp_request_id,
 8623                    inlay_hints,
 8624                    None,
 8625                    &mut cx,
 8626                )
 8627                .await
 8628                .context("querying for inlay hints")?
 8629            }
 8630        }
 8631        Ok(proto::Ack {})
 8632    }
 8633
 8634    async fn handle_lsp_query_response(
 8635        lsp_store: Entity<Self>,
 8636        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8637        cx: AsyncApp,
 8638    ) -> Result<()> {
 8639        lsp_store.read_with(&cx, |lsp_store, _| {
 8640            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8641                upstream_client.handle_lsp_response(envelope.clone());
 8642            }
 8643        })?;
 8644        Ok(())
 8645    }
 8646
 8647    async fn handle_apply_code_action(
 8648        this: Entity<Self>,
 8649        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8650        mut cx: AsyncApp,
 8651    ) -> Result<proto::ApplyCodeActionResponse> {
 8652        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8653        let action =
 8654            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8655        let apply_code_action = this.update(&mut cx, |this, cx| {
 8656            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8657            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8658            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8659        })??;
 8660
 8661        let project_transaction = apply_code_action.await?;
 8662        let project_transaction = this.update(&mut cx, |this, cx| {
 8663            this.buffer_store.update(cx, |buffer_store, cx| {
 8664                buffer_store.serialize_project_transaction_for_peer(
 8665                    project_transaction,
 8666                    sender_id,
 8667                    cx,
 8668                )
 8669            })
 8670        })?;
 8671        Ok(proto::ApplyCodeActionResponse {
 8672            transaction: Some(project_transaction),
 8673        })
 8674    }
 8675
 8676    async fn handle_register_buffer_with_language_servers(
 8677        this: Entity<Self>,
 8678        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8679        mut cx: AsyncApp,
 8680    ) -> Result<proto::Ack> {
 8681        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8682        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8683        this.update(&mut cx, |this, cx| {
 8684            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8685                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8686                    project_id: upstream_project_id,
 8687                    buffer_id: buffer_id.to_proto(),
 8688                    only_servers: envelope.payload.only_servers,
 8689                });
 8690            }
 8691
 8692            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8693                anyhow::bail!("buffer is not open");
 8694            };
 8695
 8696            let handle = this.register_buffer_with_language_servers(
 8697                &buffer,
 8698                envelope
 8699                    .payload
 8700                    .only_servers
 8701                    .into_iter()
 8702                    .filter_map(|selector| {
 8703                        Some(match selector.selector? {
 8704                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8705                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8706                            }
 8707                            proto::language_server_selector::Selector::Name(name) => {
 8708                                LanguageServerSelector::Name(LanguageServerName(
 8709                                    SharedString::from(name),
 8710                                ))
 8711                            }
 8712                        })
 8713                    })
 8714                    .collect(),
 8715                false,
 8716                cx,
 8717            );
 8718            this.buffer_store().update(cx, |buffer_store, _| {
 8719                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8720            });
 8721
 8722            Ok(())
 8723        })??;
 8724        Ok(proto::Ack {})
 8725    }
 8726
 8727    async fn handle_rename_project_entry(
 8728        this: Entity<Self>,
 8729        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8730        mut cx: AsyncApp,
 8731    ) -> Result<proto::ProjectEntryResponse> {
 8732        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8733        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8734        let new_path =
 8735            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8736
 8737        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8738            .update(&mut cx, |this, cx| {
 8739                let (worktree, entry) = this
 8740                    .worktree_store
 8741                    .read(cx)
 8742                    .worktree_and_entry_for_id(entry_id, cx)?;
 8743                let new_worktree = this
 8744                    .worktree_store
 8745                    .read(cx)
 8746                    .worktree_for_id(new_worktree_id, cx)?;
 8747                Some((
 8748                    this.worktree_store.clone(),
 8749                    worktree,
 8750                    new_worktree,
 8751                    entry.clone(),
 8752                ))
 8753            })?
 8754            .context("worktree not found")?;
 8755        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8756            (worktree.absolutize(&old_entry.path), worktree.id())
 8757        })?;
 8758        let new_abs_path =
 8759            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8760
 8761        let _transaction = Self::will_rename_entry(
 8762            this.downgrade(),
 8763            old_worktree_id,
 8764            &old_abs_path,
 8765            &new_abs_path,
 8766            old_entry.is_dir(),
 8767            cx.clone(),
 8768        )
 8769        .await;
 8770        let response = WorktreeStore::handle_rename_project_entry(
 8771            worktree_store,
 8772            envelope.payload,
 8773            cx.clone(),
 8774        )
 8775        .await;
 8776        this.read_with(&cx, |this, _| {
 8777            this.did_rename_entry(
 8778                old_worktree_id,
 8779                &old_abs_path,
 8780                &new_abs_path,
 8781                old_entry.is_dir(),
 8782            );
 8783        })
 8784        .ok();
 8785        response
 8786    }
 8787
 8788    async fn handle_update_diagnostic_summary(
 8789        this: Entity<Self>,
 8790        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8791        mut cx: AsyncApp,
 8792    ) -> Result<()> {
 8793        this.update(&mut cx, |lsp_store, cx| {
 8794            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8795            let mut updated_diagnostics_paths = HashMap::default();
 8796            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8797            for message_summary in envelope
 8798                .payload
 8799                .summary
 8800                .into_iter()
 8801                .chain(envelope.payload.more_summaries)
 8802            {
 8803                let project_path = ProjectPath {
 8804                    worktree_id,
 8805                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8806                };
 8807                let path = project_path.path.clone();
 8808                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8809                let summary = DiagnosticSummary {
 8810                    error_count: message_summary.error_count as usize,
 8811                    warning_count: message_summary.warning_count as usize,
 8812                };
 8813
 8814                if summary.is_empty() {
 8815                    if let Some(worktree_summaries) =
 8816                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8817                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8818                    {
 8819                        summaries.remove(&server_id);
 8820                        if summaries.is_empty() {
 8821                            worktree_summaries.remove(&path);
 8822                        }
 8823                    }
 8824                } else {
 8825                    lsp_store
 8826                        .diagnostic_summaries
 8827                        .entry(worktree_id)
 8828                        .or_default()
 8829                        .entry(path)
 8830                        .or_default()
 8831                        .insert(server_id, summary);
 8832                }
 8833
 8834                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8835                    match &mut diagnostics_summary {
 8836                        Some(diagnostics_summary) => {
 8837                            diagnostics_summary
 8838                                .more_summaries
 8839                                .push(proto::DiagnosticSummary {
 8840                                    path: project_path.path.as_ref().to_proto(),
 8841                                    language_server_id: server_id.0 as u64,
 8842                                    error_count: summary.error_count as u32,
 8843                                    warning_count: summary.warning_count as u32,
 8844                                })
 8845                        }
 8846                        None => {
 8847                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8848                                project_id: *project_id,
 8849                                worktree_id: worktree_id.to_proto(),
 8850                                summary: Some(proto::DiagnosticSummary {
 8851                                    path: project_path.path.as_ref().to_proto(),
 8852                                    language_server_id: server_id.0 as u64,
 8853                                    error_count: summary.error_count as u32,
 8854                                    warning_count: summary.warning_count as u32,
 8855                                }),
 8856                                more_summaries: Vec::new(),
 8857                            })
 8858                        }
 8859                    }
 8860                }
 8861                updated_diagnostics_paths
 8862                    .entry(server_id)
 8863                    .or_insert_with(Vec::new)
 8864                    .push(project_path);
 8865            }
 8866
 8867            if let Some((diagnostics_summary, (downstream_client, _))) =
 8868                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8869            {
 8870                downstream_client.send(diagnostics_summary).log_err();
 8871            }
 8872            for (server_id, paths) in updated_diagnostics_paths {
 8873                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8874            }
 8875            Ok(())
 8876        })?
 8877    }
 8878
 8879    async fn handle_start_language_server(
 8880        lsp_store: Entity<Self>,
 8881        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8882        mut cx: AsyncApp,
 8883    ) -> Result<()> {
 8884        let server = envelope.payload.server.context("invalid server")?;
 8885        let server_capabilities =
 8886            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8887                .with_context(|| {
 8888                    format!(
 8889                        "incorrect server capabilities {}",
 8890                        envelope.payload.capabilities
 8891                    )
 8892                })?;
 8893        lsp_store.update(&mut cx, |lsp_store, cx| {
 8894            let server_id = LanguageServerId(server.id as usize);
 8895            let server_name = LanguageServerName::from_proto(server.name.clone());
 8896            lsp_store
 8897                .lsp_server_capabilities
 8898                .insert(server_id, server_capabilities);
 8899            lsp_store.language_server_statuses.insert(
 8900                server_id,
 8901                LanguageServerStatus {
 8902                    name: server_name.clone(),
 8903                    pending_work: Default::default(),
 8904                    has_pending_diagnostic_updates: false,
 8905                    progress_tokens: Default::default(),
 8906                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8907                },
 8908            );
 8909            cx.emit(LspStoreEvent::LanguageServerAdded(
 8910                server_id,
 8911                server_name,
 8912                server.worktree_id.map(WorktreeId::from_proto),
 8913            ));
 8914            cx.notify();
 8915        })?;
 8916        Ok(())
 8917    }
 8918
 8919    async fn handle_update_language_server(
 8920        lsp_store: Entity<Self>,
 8921        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8922        mut cx: AsyncApp,
 8923    ) -> Result<()> {
 8924        lsp_store.update(&mut cx, |lsp_store, cx| {
 8925            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8926
 8927            match envelope.payload.variant.context("invalid variant")? {
 8928                proto::update_language_server::Variant::WorkStart(payload) => {
 8929                    lsp_store.on_lsp_work_start(
 8930                        language_server_id,
 8931                        payload.token,
 8932                        LanguageServerProgress {
 8933                            title: payload.title,
 8934                            is_disk_based_diagnostics_progress: false,
 8935                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8936                            message: payload.message,
 8937                            percentage: payload.percentage.map(|p| p as usize),
 8938                            last_update_at: cx.background_executor().now(),
 8939                        },
 8940                        cx,
 8941                    );
 8942                }
 8943                proto::update_language_server::Variant::WorkProgress(payload) => {
 8944                    lsp_store.on_lsp_work_progress(
 8945                        language_server_id,
 8946                        payload.token,
 8947                        LanguageServerProgress {
 8948                            title: None,
 8949                            is_disk_based_diagnostics_progress: false,
 8950                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8951                            message: payload.message,
 8952                            percentage: payload.percentage.map(|p| p as usize),
 8953                            last_update_at: cx.background_executor().now(),
 8954                        },
 8955                        cx,
 8956                    );
 8957                }
 8958
 8959                proto::update_language_server::Variant::WorkEnd(payload) => {
 8960                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8961                }
 8962
 8963                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8964                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8965                }
 8966
 8967                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8968                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8969                }
 8970
 8971                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8972                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8973                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8974                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 8975                        language_server_id,
 8976                        name: envelope
 8977                            .payload
 8978                            .server_name
 8979                            .map(SharedString::new)
 8980                            .map(LanguageServerName),
 8981                        message: non_lsp,
 8982                    });
 8983                }
 8984            }
 8985
 8986            Ok(())
 8987        })?
 8988    }
 8989
 8990    async fn handle_language_server_log(
 8991        this: Entity<Self>,
 8992        envelope: TypedEnvelope<proto::LanguageServerLog>,
 8993        mut cx: AsyncApp,
 8994    ) -> Result<()> {
 8995        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8996        let log_type = envelope
 8997            .payload
 8998            .log_type
 8999            .map(LanguageServerLogType::from_proto)
 9000            .context("invalid language server log type")?;
 9001
 9002        let message = envelope.payload.message;
 9003
 9004        this.update(&mut cx, |_, cx| {
 9005            cx.emit(LspStoreEvent::LanguageServerLog(
 9006                language_server_id,
 9007                log_type,
 9008                message,
 9009            ));
 9010        })
 9011    }
 9012
 9013    async fn handle_lsp_ext_cancel_flycheck(
 9014        lsp_store: Entity<Self>,
 9015        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9016        cx: AsyncApp,
 9017    ) -> Result<proto::Ack> {
 9018        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9019        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9020            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9021                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9022            } else {
 9023                None
 9024            }
 9025        })?;
 9026        if let Some(task) = task {
 9027            task.context("handling lsp ext cancel flycheck")?;
 9028        }
 9029
 9030        Ok(proto::Ack {})
 9031    }
 9032
 9033    async fn handle_lsp_ext_run_flycheck(
 9034        lsp_store: Entity<Self>,
 9035        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9036        mut cx: AsyncApp,
 9037    ) -> Result<proto::Ack> {
 9038        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9039        lsp_store.update(&mut cx, |lsp_store, cx| {
 9040            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9041                let text_document = if envelope.payload.current_file_only {
 9042                    let buffer_id = envelope
 9043                        .payload
 9044                        .buffer_id
 9045                        .map(|id| BufferId::new(id))
 9046                        .transpose()?;
 9047                    buffer_id
 9048                        .and_then(|buffer_id| {
 9049                            lsp_store
 9050                                .buffer_store()
 9051                                .read(cx)
 9052                                .get(buffer_id)
 9053                                .and_then(|buffer| {
 9054                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9055                                })
 9056                                .map(|path| make_text_document_identifier(&path))
 9057                        })
 9058                        .transpose()?
 9059                } else {
 9060                    None
 9061                };
 9062                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9063                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9064                )?;
 9065            }
 9066            anyhow::Ok(())
 9067        })??;
 9068
 9069        Ok(proto::Ack {})
 9070    }
 9071
 9072    async fn handle_lsp_ext_clear_flycheck(
 9073        lsp_store: Entity<Self>,
 9074        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9075        cx: AsyncApp,
 9076    ) -> Result<proto::Ack> {
 9077        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9078        lsp_store
 9079            .read_with(&cx, |lsp_store, _| {
 9080                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9081                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9082                } else {
 9083                    None
 9084                }
 9085            })
 9086            .context("handling lsp ext clear flycheck")?;
 9087
 9088        Ok(proto::Ack {})
 9089    }
 9090
 9091    pub fn disk_based_diagnostics_started(
 9092        &mut self,
 9093        language_server_id: LanguageServerId,
 9094        cx: &mut Context<Self>,
 9095    ) {
 9096        if let Some(language_server_status) =
 9097            self.language_server_statuses.get_mut(&language_server_id)
 9098        {
 9099            language_server_status.has_pending_diagnostic_updates = true;
 9100        }
 9101
 9102        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9103        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9104            language_server_id,
 9105            name: self
 9106                .language_server_adapter_for_id(language_server_id)
 9107                .map(|adapter| adapter.name()),
 9108            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9109                Default::default(),
 9110            ),
 9111        })
 9112    }
 9113
 9114    pub fn disk_based_diagnostics_finished(
 9115        &mut self,
 9116        language_server_id: LanguageServerId,
 9117        cx: &mut Context<Self>,
 9118    ) {
 9119        if let Some(language_server_status) =
 9120            self.language_server_statuses.get_mut(&language_server_id)
 9121        {
 9122            language_server_status.has_pending_diagnostic_updates = false;
 9123        }
 9124
 9125        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9126        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9127            language_server_id,
 9128            name: self
 9129                .language_server_adapter_for_id(language_server_id)
 9130                .map(|adapter| adapter.name()),
 9131            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9132                Default::default(),
 9133            ),
 9134        })
 9135    }
 9136
 9137    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9138    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9139    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9140    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9141    // the language server might take some time to publish diagnostics.
 9142    fn simulate_disk_based_diagnostics_events_if_needed(
 9143        &mut self,
 9144        language_server_id: LanguageServerId,
 9145        cx: &mut Context<Self>,
 9146    ) {
 9147        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9148
 9149        let Some(LanguageServerState::Running {
 9150            simulate_disk_based_diagnostics_completion,
 9151            adapter,
 9152            ..
 9153        }) = self
 9154            .as_local_mut()
 9155            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9156        else {
 9157            return;
 9158        };
 9159
 9160        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9161            return;
 9162        }
 9163
 9164        let prev_task =
 9165            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9166                cx.background_executor()
 9167                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9168                    .await;
 9169
 9170                this.update(cx, |this, cx| {
 9171                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9172
 9173                    if let Some(LanguageServerState::Running {
 9174                        simulate_disk_based_diagnostics_completion,
 9175                        ..
 9176                    }) = this.as_local_mut().and_then(|local_store| {
 9177                        local_store.language_servers.get_mut(&language_server_id)
 9178                    }) {
 9179                        *simulate_disk_based_diagnostics_completion = None;
 9180                    }
 9181                })
 9182                .ok();
 9183            }));
 9184
 9185        if prev_task.is_none() {
 9186            self.disk_based_diagnostics_started(language_server_id, cx);
 9187        }
 9188    }
 9189
 9190    pub fn language_server_statuses(
 9191        &self,
 9192    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9193        self.language_server_statuses
 9194            .iter()
 9195            .map(|(key, value)| (*key, value))
 9196    }
 9197
 9198    pub(super) fn did_rename_entry(
 9199        &self,
 9200        worktree_id: WorktreeId,
 9201        old_path: &Path,
 9202        new_path: &Path,
 9203        is_dir: bool,
 9204    ) {
 9205        maybe!({
 9206            let local_store = self.as_local()?;
 9207
 9208            let old_uri = lsp::Uri::from_file_path(old_path)
 9209                .ok()
 9210                .map(|uri| uri.to_string())?;
 9211            let new_uri = lsp::Uri::from_file_path(new_path)
 9212                .ok()
 9213                .map(|uri| uri.to_string())?;
 9214
 9215            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9216                let Some(filter) = local_store
 9217                    .language_server_paths_watched_for_rename
 9218                    .get(&language_server.server_id())
 9219                else {
 9220                    continue;
 9221                };
 9222
 9223                if filter.should_send_did_rename(&old_uri, is_dir) {
 9224                    language_server
 9225                        .notify::<DidRenameFiles>(RenameFilesParams {
 9226                            files: vec![FileRename {
 9227                                old_uri: old_uri.clone(),
 9228                                new_uri: new_uri.clone(),
 9229                            }],
 9230                        })
 9231                        .ok();
 9232                }
 9233            }
 9234            Some(())
 9235        });
 9236    }
 9237
 9238    pub(super) fn will_rename_entry(
 9239        this: WeakEntity<Self>,
 9240        worktree_id: WorktreeId,
 9241        old_path: &Path,
 9242        new_path: &Path,
 9243        is_dir: bool,
 9244        cx: AsyncApp,
 9245    ) -> Task<ProjectTransaction> {
 9246        let old_uri = lsp::Uri::from_file_path(old_path)
 9247            .ok()
 9248            .map(|uri| uri.to_string());
 9249        let new_uri = lsp::Uri::from_file_path(new_path)
 9250            .ok()
 9251            .map(|uri| uri.to_string());
 9252        cx.spawn(async move |cx| {
 9253            let mut tasks = vec![];
 9254            this.update(cx, |this, cx| {
 9255                let local_store = this.as_local()?;
 9256                let old_uri = old_uri?;
 9257                let new_uri = new_uri?;
 9258                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9259                    let Some(filter) = local_store
 9260                        .language_server_paths_watched_for_rename
 9261                        .get(&language_server.server_id())
 9262                    else {
 9263                        continue;
 9264                    };
 9265
 9266                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9267                        let apply_edit = cx.spawn({
 9268                            let old_uri = old_uri.clone();
 9269                            let new_uri = new_uri.clone();
 9270                            let language_server = language_server.clone();
 9271                            async move |this, cx| {
 9272                                let edit = language_server
 9273                                    .request::<WillRenameFiles>(RenameFilesParams {
 9274                                        files: vec![FileRename { old_uri, new_uri }],
 9275                                    })
 9276                                    .await
 9277                                    .into_response()
 9278                                    .context("will rename files")
 9279                                    .log_err()
 9280                                    .flatten()?;
 9281
 9282                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9283                                    this.upgrade()?,
 9284                                    edit,
 9285                                    false,
 9286                                    language_server.clone(),
 9287                                    cx,
 9288                                )
 9289                                .await
 9290                                .ok()?;
 9291                                Some(transaction)
 9292                            }
 9293                        });
 9294                        tasks.push(apply_edit);
 9295                    }
 9296                }
 9297                Some(())
 9298            })
 9299            .ok()
 9300            .flatten();
 9301            let mut merged_transaction = ProjectTransaction::default();
 9302            for task in tasks {
 9303                // Await on tasks sequentially so that the order of application of edits is deterministic
 9304                // (at least with regards to the order of registration of language servers)
 9305                if let Some(transaction) = task.await {
 9306                    for (buffer, buffer_transaction) in transaction.0 {
 9307                        merged_transaction.0.insert(buffer, buffer_transaction);
 9308                    }
 9309                }
 9310            }
 9311            merged_transaction
 9312        })
 9313    }
 9314
 9315    fn lsp_notify_abs_paths_changed(
 9316        &mut self,
 9317        server_id: LanguageServerId,
 9318        changes: Vec<PathEvent>,
 9319    ) {
 9320        maybe!({
 9321            let server = self.language_server_for_id(server_id)?;
 9322            let changes = changes
 9323                .into_iter()
 9324                .filter_map(|event| {
 9325                    let typ = match event.kind? {
 9326                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9327                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9328                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9329                    };
 9330                    Some(lsp::FileEvent {
 9331                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9332                        typ,
 9333                    })
 9334                })
 9335                .collect::<Vec<_>>();
 9336            if !changes.is_empty() {
 9337                server
 9338                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9339                        lsp::DidChangeWatchedFilesParams { changes },
 9340                    )
 9341                    .ok();
 9342            }
 9343            Some(())
 9344        });
 9345    }
 9346
 9347    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9348        self.as_local()?.language_server_for_id(id)
 9349    }
 9350
 9351    fn on_lsp_progress(
 9352        &mut self,
 9353        progress: lsp::ProgressParams,
 9354        language_server_id: LanguageServerId,
 9355        disk_based_diagnostics_progress_token: Option<String>,
 9356        cx: &mut Context<Self>,
 9357    ) {
 9358        let token = match progress.token {
 9359            lsp::NumberOrString::String(token) => token,
 9360            lsp::NumberOrString::Number(token) => {
 9361                log::info!("skipping numeric progress token {}", token);
 9362                return;
 9363            }
 9364        };
 9365
 9366        match progress.value {
 9367            lsp::ProgressParamsValue::WorkDone(progress) => {
 9368                self.handle_work_done_progress(
 9369                    progress,
 9370                    language_server_id,
 9371                    disk_based_diagnostics_progress_token,
 9372                    token,
 9373                    cx,
 9374                );
 9375            }
 9376            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9377                let identifier = token.split_once("id:").map(|(_, id)| id.to_owned());
 9378                if let Some(LanguageServerState::Running {
 9379                    workspace_diagnostics_refresh_tasks,
 9380                    ..
 9381                }) = self
 9382                    .as_local_mut()
 9383                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9384                    && let Some(workspace_diagnostics) =
 9385                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9386                {
 9387                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9388                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9389                }
 9390            }
 9391        }
 9392    }
 9393
 9394    fn handle_work_done_progress(
 9395        &mut self,
 9396        progress: lsp::WorkDoneProgress,
 9397        language_server_id: LanguageServerId,
 9398        disk_based_diagnostics_progress_token: Option<String>,
 9399        token: String,
 9400        cx: &mut Context<Self>,
 9401    ) {
 9402        let language_server_status =
 9403            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9404                status
 9405            } else {
 9406                return;
 9407            };
 9408
 9409        if !language_server_status.progress_tokens.contains(&token) {
 9410            return;
 9411        }
 9412
 9413        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9414            .as_ref()
 9415            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9416
 9417        match progress {
 9418            lsp::WorkDoneProgress::Begin(report) => {
 9419                if is_disk_based_diagnostics_progress {
 9420                    self.disk_based_diagnostics_started(language_server_id, cx);
 9421                }
 9422                self.on_lsp_work_start(
 9423                    language_server_id,
 9424                    token.clone(),
 9425                    LanguageServerProgress {
 9426                        title: Some(report.title),
 9427                        is_disk_based_diagnostics_progress,
 9428                        is_cancellable: report.cancellable.unwrap_or(false),
 9429                        message: report.message.clone(),
 9430                        percentage: report.percentage.map(|p| p as usize),
 9431                        last_update_at: cx.background_executor().now(),
 9432                    },
 9433                    cx,
 9434                );
 9435            }
 9436            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9437                language_server_id,
 9438                token,
 9439                LanguageServerProgress {
 9440                    title: None,
 9441                    is_disk_based_diagnostics_progress,
 9442                    is_cancellable: report.cancellable.unwrap_or(false),
 9443                    message: report.message,
 9444                    percentage: report.percentage.map(|p| p as usize),
 9445                    last_update_at: cx.background_executor().now(),
 9446                },
 9447                cx,
 9448            ),
 9449            lsp::WorkDoneProgress::End(_) => {
 9450                language_server_status.progress_tokens.remove(&token);
 9451                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9452                if is_disk_based_diagnostics_progress {
 9453                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9454                }
 9455            }
 9456        }
 9457    }
 9458
 9459    fn on_lsp_work_start(
 9460        &mut self,
 9461        language_server_id: LanguageServerId,
 9462        token: String,
 9463        progress: LanguageServerProgress,
 9464        cx: &mut Context<Self>,
 9465    ) {
 9466        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9467            status.pending_work.insert(token.clone(), progress.clone());
 9468            cx.notify();
 9469        }
 9470        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9471            language_server_id,
 9472            name: self
 9473                .language_server_adapter_for_id(language_server_id)
 9474                .map(|adapter| adapter.name()),
 9475            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9476                token,
 9477                title: progress.title,
 9478                message: progress.message,
 9479                percentage: progress.percentage.map(|p| p as u32),
 9480                is_cancellable: Some(progress.is_cancellable),
 9481            }),
 9482        })
 9483    }
 9484
 9485    fn on_lsp_work_progress(
 9486        &mut self,
 9487        language_server_id: LanguageServerId,
 9488        token: String,
 9489        progress: LanguageServerProgress,
 9490        cx: &mut Context<Self>,
 9491    ) {
 9492        let mut did_update = false;
 9493        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9494            match status.pending_work.entry(token.clone()) {
 9495                btree_map::Entry::Vacant(entry) => {
 9496                    entry.insert(progress.clone());
 9497                    did_update = true;
 9498                }
 9499                btree_map::Entry::Occupied(mut entry) => {
 9500                    let entry = entry.get_mut();
 9501                    if (progress.last_update_at - entry.last_update_at)
 9502                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9503                    {
 9504                        entry.last_update_at = progress.last_update_at;
 9505                        if progress.message.is_some() {
 9506                            entry.message = progress.message.clone();
 9507                        }
 9508                        if progress.percentage.is_some() {
 9509                            entry.percentage = progress.percentage;
 9510                        }
 9511                        if progress.is_cancellable != entry.is_cancellable {
 9512                            entry.is_cancellable = progress.is_cancellable;
 9513                        }
 9514                        did_update = true;
 9515                    }
 9516                }
 9517            }
 9518        }
 9519
 9520        if did_update {
 9521            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9522                language_server_id,
 9523                name: self
 9524                    .language_server_adapter_for_id(language_server_id)
 9525                    .map(|adapter| adapter.name()),
 9526                message: proto::update_language_server::Variant::WorkProgress(
 9527                    proto::LspWorkProgress {
 9528                        token,
 9529                        message: progress.message,
 9530                        percentage: progress.percentage.map(|p| p as u32),
 9531                        is_cancellable: Some(progress.is_cancellable),
 9532                    },
 9533                ),
 9534            })
 9535        }
 9536    }
 9537
 9538    fn on_lsp_work_end(
 9539        &mut self,
 9540        language_server_id: LanguageServerId,
 9541        token: String,
 9542        cx: &mut Context<Self>,
 9543    ) {
 9544        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9545            if let Some(work) = status.pending_work.remove(&token)
 9546                && !work.is_disk_based_diagnostics_progress
 9547            {
 9548                cx.emit(LspStoreEvent::RefreshInlayHints(language_server_id));
 9549            }
 9550            cx.notify();
 9551        }
 9552
 9553        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9554            language_server_id,
 9555            name: self
 9556                .language_server_adapter_for_id(language_server_id)
 9557                .map(|adapter| adapter.name()),
 9558            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9559        })
 9560    }
 9561
 9562    pub async fn handle_resolve_completion_documentation(
 9563        this: Entity<Self>,
 9564        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9565        mut cx: AsyncApp,
 9566    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9567        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9568
 9569        let completion = this
 9570            .read_with(&cx, |this, cx| {
 9571                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9572                let server = this
 9573                    .language_server_for_id(id)
 9574                    .with_context(|| format!("No language server {id}"))?;
 9575
 9576                anyhow::Ok(cx.background_spawn(async move {
 9577                    let can_resolve = server
 9578                        .capabilities()
 9579                        .completion_provider
 9580                        .as_ref()
 9581                        .and_then(|options| options.resolve_provider)
 9582                        .unwrap_or(false);
 9583                    if can_resolve {
 9584                        server
 9585                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9586                            .await
 9587                            .into_response()
 9588                            .context("resolve completion item")
 9589                    } else {
 9590                        anyhow::Ok(lsp_completion)
 9591                    }
 9592                }))
 9593            })??
 9594            .await?;
 9595
 9596        let mut documentation_is_markdown = false;
 9597        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9598        let documentation = match completion.documentation {
 9599            Some(lsp::Documentation::String(text)) => text,
 9600
 9601            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9602                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9603                value
 9604            }
 9605
 9606            _ => String::new(),
 9607        };
 9608
 9609        // If we have a new buffer_id, that means we're talking to a new client
 9610        // and want to check for new text_edits in the completion too.
 9611        let mut old_replace_start = None;
 9612        let mut old_replace_end = None;
 9613        let mut old_insert_start = None;
 9614        let mut old_insert_end = None;
 9615        let mut new_text = String::default();
 9616        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9617            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9618                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9619                anyhow::Ok(buffer.read(cx).snapshot())
 9620            })??;
 9621
 9622            if let Some(text_edit) = completion.text_edit.as_ref() {
 9623                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9624
 9625                if let Some(mut edit) = edit {
 9626                    LineEnding::normalize(&mut edit.new_text);
 9627
 9628                    new_text = edit.new_text;
 9629                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9630                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9631                    if let Some(insert_range) = edit.insert_range {
 9632                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9633                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9634                    }
 9635                }
 9636            }
 9637        }
 9638
 9639        Ok(proto::ResolveCompletionDocumentationResponse {
 9640            documentation,
 9641            documentation_is_markdown,
 9642            old_replace_start,
 9643            old_replace_end,
 9644            new_text,
 9645            lsp_completion,
 9646            old_insert_start,
 9647            old_insert_end,
 9648        })
 9649    }
 9650
 9651    async fn handle_on_type_formatting(
 9652        this: Entity<Self>,
 9653        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9654        mut cx: AsyncApp,
 9655    ) -> Result<proto::OnTypeFormattingResponse> {
 9656        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9657            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9658            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9659            let position = envelope
 9660                .payload
 9661                .position
 9662                .and_then(deserialize_anchor)
 9663                .context("invalid position")?;
 9664            anyhow::Ok(this.apply_on_type_formatting(
 9665                buffer,
 9666                position,
 9667                envelope.payload.trigger.clone(),
 9668                cx,
 9669            ))
 9670        })??;
 9671
 9672        let transaction = on_type_formatting
 9673            .await?
 9674            .as_ref()
 9675            .map(language::proto::serialize_transaction);
 9676        Ok(proto::OnTypeFormattingResponse { transaction })
 9677    }
 9678
 9679    async fn handle_refresh_inlay_hints(
 9680        lsp_store: Entity<Self>,
 9681        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9682        mut cx: AsyncApp,
 9683    ) -> Result<proto::Ack> {
 9684        lsp_store.update(&mut cx, |_, cx| {
 9685            cx.emit(LspStoreEvent::RefreshInlayHints(
 9686                LanguageServerId::from_proto(envelope.payload.server_id),
 9687            ));
 9688        })?;
 9689        Ok(proto::Ack {})
 9690    }
 9691
 9692    async fn handle_pull_workspace_diagnostics(
 9693        lsp_store: Entity<Self>,
 9694        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9695        mut cx: AsyncApp,
 9696    ) -> Result<proto::Ack> {
 9697        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9698        lsp_store.update(&mut cx, |lsp_store, _| {
 9699            lsp_store.pull_workspace_diagnostics(server_id);
 9700        })?;
 9701        Ok(proto::Ack {})
 9702    }
 9703
 9704    async fn handle_get_color_presentation(
 9705        lsp_store: Entity<Self>,
 9706        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9707        mut cx: AsyncApp,
 9708    ) -> Result<proto::GetColorPresentationResponse> {
 9709        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9710        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9711            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9712        })??;
 9713
 9714        let color = envelope
 9715            .payload
 9716            .color
 9717            .context("invalid color resolve request")?;
 9718        let start = color
 9719            .lsp_range_start
 9720            .context("invalid color resolve request")?;
 9721        let end = color
 9722            .lsp_range_end
 9723            .context("invalid color resolve request")?;
 9724
 9725        let color = DocumentColor {
 9726            lsp_range: lsp::Range {
 9727                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9728                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9729            },
 9730            color: lsp::Color {
 9731                red: color.red,
 9732                green: color.green,
 9733                blue: color.blue,
 9734                alpha: color.alpha,
 9735            },
 9736            resolved: false,
 9737            color_presentations: Vec::new(),
 9738        };
 9739        let resolved_color = lsp_store
 9740            .update(&mut cx, |lsp_store, cx| {
 9741                lsp_store.resolve_color_presentation(
 9742                    color,
 9743                    buffer.clone(),
 9744                    LanguageServerId(envelope.payload.server_id as usize),
 9745                    cx,
 9746                )
 9747            })?
 9748            .await
 9749            .context("resolving color presentation")?;
 9750
 9751        Ok(proto::GetColorPresentationResponse {
 9752            presentations: resolved_color
 9753                .color_presentations
 9754                .into_iter()
 9755                .map(|presentation| proto::ColorPresentation {
 9756                    label: presentation.label.to_string(),
 9757                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9758                    additional_text_edits: presentation
 9759                        .additional_text_edits
 9760                        .into_iter()
 9761                        .map(serialize_lsp_edit)
 9762                        .collect(),
 9763                })
 9764                .collect(),
 9765        })
 9766    }
 9767
 9768    async fn handle_resolve_inlay_hint(
 9769        lsp_store: Entity<Self>,
 9770        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9771        mut cx: AsyncApp,
 9772    ) -> Result<proto::ResolveInlayHintResponse> {
 9773        let proto_hint = envelope
 9774            .payload
 9775            .hint
 9776            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9777        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9778            .context("resolved proto inlay hint conversion")?;
 9779        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9780            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9781            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9782        })??;
 9783        let response_hint = lsp_store
 9784            .update(&mut cx, |lsp_store, cx| {
 9785                lsp_store.resolve_inlay_hint(
 9786                    hint,
 9787                    buffer,
 9788                    LanguageServerId(envelope.payload.language_server_id as usize),
 9789                    cx,
 9790                )
 9791            })?
 9792            .await
 9793            .context("inlay hints fetch")?;
 9794        Ok(proto::ResolveInlayHintResponse {
 9795            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9796        })
 9797    }
 9798
 9799    async fn handle_refresh_code_lens(
 9800        this: Entity<Self>,
 9801        _: TypedEnvelope<proto::RefreshCodeLens>,
 9802        mut cx: AsyncApp,
 9803    ) -> Result<proto::Ack> {
 9804        this.update(&mut cx, |_, cx| {
 9805            cx.emit(LspStoreEvent::RefreshCodeLens);
 9806        })?;
 9807        Ok(proto::Ack {})
 9808    }
 9809
 9810    async fn handle_open_buffer_for_symbol(
 9811        this: Entity<Self>,
 9812        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9813        mut cx: AsyncApp,
 9814    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9815        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9816        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9817        let symbol = Self::deserialize_symbol(symbol)?;
 9818        this.read_with(&cx, |this, _| {
 9819            if let SymbolLocation::OutsideProject {
 9820                abs_path,
 9821                signature,
 9822            } = &symbol.path
 9823            {
 9824                let new_signature = this.symbol_signature(&abs_path);
 9825                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9826            }
 9827            Ok(())
 9828        })??;
 9829        let buffer = this
 9830            .update(&mut cx, |this, cx| {
 9831                this.open_buffer_for_symbol(
 9832                    &Symbol {
 9833                        language_server_name: symbol.language_server_name,
 9834                        source_worktree_id: symbol.source_worktree_id,
 9835                        source_language_server_id: symbol.source_language_server_id,
 9836                        path: symbol.path,
 9837                        name: symbol.name,
 9838                        kind: symbol.kind,
 9839                        range: symbol.range,
 9840                        label: CodeLabel::default(),
 9841                    },
 9842                    cx,
 9843                )
 9844            })?
 9845            .await?;
 9846
 9847        this.update(&mut cx, |this, cx| {
 9848            let is_private = buffer
 9849                .read(cx)
 9850                .file()
 9851                .map(|f| f.is_private())
 9852                .unwrap_or_default();
 9853            if is_private {
 9854                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9855            } else {
 9856                this.buffer_store
 9857                    .update(cx, |buffer_store, cx| {
 9858                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9859                    })
 9860                    .detach_and_log_err(cx);
 9861                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9862                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9863            }
 9864        })?
 9865    }
 9866
 9867    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9868        let mut hasher = Sha256::new();
 9869        hasher.update(abs_path.to_string_lossy().as_bytes());
 9870        hasher.update(self.nonce.to_be_bytes());
 9871        hasher.finalize().as_slice().try_into().unwrap()
 9872    }
 9873
 9874    pub async fn handle_get_project_symbols(
 9875        this: Entity<Self>,
 9876        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9877        mut cx: AsyncApp,
 9878    ) -> Result<proto::GetProjectSymbolsResponse> {
 9879        let symbols = this
 9880            .update(&mut cx, |this, cx| {
 9881                this.symbols(&envelope.payload.query, cx)
 9882            })?
 9883            .await?;
 9884
 9885        Ok(proto::GetProjectSymbolsResponse {
 9886            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9887        })
 9888    }
 9889
 9890    pub async fn handle_restart_language_servers(
 9891        this: Entity<Self>,
 9892        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9893        mut cx: AsyncApp,
 9894    ) -> Result<proto::Ack> {
 9895        this.update(&mut cx, |lsp_store, cx| {
 9896            let buffers =
 9897                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9898            lsp_store.restart_language_servers_for_buffers(
 9899                buffers,
 9900                envelope
 9901                    .payload
 9902                    .only_servers
 9903                    .into_iter()
 9904                    .filter_map(|selector| {
 9905                        Some(match selector.selector? {
 9906                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9907                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9908                            }
 9909                            proto::language_server_selector::Selector::Name(name) => {
 9910                                LanguageServerSelector::Name(LanguageServerName(
 9911                                    SharedString::from(name),
 9912                                ))
 9913                            }
 9914                        })
 9915                    })
 9916                    .collect(),
 9917                cx,
 9918            );
 9919        })?;
 9920
 9921        Ok(proto::Ack {})
 9922    }
 9923
 9924    pub async fn handle_stop_language_servers(
 9925        lsp_store: Entity<Self>,
 9926        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9927        mut cx: AsyncApp,
 9928    ) -> Result<proto::Ack> {
 9929        lsp_store.update(&mut cx, |lsp_store, cx| {
 9930            if envelope.payload.all
 9931                && envelope.payload.also_servers.is_empty()
 9932                && envelope.payload.buffer_ids.is_empty()
 9933            {
 9934                lsp_store.stop_all_language_servers(cx);
 9935            } else {
 9936                let buffers =
 9937                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9938                lsp_store
 9939                    .stop_language_servers_for_buffers(
 9940                        buffers,
 9941                        envelope
 9942                            .payload
 9943                            .also_servers
 9944                            .into_iter()
 9945                            .filter_map(|selector| {
 9946                                Some(match selector.selector? {
 9947                                    proto::language_server_selector::Selector::ServerId(
 9948                                        server_id,
 9949                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9950                                        server_id,
 9951                                    )),
 9952                                    proto::language_server_selector::Selector::Name(name) => {
 9953                                        LanguageServerSelector::Name(LanguageServerName(
 9954                                            SharedString::from(name),
 9955                                        ))
 9956                                    }
 9957                                })
 9958                            })
 9959                            .collect(),
 9960                        cx,
 9961                    )
 9962                    .detach_and_log_err(cx);
 9963            }
 9964        })?;
 9965
 9966        Ok(proto::Ack {})
 9967    }
 9968
 9969    pub async fn handle_cancel_language_server_work(
 9970        this: Entity<Self>,
 9971        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
 9972        mut cx: AsyncApp,
 9973    ) -> Result<proto::Ack> {
 9974        this.update(&mut cx, |this, cx| {
 9975            if let Some(work) = envelope.payload.work {
 9976                match work {
 9977                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
 9978                        let buffers =
 9979                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
 9980                        this.cancel_language_server_work_for_buffers(buffers, cx);
 9981                    }
 9982                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
 9983                        let server_id = LanguageServerId::from_proto(work.language_server_id);
 9984                        this.cancel_language_server_work(server_id, work.token, cx);
 9985                    }
 9986                }
 9987            }
 9988        })?;
 9989
 9990        Ok(proto::Ack {})
 9991    }
 9992
 9993    fn buffer_ids_to_buffers(
 9994        &mut self,
 9995        buffer_ids: impl Iterator<Item = u64>,
 9996        cx: &mut Context<Self>,
 9997    ) -> Vec<Entity<Buffer>> {
 9998        buffer_ids
 9999            .into_iter()
10000            .flat_map(|buffer_id| {
10001                self.buffer_store
10002                    .read(cx)
10003                    .get(BufferId::new(buffer_id).log_err()?)
10004            })
10005            .collect::<Vec<_>>()
10006    }
10007
10008    async fn handle_apply_additional_edits_for_completion(
10009        this: Entity<Self>,
10010        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10011        mut cx: AsyncApp,
10012    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10013        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10014            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10015            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10016            let completion = Self::deserialize_completion(
10017                envelope.payload.completion.context("invalid completion")?,
10018            )?;
10019            anyhow::Ok((buffer, completion))
10020        })??;
10021
10022        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10023            this.apply_additional_edits_for_completion(
10024                buffer,
10025                Rc::new(RefCell::new(Box::new([Completion {
10026                    replace_range: completion.replace_range,
10027                    new_text: completion.new_text,
10028                    source: completion.source,
10029                    documentation: None,
10030                    label: CodeLabel::default(),
10031                    insert_text_mode: None,
10032                    icon_path: None,
10033                    confirm: None,
10034                }]))),
10035                0,
10036                false,
10037                cx,
10038            )
10039        })?;
10040
10041        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10042            transaction: apply_additional_edits
10043                .await?
10044                .as_ref()
10045                .map(language::proto::serialize_transaction),
10046        })
10047    }
10048
10049    pub fn last_formatting_failure(&self) -> Option<&str> {
10050        self.last_formatting_failure.as_deref()
10051    }
10052
10053    pub fn reset_last_formatting_failure(&mut self) {
10054        self.last_formatting_failure = None;
10055    }
10056
10057    pub fn environment_for_buffer(
10058        &self,
10059        buffer: &Entity<Buffer>,
10060        cx: &mut Context<Self>,
10061    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10062        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10063            environment.update(cx, |env, cx| {
10064                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10065            })
10066        } else {
10067            Task::ready(None).shared()
10068        }
10069    }
10070
10071    pub fn format(
10072        &mut self,
10073        buffers: HashSet<Entity<Buffer>>,
10074        target: LspFormatTarget,
10075        push_to_history: bool,
10076        trigger: FormatTrigger,
10077        cx: &mut Context<Self>,
10078    ) -> Task<anyhow::Result<ProjectTransaction>> {
10079        let logger = zlog::scoped!("format");
10080        if self.as_local().is_some() {
10081            zlog::trace!(logger => "Formatting locally");
10082            let logger = zlog::scoped!(logger => "local");
10083            let buffers = buffers
10084                .into_iter()
10085                .map(|buffer_handle| {
10086                    let buffer = buffer_handle.read(cx);
10087                    let buffer_abs_path = File::from_dyn(buffer.file())
10088                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10089
10090                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10091                })
10092                .collect::<Vec<_>>();
10093
10094            cx.spawn(async move |lsp_store, cx| {
10095                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10096
10097                for (handle, abs_path, id) in buffers {
10098                    let env = lsp_store
10099                        .update(cx, |lsp_store, cx| {
10100                            lsp_store.environment_for_buffer(&handle, cx)
10101                        })?
10102                        .await;
10103
10104                    let ranges = match &target {
10105                        LspFormatTarget::Buffers => None,
10106                        LspFormatTarget::Ranges(ranges) => {
10107                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10108                        }
10109                    };
10110
10111                    formattable_buffers.push(FormattableBuffer {
10112                        handle,
10113                        abs_path,
10114                        env,
10115                        ranges,
10116                    });
10117                }
10118                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10119
10120                let format_timer = zlog::time!(logger => "Formatting buffers");
10121                let result = LocalLspStore::format_locally(
10122                    lsp_store.clone(),
10123                    formattable_buffers,
10124                    push_to_history,
10125                    trigger,
10126                    logger,
10127                    cx,
10128                )
10129                .await;
10130                format_timer.end();
10131
10132                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10133
10134                lsp_store.update(cx, |lsp_store, _| {
10135                    lsp_store.update_last_formatting_failure(&result);
10136                })?;
10137
10138                result
10139            })
10140        } else if let Some((client, project_id)) = self.upstream_client() {
10141            zlog::trace!(logger => "Formatting remotely");
10142            let logger = zlog::scoped!(logger => "remote");
10143            // Don't support formatting ranges via remote
10144            match target {
10145                LspFormatTarget::Buffers => {}
10146                LspFormatTarget::Ranges(_) => {
10147                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10148                    return Task::ready(Ok(ProjectTransaction::default()));
10149                }
10150            }
10151
10152            let buffer_store = self.buffer_store();
10153            cx.spawn(async move |lsp_store, cx| {
10154                zlog::trace!(logger => "Sending remote format request");
10155                let request_timer = zlog::time!(logger => "remote format request");
10156                let result = client
10157                    .request(proto::FormatBuffers {
10158                        project_id,
10159                        trigger: trigger as i32,
10160                        buffer_ids: buffers
10161                            .iter()
10162                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10163                            .collect::<Result<_>>()?,
10164                    })
10165                    .await
10166                    .and_then(|result| result.transaction.context("missing transaction"));
10167                request_timer.end();
10168
10169                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10170
10171                lsp_store.update(cx, |lsp_store, _| {
10172                    lsp_store.update_last_formatting_failure(&result);
10173                })?;
10174
10175                let transaction_response = result?;
10176                let _timer = zlog::time!(logger => "deserializing project transaction");
10177                buffer_store
10178                    .update(cx, |buffer_store, cx| {
10179                        buffer_store.deserialize_project_transaction(
10180                            transaction_response,
10181                            push_to_history,
10182                            cx,
10183                        )
10184                    })?
10185                    .await
10186            })
10187        } else {
10188            zlog::trace!(logger => "Not formatting");
10189            Task::ready(Ok(ProjectTransaction::default()))
10190        }
10191    }
10192
10193    async fn handle_format_buffers(
10194        this: Entity<Self>,
10195        envelope: TypedEnvelope<proto::FormatBuffers>,
10196        mut cx: AsyncApp,
10197    ) -> Result<proto::FormatBuffersResponse> {
10198        let sender_id = envelope.original_sender_id().unwrap_or_default();
10199        let format = this.update(&mut cx, |this, cx| {
10200            let mut buffers = HashSet::default();
10201            for buffer_id in &envelope.payload.buffer_ids {
10202                let buffer_id = BufferId::new(*buffer_id)?;
10203                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10204            }
10205            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10206            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10207        })??;
10208
10209        let project_transaction = format.await?;
10210        let project_transaction = this.update(&mut cx, |this, cx| {
10211            this.buffer_store.update(cx, |buffer_store, cx| {
10212                buffer_store.serialize_project_transaction_for_peer(
10213                    project_transaction,
10214                    sender_id,
10215                    cx,
10216                )
10217            })
10218        })?;
10219        Ok(proto::FormatBuffersResponse {
10220            transaction: Some(project_transaction),
10221        })
10222    }
10223
10224    async fn handle_apply_code_action_kind(
10225        this: Entity<Self>,
10226        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10227        mut cx: AsyncApp,
10228    ) -> Result<proto::ApplyCodeActionKindResponse> {
10229        let sender_id = envelope.original_sender_id().unwrap_or_default();
10230        let format = this.update(&mut cx, |this, cx| {
10231            let mut buffers = HashSet::default();
10232            for buffer_id in &envelope.payload.buffer_ids {
10233                let buffer_id = BufferId::new(*buffer_id)?;
10234                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10235            }
10236            let kind = match envelope.payload.kind.as_str() {
10237                "" => CodeActionKind::EMPTY,
10238                "quickfix" => CodeActionKind::QUICKFIX,
10239                "refactor" => CodeActionKind::REFACTOR,
10240                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10241                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10242                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10243                "source" => CodeActionKind::SOURCE,
10244                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10245                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10246                _ => anyhow::bail!(
10247                    "Invalid code action kind {}",
10248                    envelope.payload.kind.as_str()
10249                ),
10250            };
10251            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10252        })??;
10253
10254        let project_transaction = format.await?;
10255        let project_transaction = this.update(&mut cx, |this, cx| {
10256            this.buffer_store.update(cx, |buffer_store, cx| {
10257                buffer_store.serialize_project_transaction_for_peer(
10258                    project_transaction,
10259                    sender_id,
10260                    cx,
10261                )
10262            })
10263        })?;
10264        Ok(proto::ApplyCodeActionKindResponse {
10265            transaction: Some(project_transaction),
10266        })
10267    }
10268
10269    async fn shutdown_language_server(
10270        server_state: Option<LanguageServerState>,
10271        name: LanguageServerName,
10272        cx: &mut AsyncApp,
10273    ) {
10274        let server = match server_state {
10275            Some(LanguageServerState::Starting { startup, .. }) => {
10276                let mut timer = cx
10277                    .background_executor()
10278                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10279                    .fuse();
10280
10281                select! {
10282                    server = startup.fuse() => server,
10283                    () = timer => {
10284                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10285                        None
10286                    },
10287                }
10288            }
10289
10290            Some(LanguageServerState::Running { server, .. }) => Some(server),
10291
10292            None => None,
10293        };
10294
10295        if let Some(server) = server
10296            && let Some(shutdown) = server.shutdown()
10297        {
10298            shutdown.await;
10299        }
10300    }
10301
10302    // Returns a list of all of the worktrees which no longer have a language server and the root path
10303    // for the stopped server
10304    fn stop_local_language_server(
10305        &mut self,
10306        server_id: LanguageServerId,
10307        cx: &mut Context<Self>,
10308    ) -> Task<()> {
10309        let local = match &mut self.mode {
10310            LspStoreMode::Local(local) => local,
10311            _ => {
10312                return Task::ready(());
10313            }
10314        };
10315
10316        // Remove this server ID from all entries in the given worktree.
10317        local
10318            .language_server_ids
10319            .retain(|_, state| state.id != server_id);
10320        self.buffer_store.update(cx, |buffer_store, cx| {
10321            for buffer in buffer_store.buffers() {
10322                buffer.update(cx, |buffer, cx| {
10323                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10324                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10325                });
10326            }
10327        });
10328
10329        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10330            summaries.retain(|path, summaries_by_server_id| {
10331                if summaries_by_server_id.remove(&server_id).is_some() {
10332                    if let Some((client, project_id)) = self.downstream_client.clone() {
10333                        client
10334                            .send(proto::UpdateDiagnosticSummary {
10335                                project_id,
10336                                worktree_id: worktree_id.to_proto(),
10337                                summary: Some(proto::DiagnosticSummary {
10338                                    path: path.as_ref().to_proto(),
10339                                    language_server_id: server_id.0 as u64,
10340                                    error_count: 0,
10341                                    warning_count: 0,
10342                                }),
10343                                more_summaries: Vec::new(),
10344                            })
10345                            .log_err();
10346                    }
10347                    !summaries_by_server_id.is_empty()
10348                } else {
10349                    true
10350                }
10351            });
10352        }
10353
10354        let local = self.as_local_mut().unwrap();
10355        for diagnostics in local.diagnostics.values_mut() {
10356            diagnostics.retain(|_, diagnostics_by_server_id| {
10357                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10358                    diagnostics_by_server_id.remove(ix);
10359                    !diagnostics_by_server_id.is_empty()
10360                } else {
10361                    true
10362                }
10363            });
10364        }
10365        local.language_server_watched_paths.remove(&server_id);
10366
10367        let server_state = local.language_servers.remove(&server_id);
10368        self.cleanup_lsp_data(server_id);
10369        let name = self
10370            .language_server_statuses
10371            .remove(&server_id)
10372            .map(|status| status.name)
10373            .or_else(|| {
10374                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10375                    Some(adapter.name())
10376                } else {
10377                    None
10378                }
10379            });
10380
10381        if let Some(name) = name {
10382            log::info!("stopping language server {name}");
10383            self.languages
10384                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10385            cx.notify();
10386
10387            return cx.spawn(async move |lsp_store, cx| {
10388                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10389                lsp_store
10390                    .update(cx, |lsp_store, cx| {
10391                        lsp_store
10392                            .languages
10393                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10394                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10395                        cx.notify();
10396                    })
10397                    .ok();
10398            });
10399        }
10400
10401        if server_state.is_some() {
10402            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10403        }
10404        Task::ready(())
10405    }
10406
10407    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10408        if let Some((client, project_id)) = self.upstream_client() {
10409            let request = client.request(proto::StopLanguageServers {
10410                project_id,
10411                buffer_ids: Vec::new(),
10412                also_servers: Vec::new(),
10413                all: true,
10414            });
10415            cx.background_spawn(request).detach_and_log_err(cx);
10416        } else {
10417            let Some(local) = self.as_local_mut() else {
10418                return;
10419            };
10420            let language_servers_to_stop = local
10421                .language_server_ids
10422                .values()
10423                .map(|state| state.id)
10424                .collect();
10425            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10426            let tasks = language_servers_to_stop
10427                .into_iter()
10428                .map(|server| self.stop_local_language_server(server, cx))
10429                .collect::<Vec<_>>();
10430            cx.background_spawn(async move {
10431                futures::future::join_all(tasks).await;
10432            })
10433            .detach();
10434        }
10435    }
10436
10437    pub fn restart_language_servers_for_buffers(
10438        &mut self,
10439        buffers: Vec<Entity<Buffer>>,
10440        only_restart_servers: HashSet<LanguageServerSelector>,
10441        cx: &mut Context<Self>,
10442    ) {
10443        if let Some((client, project_id)) = self.upstream_client() {
10444            let request = client.request(proto::RestartLanguageServers {
10445                project_id,
10446                buffer_ids: buffers
10447                    .into_iter()
10448                    .map(|b| b.read(cx).remote_id().to_proto())
10449                    .collect(),
10450                only_servers: only_restart_servers
10451                    .into_iter()
10452                    .map(|selector| {
10453                        let selector = match selector {
10454                            LanguageServerSelector::Id(language_server_id) => {
10455                                proto::language_server_selector::Selector::ServerId(
10456                                    language_server_id.to_proto(),
10457                                )
10458                            }
10459                            LanguageServerSelector::Name(language_server_name) => {
10460                                proto::language_server_selector::Selector::Name(
10461                                    language_server_name.to_string(),
10462                                )
10463                            }
10464                        };
10465                        proto::LanguageServerSelector {
10466                            selector: Some(selector),
10467                        }
10468                    })
10469                    .collect(),
10470                all: false,
10471            });
10472            cx.background_spawn(request).detach_and_log_err(cx);
10473        } else {
10474            let stop_task = if only_restart_servers.is_empty() {
10475                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10476            } else {
10477                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10478            };
10479            cx.spawn(async move |lsp_store, cx| {
10480                stop_task.await;
10481                lsp_store
10482                    .update(cx, |lsp_store, cx| {
10483                        for buffer in buffers {
10484                            lsp_store.register_buffer_with_language_servers(
10485                                &buffer,
10486                                only_restart_servers.clone(),
10487                                true,
10488                                cx,
10489                            );
10490                        }
10491                    })
10492                    .ok()
10493            })
10494            .detach();
10495        }
10496    }
10497
10498    pub fn stop_language_servers_for_buffers(
10499        &mut self,
10500        buffers: Vec<Entity<Buffer>>,
10501        also_stop_servers: HashSet<LanguageServerSelector>,
10502        cx: &mut Context<Self>,
10503    ) -> Task<Result<()>> {
10504        if let Some((client, project_id)) = self.upstream_client() {
10505            let request = client.request(proto::StopLanguageServers {
10506                project_id,
10507                buffer_ids: buffers
10508                    .into_iter()
10509                    .map(|b| b.read(cx).remote_id().to_proto())
10510                    .collect(),
10511                also_servers: also_stop_servers
10512                    .into_iter()
10513                    .map(|selector| {
10514                        let selector = match selector {
10515                            LanguageServerSelector::Id(language_server_id) => {
10516                                proto::language_server_selector::Selector::ServerId(
10517                                    language_server_id.to_proto(),
10518                                )
10519                            }
10520                            LanguageServerSelector::Name(language_server_name) => {
10521                                proto::language_server_selector::Selector::Name(
10522                                    language_server_name.to_string(),
10523                                )
10524                            }
10525                        };
10526                        proto::LanguageServerSelector {
10527                            selector: Some(selector),
10528                        }
10529                    })
10530                    .collect(),
10531                all: false,
10532            });
10533            cx.background_spawn(async move {
10534                let _ = request.await?;
10535                Ok(())
10536            })
10537        } else {
10538            let task =
10539                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10540            cx.background_spawn(async move {
10541                task.await;
10542                Ok(())
10543            })
10544        }
10545    }
10546
10547    fn stop_local_language_servers_for_buffers(
10548        &mut self,
10549        buffers: &[Entity<Buffer>],
10550        also_stop_servers: HashSet<LanguageServerSelector>,
10551        cx: &mut Context<Self>,
10552    ) -> Task<()> {
10553        let Some(local) = self.as_local_mut() else {
10554            return Task::ready(());
10555        };
10556        let mut language_server_names_to_stop = BTreeSet::default();
10557        let mut language_servers_to_stop = also_stop_servers
10558            .into_iter()
10559            .flat_map(|selector| match selector {
10560                LanguageServerSelector::Id(id) => Some(id),
10561                LanguageServerSelector::Name(name) => {
10562                    language_server_names_to_stop.insert(name);
10563                    None
10564                }
10565            })
10566            .collect::<BTreeSet<_>>();
10567
10568        let mut covered_worktrees = HashSet::default();
10569        for buffer in buffers {
10570            buffer.update(cx, |buffer, cx| {
10571                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10572                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10573                    && covered_worktrees.insert(worktree_id)
10574                {
10575                    language_server_names_to_stop.retain(|name| {
10576                        let old_ids_count = language_servers_to_stop.len();
10577                        let all_language_servers_with_this_name = local
10578                            .language_server_ids
10579                            .iter()
10580                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10581                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10582                        old_ids_count == language_servers_to_stop.len()
10583                    });
10584                }
10585            });
10586        }
10587        for name in language_server_names_to_stop {
10588            language_servers_to_stop.extend(
10589                local
10590                    .language_server_ids
10591                    .iter()
10592                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10593            );
10594        }
10595
10596        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10597        let tasks = language_servers_to_stop
10598            .into_iter()
10599            .map(|server| self.stop_local_language_server(server, cx))
10600            .collect::<Vec<_>>();
10601
10602        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10603    }
10604
10605    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10606        let (worktree, relative_path) =
10607            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10608
10609        let project_path = ProjectPath {
10610            worktree_id: worktree.read(cx).id(),
10611            path: relative_path,
10612        };
10613
10614        Some(
10615            self.buffer_store()
10616                .read(cx)
10617                .get_by_path(&project_path)?
10618                .read(cx),
10619        )
10620    }
10621
10622    #[cfg(any(test, feature = "test-support"))]
10623    pub fn update_diagnostics(
10624        &mut self,
10625        server_id: LanguageServerId,
10626        diagnostics: lsp::PublishDiagnosticsParams,
10627        result_id: Option<String>,
10628        source_kind: DiagnosticSourceKind,
10629        disk_based_sources: &[String],
10630        cx: &mut Context<Self>,
10631    ) -> Result<()> {
10632        self.merge_lsp_diagnostics(
10633            source_kind,
10634            vec![DocumentDiagnosticsUpdate {
10635                diagnostics,
10636                result_id,
10637                server_id,
10638                disk_based_sources: Cow::Borrowed(disk_based_sources),
10639            }],
10640            |_, _, _| false,
10641            cx,
10642        )
10643    }
10644
10645    pub fn merge_lsp_diagnostics(
10646        &mut self,
10647        source_kind: DiagnosticSourceKind,
10648        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10649        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10650        cx: &mut Context<Self>,
10651    ) -> Result<()> {
10652        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10653        let updates = lsp_diagnostics
10654            .into_iter()
10655            .filter_map(|update| {
10656                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10657                Some(DocumentDiagnosticsUpdate {
10658                    diagnostics: self.lsp_to_document_diagnostics(
10659                        abs_path,
10660                        source_kind,
10661                        update.server_id,
10662                        update.diagnostics,
10663                        &update.disk_based_sources,
10664                    ),
10665                    result_id: update.result_id,
10666                    server_id: update.server_id,
10667                    disk_based_sources: update.disk_based_sources,
10668                })
10669            })
10670            .collect();
10671        self.merge_diagnostic_entries(updates, merge, cx)?;
10672        Ok(())
10673    }
10674
10675    fn lsp_to_document_diagnostics(
10676        &mut self,
10677        document_abs_path: PathBuf,
10678        source_kind: DiagnosticSourceKind,
10679        server_id: LanguageServerId,
10680        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10681        disk_based_sources: &[String],
10682    ) -> DocumentDiagnostics {
10683        let mut diagnostics = Vec::default();
10684        let mut primary_diagnostic_group_ids = HashMap::default();
10685        let mut sources_by_group_id = HashMap::default();
10686        let mut supporting_diagnostics = HashMap::default();
10687
10688        let adapter = self.language_server_adapter_for_id(server_id);
10689
10690        // Ensure that primary diagnostics are always the most severe
10691        lsp_diagnostics
10692            .diagnostics
10693            .sort_by_key(|item| item.severity);
10694
10695        for diagnostic in &lsp_diagnostics.diagnostics {
10696            let source = diagnostic.source.as_ref();
10697            let range = range_from_lsp(diagnostic.range);
10698            let is_supporting = diagnostic
10699                .related_information
10700                .as_ref()
10701                .is_some_and(|infos| {
10702                    infos.iter().any(|info| {
10703                        primary_diagnostic_group_ids.contains_key(&(
10704                            source,
10705                            diagnostic.code.clone(),
10706                            range_from_lsp(info.location.range),
10707                        ))
10708                    })
10709                });
10710
10711            let is_unnecessary = diagnostic
10712                .tags
10713                .as_ref()
10714                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10715
10716            let underline = self
10717                .language_server_adapter_for_id(server_id)
10718                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10719
10720            if is_supporting {
10721                supporting_diagnostics.insert(
10722                    (source, diagnostic.code.clone(), range),
10723                    (diagnostic.severity, is_unnecessary),
10724                );
10725            } else {
10726                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10727                let is_disk_based =
10728                    source.is_some_and(|source| disk_based_sources.contains(source));
10729
10730                sources_by_group_id.insert(group_id, source);
10731                primary_diagnostic_group_ids
10732                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10733
10734                diagnostics.push(DiagnosticEntry {
10735                    range,
10736                    diagnostic: Diagnostic {
10737                        source: diagnostic.source.clone(),
10738                        source_kind,
10739                        code: diagnostic.code.clone(),
10740                        code_description: diagnostic
10741                            .code_description
10742                            .as_ref()
10743                            .and_then(|d| d.href.clone()),
10744                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10745                        markdown: adapter.as_ref().and_then(|adapter| {
10746                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10747                        }),
10748                        message: diagnostic.message.trim().to_string(),
10749                        group_id,
10750                        is_primary: true,
10751                        is_disk_based,
10752                        is_unnecessary,
10753                        underline,
10754                        data: diagnostic.data.clone(),
10755                    },
10756                });
10757                if let Some(infos) = &diagnostic.related_information {
10758                    for info in infos {
10759                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10760                            let range = range_from_lsp(info.location.range);
10761                            diagnostics.push(DiagnosticEntry {
10762                                range,
10763                                diagnostic: Diagnostic {
10764                                    source: diagnostic.source.clone(),
10765                                    source_kind,
10766                                    code: diagnostic.code.clone(),
10767                                    code_description: diagnostic
10768                                        .code_description
10769                                        .as_ref()
10770                                        .and_then(|d| d.href.clone()),
10771                                    severity: DiagnosticSeverity::INFORMATION,
10772                                    markdown: adapter.as_ref().and_then(|adapter| {
10773                                        adapter.diagnostic_message_to_markdown(&info.message)
10774                                    }),
10775                                    message: info.message.trim().to_string(),
10776                                    group_id,
10777                                    is_primary: false,
10778                                    is_disk_based,
10779                                    is_unnecessary: false,
10780                                    underline,
10781                                    data: diagnostic.data.clone(),
10782                                },
10783                            });
10784                        }
10785                    }
10786                }
10787            }
10788        }
10789
10790        for entry in &mut diagnostics {
10791            let diagnostic = &mut entry.diagnostic;
10792            if !diagnostic.is_primary {
10793                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10794                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10795                    source,
10796                    diagnostic.code.clone(),
10797                    entry.range.clone(),
10798                )) {
10799                    if let Some(severity) = severity {
10800                        diagnostic.severity = severity;
10801                    }
10802                    diagnostic.is_unnecessary = is_unnecessary;
10803                }
10804            }
10805        }
10806
10807        DocumentDiagnostics {
10808            diagnostics,
10809            document_abs_path,
10810            version: lsp_diagnostics.version,
10811        }
10812    }
10813
10814    fn insert_newly_running_language_server(
10815        &mut self,
10816        adapter: Arc<CachedLspAdapter>,
10817        language_server: Arc<LanguageServer>,
10818        server_id: LanguageServerId,
10819        key: LanguageServerSeed,
10820        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10821        cx: &mut Context<Self>,
10822    ) {
10823        let Some(local) = self.as_local_mut() else {
10824            return;
10825        };
10826        // If the language server for this key doesn't match the server id, don't store the
10827        // server. Which will cause it to be dropped, killing the process
10828        if local
10829            .language_server_ids
10830            .get(&key)
10831            .map(|state| state.id != server_id)
10832            .unwrap_or(false)
10833        {
10834            return;
10835        }
10836
10837        // Update language_servers collection with Running variant of LanguageServerState
10838        // indicating that the server is up and running and ready
10839        let workspace_folders = workspace_folders.lock().clone();
10840        language_server.set_workspace_folders(workspace_folders);
10841
10842        let workspace_diagnostics_refresh_tasks = language_server
10843            .capabilities()
10844            .diagnostic_provider
10845            .and_then(|provider| {
10846                let workspace_refresher = lsp_workspace_diagnostics_refresh(
10847                    None,
10848                    provider.clone(),
10849                    language_server.clone(),
10850                    cx,
10851                )?;
10852                local
10853                    .language_server_dynamic_registrations
10854                    .entry(server_id)
10855                    .or_default()
10856                    .diagnostics
10857                    .entry(None)
10858                    .or_insert(provider);
10859                Some((None, workspace_refresher))
10860            })
10861            .into_iter()
10862            .collect();
10863        local.language_servers.insert(
10864            server_id,
10865            LanguageServerState::Running {
10866                workspace_diagnostics_refresh_tasks,
10867                adapter: adapter.clone(),
10868                server: language_server.clone(),
10869                simulate_disk_based_diagnostics_completion: None,
10870            },
10871        );
10872        local
10873            .languages
10874            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10875        if let Some(file_ops_caps) = language_server
10876            .capabilities()
10877            .workspace
10878            .as_ref()
10879            .and_then(|ws| ws.file_operations.as_ref())
10880        {
10881            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10882            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10883            if did_rename_caps.or(will_rename_caps).is_some() {
10884                let watcher = RenamePathsWatchedForServer::default()
10885                    .with_did_rename_patterns(did_rename_caps)
10886                    .with_will_rename_patterns(will_rename_caps);
10887                local
10888                    .language_server_paths_watched_for_rename
10889                    .insert(server_id, watcher);
10890            }
10891        }
10892
10893        self.language_server_statuses.insert(
10894            server_id,
10895            LanguageServerStatus {
10896                name: language_server.name(),
10897                pending_work: Default::default(),
10898                has_pending_diagnostic_updates: false,
10899                progress_tokens: Default::default(),
10900                worktree: Some(key.worktree_id),
10901            },
10902        );
10903
10904        cx.emit(LspStoreEvent::LanguageServerAdded(
10905            server_id,
10906            language_server.name(),
10907            Some(key.worktree_id),
10908        ));
10909        cx.emit(LspStoreEvent::RefreshInlayHints(server_id));
10910
10911        let server_capabilities = language_server.capabilities();
10912        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10913            downstream_client
10914                .send(proto::StartLanguageServer {
10915                    project_id: *project_id,
10916                    server: Some(proto::LanguageServer {
10917                        id: server_id.to_proto(),
10918                        name: language_server.name().to_string(),
10919                        worktree_id: Some(key.worktree_id.to_proto()),
10920                    }),
10921                    capabilities: serde_json::to_string(&server_capabilities)
10922                        .expect("serializing server LSP capabilities"),
10923                })
10924                .log_err();
10925        }
10926        self.lsp_server_capabilities
10927            .insert(server_id, server_capabilities);
10928
10929        // Tell the language server about every open buffer in the worktree that matches the language.
10930        // Also check for buffers in worktrees that reused this server
10931        let mut worktrees_using_server = vec![key.worktree_id];
10932        if let Some(local) = self.as_local() {
10933            // Find all worktrees that have this server in their language server tree
10934            for (worktree_id, servers) in &local.lsp_tree.instances {
10935                if *worktree_id != key.worktree_id {
10936                    for server_map in servers.roots.values() {
10937                        if server_map
10938                            .values()
10939                            .any(|(node, _)| node.id() == Some(server_id))
10940                        {
10941                            worktrees_using_server.push(*worktree_id);
10942                        }
10943                    }
10944                }
10945            }
10946        }
10947
10948        let mut buffer_paths_registered = Vec::new();
10949        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10950            let mut lsp_adapters = HashMap::default();
10951            for buffer_handle in buffer_store.buffers() {
10952                let buffer = buffer_handle.read(cx);
10953                let file = match File::from_dyn(buffer.file()) {
10954                    Some(file) => file,
10955                    None => continue,
10956                };
10957                let language = match buffer.language() {
10958                    Some(language) => language,
10959                    None => continue,
10960                };
10961
10962                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10963                    || !lsp_adapters
10964                        .entry(language.name())
10965                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
10966                        .iter()
10967                        .any(|a| a.name == key.name)
10968                {
10969                    continue;
10970                }
10971                // didOpen
10972                let file = match file.as_local() {
10973                    Some(file) => file,
10974                    None => continue,
10975                };
10976
10977                let local = self.as_local_mut().unwrap();
10978
10979                let buffer_id = buffer.remote_id();
10980                if local.registered_buffers.contains_key(&buffer_id) {
10981                    let versions = local
10982                        .buffer_snapshots
10983                        .entry(buffer_id)
10984                        .or_default()
10985                        .entry(server_id)
10986                        .and_modify(|_| {
10987                            assert!(
10988                            false,
10989                            "There should not be an existing snapshot for a newly inserted buffer"
10990                        )
10991                        })
10992                        .or_insert_with(|| {
10993                            vec![LspBufferSnapshot {
10994                                version: 0,
10995                                snapshot: buffer.text_snapshot(),
10996                            }]
10997                        });
10998
10999                    let snapshot = versions.last().unwrap();
11000                    let version = snapshot.version;
11001                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11002                    language_server.register_buffer(
11003                        uri,
11004                        adapter.language_id(&language.name()),
11005                        version,
11006                        buffer_handle.read(cx).text_with_original_line_endings(),
11007                    );
11008                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11009                    local
11010                        .buffers_opened_in_servers
11011                        .entry(buffer_id)
11012                        .or_default()
11013                        .insert(server_id);
11014                }
11015                buffer_handle.update(cx, |buffer, cx| {
11016                    buffer.set_completion_triggers(
11017                        server_id,
11018                        language_server
11019                            .capabilities()
11020                            .completion_provider
11021                            .as_ref()
11022                            .and_then(|provider| {
11023                                provider
11024                                    .trigger_characters
11025                                    .as_ref()
11026                                    .map(|characters| characters.iter().cloned().collect())
11027                            })
11028                            .unwrap_or_default(),
11029                        cx,
11030                    )
11031                });
11032            }
11033        });
11034
11035        for (buffer_id, abs_path) in buffer_paths_registered {
11036            cx.emit(LspStoreEvent::LanguageServerUpdate {
11037                language_server_id: server_id,
11038                name: Some(adapter.name()),
11039                message: proto::update_language_server::Variant::RegisteredForBuffer(
11040                    proto::RegisteredForBuffer {
11041                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11042                        buffer_id: buffer_id.to_proto(),
11043                    },
11044                ),
11045            });
11046        }
11047
11048        cx.notify();
11049    }
11050
11051    pub fn language_servers_running_disk_based_diagnostics(
11052        &self,
11053    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11054        self.language_server_statuses
11055            .iter()
11056            .filter_map(|(id, status)| {
11057                if status.has_pending_diagnostic_updates {
11058                    Some(*id)
11059                } else {
11060                    None
11061                }
11062            })
11063    }
11064
11065    pub(crate) fn cancel_language_server_work_for_buffers(
11066        &mut self,
11067        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11068        cx: &mut Context<Self>,
11069    ) {
11070        if let Some((client, project_id)) = self.upstream_client() {
11071            let request = client.request(proto::CancelLanguageServerWork {
11072                project_id,
11073                work: Some(proto::cancel_language_server_work::Work::Buffers(
11074                    proto::cancel_language_server_work::Buffers {
11075                        buffer_ids: buffers
11076                            .into_iter()
11077                            .map(|b| b.read(cx).remote_id().to_proto())
11078                            .collect(),
11079                    },
11080                )),
11081            });
11082            cx.background_spawn(request).detach_and_log_err(cx);
11083        } else if let Some(local) = self.as_local() {
11084            let servers = buffers
11085                .into_iter()
11086                .flat_map(|buffer| {
11087                    buffer.update(cx, |buffer, cx| {
11088                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11089                    })
11090                })
11091                .collect::<HashSet<_>>();
11092            for server_id in servers {
11093                self.cancel_language_server_work(server_id, None, cx);
11094            }
11095        }
11096    }
11097
11098    pub(crate) fn cancel_language_server_work(
11099        &mut self,
11100        server_id: LanguageServerId,
11101        token_to_cancel: Option<String>,
11102        cx: &mut Context<Self>,
11103    ) {
11104        if let Some(local) = self.as_local() {
11105            let status = self.language_server_statuses.get(&server_id);
11106            let server = local.language_servers.get(&server_id);
11107            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11108            {
11109                for (token, progress) in &status.pending_work {
11110                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11111                        && token != token_to_cancel
11112                    {
11113                        continue;
11114                    }
11115                    if progress.is_cancellable {
11116                        server
11117                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11118                                WorkDoneProgressCancelParams {
11119                                    token: lsp::NumberOrString::String(token.clone()),
11120                                },
11121                            )
11122                            .ok();
11123                    }
11124                }
11125            }
11126        } else if let Some((client, project_id)) = self.upstream_client() {
11127            let request = client.request(proto::CancelLanguageServerWork {
11128                project_id,
11129                work: Some(
11130                    proto::cancel_language_server_work::Work::LanguageServerWork(
11131                        proto::cancel_language_server_work::LanguageServerWork {
11132                            language_server_id: server_id.to_proto(),
11133                            token: token_to_cancel,
11134                        },
11135                    ),
11136                ),
11137            });
11138            cx.background_spawn(request).detach_and_log_err(cx);
11139        }
11140    }
11141
11142    fn register_supplementary_language_server(
11143        &mut self,
11144        id: LanguageServerId,
11145        name: LanguageServerName,
11146        server: Arc<LanguageServer>,
11147        cx: &mut Context<Self>,
11148    ) {
11149        if let Some(local) = self.as_local_mut() {
11150            local
11151                .supplementary_language_servers
11152                .insert(id, (name.clone(), server));
11153            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11154        }
11155    }
11156
11157    fn unregister_supplementary_language_server(
11158        &mut self,
11159        id: LanguageServerId,
11160        cx: &mut Context<Self>,
11161    ) {
11162        if let Some(local) = self.as_local_mut() {
11163            local.supplementary_language_servers.remove(&id);
11164            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11165        }
11166    }
11167
11168    pub(crate) fn supplementary_language_servers(
11169        &self,
11170    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11171        self.as_local().into_iter().flat_map(|local| {
11172            local
11173                .supplementary_language_servers
11174                .iter()
11175                .map(|(id, (name, _))| (*id, name.clone()))
11176        })
11177    }
11178
11179    pub fn language_server_adapter_for_id(
11180        &self,
11181        id: LanguageServerId,
11182    ) -> Option<Arc<CachedLspAdapter>> {
11183        self.as_local()
11184            .and_then(|local| local.language_servers.get(&id))
11185            .and_then(|language_server_state| match language_server_state {
11186                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11187                _ => None,
11188            })
11189    }
11190
11191    pub(super) fn update_local_worktree_language_servers(
11192        &mut self,
11193        worktree_handle: &Entity<Worktree>,
11194        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11195        cx: &mut Context<Self>,
11196    ) {
11197        if changes.is_empty() {
11198            return;
11199        }
11200
11201        let Some(local) = self.as_local() else { return };
11202
11203        local.prettier_store.update(cx, |prettier_store, cx| {
11204            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11205        });
11206
11207        let worktree_id = worktree_handle.read(cx).id();
11208        let mut language_server_ids = local
11209            .language_server_ids
11210            .iter()
11211            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11212            .collect::<Vec<_>>();
11213        language_server_ids.sort();
11214        language_server_ids.dedup();
11215
11216        // let abs_path = worktree_handle.read(cx).abs_path();
11217        for server_id in &language_server_ids {
11218            if let Some(LanguageServerState::Running { server, .. }) =
11219                local.language_servers.get(server_id)
11220                && let Some(watched_paths) = local
11221                    .language_server_watched_paths
11222                    .get(server_id)
11223                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11224            {
11225                let params = lsp::DidChangeWatchedFilesParams {
11226                    changes: changes
11227                        .iter()
11228                        .filter_map(|(path, _, change)| {
11229                            if !watched_paths.is_match(path.as_std_path()) {
11230                                return None;
11231                            }
11232                            let typ = match change {
11233                                PathChange::Loaded => return None,
11234                                PathChange::Added => lsp::FileChangeType::CREATED,
11235                                PathChange::Removed => lsp::FileChangeType::DELETED,
11236                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11237                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11238                            };
11239                            let uri = lsp::Uri::from_file_path(
11240                                worktree_handle.read(cx).absolutize(&path),
11241                            )
11242                            .ok()?;
11243                            Some(lsp::FileEvent { uri, typ })
11244                        })
11245                        .collect(),
11246                };
11247                if !params.changes.is_empty() {
11248                    server
11249                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11250                        .ok();
11251                }
11252            }
11253        }
11254        for (path, _, _) in changes {
11255            if let Some(file_name) = path.file_name()
11256                && local.watched_manifest_filenames.contains(file_name)
11257            {
11258                self.request_workspace_config_refresh();
11259                break;
11260            }
11261        }
11262    }
11263
11264    pub fn wait_for_remote_buffer(
11265        &mut self,
11266        id: BufferId,
11267        cx: &mut Context<Self>,
11268    ) -> Task<Result<Entity<Buffer>>> {
11269        self.buffer_store.update(cx, |buffer_store, cx| {
11270            buffer_store.wait_for_remote_buffer(id, cx)
11271        })
11272    }
11273
11274    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11275        let mut result = proto::Symbol {
11276            language_server_name: symbol.language_server_name.0.to_string(),
11277            source_worktree_id: symbol.source_worktree_id.to_proto(),
11278            language_server_id: symbol.source_language_server_id.to_proto(),
11279            name: symbol.name.clone(),
11280            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11281            start: Some(proto::PointUtf16 {
11282                row: symbol.range.start.0.row,
11283                column: symbol.range.start.0.column,
11284            }),
11285            end: Some(proto::PointUtf16 {
11286                row: symbol.range.end.0.row,
11287                column: symbol.range.end.0.column,
11288            }),
11289            worktree_id: Default::default(),
11290            path: Default::default(),
11291            signature: Default::default(),
11292        };
11293        match &symbol.path {
11294            SymbolLocation::InProject(path) => {
11295                result.worktree_id = path.worktree_id.to_proto();
11296                result.path = path.path.to_proto();
11297            }
11298            SymbolLocation::OutsideProject {
11299                abs_path,
11300                signature,
11301            } => {
11302                result.path = abs_path.to_string_lossy().into_owned();
11303                result.signature = signature.to_vec();
11304            }
11305        }
11306        result
11307    }
11308
11309    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11310        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11311        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11312        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11313
11314        let path = if serialized_symbol.signature.is_empty() {
11315            SymbolLocation::InProject(ProjectPath {
11316                worktree_id,
11317                path: RelPath::from_proto(&serialized_symbol.path)
11318                    .context("invalid symbol path")?,
11319            })
11320        } else {
11321            SymbolLocation::OutsideProject {
11322                abs_path: Path::new(&serialized_symbol.path).into(),
11323                signature: serialized_symbol
11324                    .signature
11325                    .try_into()
11326                    .map_err(|_| anyhow!("invalid signature"))?,
11327            }
11328        };
11329
11330        let start = serialized_symbol.start.context("invalid start")?;
11331        let end = serialized_symbol.end.context("invalid end")?;
11332        Ok(CoreSymbol {
11333            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11334            source_worktree_id,
11335            source_language_server_id: LanguageServerId::from_proto(
11336                serialized_symbol.language_server_id,
11337            ),
11338            path,
11339            name: serialized_symbol.name,
11340            range: Unclipped(PointUtf16::new(start.row, start.column))
11341                ..Unclipped(PointUtf16::new(end.row, end.column)),
11342            kind,
11343        })
11344    }
11345
11346    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11347        let mut serialized_completion = proto::Completion {
11348            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11349            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11350            new_text: completion.new_text.clone(),
11351            ..proto::Completion::default()
11352        };
11353        match &completion.source {
11354            CompletionSource::Lsp {
11355                insert_range,
11356                server_id,
11357                lsp_completion,
11358                lsp_defaults,
11359                resolved,
11360            } => {
11361                let (old_insert_start, old_insert_end) = insert_range
11362                    .as_ref()
11363                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11364                    .unzip();
11365
11366                serialized_completion.old_insert_start = old_insert_start;
11367                serialized_completion.old_insert_end = old_insert_end;
11368                serialized_completion.source = proto::completion::Source::Lsp as i32;
11369                serialized_completion.server_id = server_id.0 as u64;
11370                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11371                serialized_completion.lsp_defaults = lsp_defaults
11372                    .as_deref()
11373                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11374                serialized_completion.resolved = *resolved;
11375            }
11376            CompletionSource::BufferWord {
11377                word_range,
11378                resolved,
11379            } => {
11380                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11381                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11382                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11383                serialized_completion.resolved = *resolved;
11384            }
11385            CompletionSource::Custom => {
11386                serialized_completion.source = proto::completion::Source::Custom as i32;
11387                serialized_completion.resolved = true;
11388            }
11389            CompletionSource::Dap { sort_text } => {
11390                serialized_completion.source = proto::completion::Source::Dap as i32;
11391                serialized_completion.sort_text = Some(sort_text.clone());
11392            }
11393        }
11394
11395        serialized_completion
11396    }
11397
11398    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11399        let old_replace_start = completion
11400            .old_replace_start
11401            .and_then(deserialize_anchor)
11402            .context("invalid old start")?;
11403        let old_replace_end = completion
11404            .old_replace_end
11405            .and_then(deserialize_anchor)
11406            .context("invalid old end")?;
11407        let insert_range = {
11408            match completion.old_insert_start.zip(completion.old_insert_end) {
11409                Some((start, end)) => {
11410                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11411                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11412                    Some(start..end)
11413                }
11414                None => None,
11415            }
11416        };
11417        Ok(CoreCompletion {
11418            replace_range: old_replace_start..old_replace_end,
11419            new_text: completion.new_text,
11420            source: match proto::completion::Source::from_i32(completion.source) {
11421                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11422                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11423                    insert_range,
11424                    server_id: LanguageServerId::from_proto(completion.server_id),
11425                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11426                    lsp_defaults: completion
11427                        .lsp_defaults
11428                        .as_deref()
11429                        .map(serde_json::from_slice)
11430                        .transpose()?,
11431                    resolved: completion.resolved,
11432                },
11433                Some(proto::completion::Source::BufferWord) => {
11434                    let word_range = completion
11435                        .buffer_word_start
11436                        .and_then(deserialize_anchor)
11437                        .context("invalid buffer word start")?
11438                        ..completion
11439                            .buffer_word_end
11440                            .and_then(deserialize_anchor)
11441                            .context("invalid buffer word end")?;
11442                    CompletionSource::BufferWord {
11443                        word_range,
11444                        resolved: completion.resolved,
11445                    }
11446                }
11447                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11448                    sort_text: completion
11449                        .sort_text
11450                        .context("expected sort text to exist")?,
11451                },
11452                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11453            },
11454        })
11455    }
11456
11457    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11458        let (kind, lsp_action) = match &action.lsp_action {
11459            LspAction::Action(code_action) => (
11460                proto::code_action::Kind::Action as i32,
11461                serde_json::to_vec(code_action).unwrap(),
11462            ),
11463            LspAction::Command(command) => (
11464                proto::code_action::Kind::Command as i32,
11465                serde_json::to_vec(command).unwrap(),
11466            ),
11467            LspAction::CodeLens(code_lens) => (
11468                proto::code_action::Kind::CodeLens as i32,
11469                serde_json::to_vec(code_lens).unwrap(),
11470            ),
11471        };
11472
11473        proto::CodeAction {
11474            server_id: action.server_id.0 as u64,
11475            start: Some(serialize_anchor(&action.range.start)),
11476            end: Some(serialize_anchor(&action.range.end)),
11477            lsp_action,
11478            kind,
11479            resolved: action.resolved,
11480        }
11481    }
11482
11483    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11484        let start = action
11485            .start
11486            .and_then(deserialize_anchor)
11487            .context("invalid start")?;
11488        let end = action
11489            .end
11490            .and_then(deserialize_anchor)
11491            .context("invalid end")?;
11492        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11493            Some(proto::code_action::Kind::Action) => {
11494                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11495            }
11496            Some(proto::code_action::Kind::Command) => {
11497                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11498            }
11499            Some(proto::code_action::Kind::CodeLens) => {
11500                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11501            }
11502            None => anyhow::bail!("Unknown action kind {}", action.kind),
11503        };
11504        Ok(CodeAction {
11505            server_id: LanguageServerId(action.server_id as usize),
11506            range: start..end,
11507            resolved: action.resolved,
11508            lsp_action,
11509        })
11510    }
11511
11512    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11513        match &formatting_result {
11514            Ok(_) => self.last_formatting_failure = None,
11515            Err(error) => {
11516                let error_string = format!("{error:#}");
11517                log::error!("Formatting failed: {error_string}");
11518                self.last_formatting_failure
11519                    .replace(error_string.lines().join(" "));
11520            }
11521        }
11522    }
11523
11524    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11525        self.lsp_server_capabilities.remove(&for_server);
11526        for lsp_data in self.lsp_data.values_mut() {
11527            lsp_data.remove_server_data(for_server);
11528        }
11529        if let Some(local) = self.as_local_mut() {
11530            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11531            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11532                buffer_servers.remove(&for_server);
11533            }
11534        }
11535    }
11536
11537    pub fn result_id(
11538        &self,
11539        server_id: LanguageServerId,
11540        buffer_id: BufferId,
11541        cx: &App,
11542    ) -> Option<String> {
11543        let abs_path = self
11544            .buffer_store
11545            .read(cx)
11546            .get(buffer_id)
11547            .and_then(|b| File::from_dyn(b.read(cx).file()))
11548            .map(|f| f.abs_path(cx))?;
11549        self.as_local()?
11550            .buffer_pull_diagnostics_result_ids
11551            .get(&server_id)?
11552            .get(&abs_path)?
11553            .clone()
11554    }
11555
11556    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11557        let Some(local) = self.as_local() else {
11558            return HashMap::default();
11559        };
11560        local
11561            .buffer_pull_diagnostics_result_ids
11562            .get(&server_id)
11563            .into_iter()
11564            .flatten()
11565            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11566            .collect()
11567    }
11568
11569    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11570        if let Some(LanguageServerState::Running {
11571            workspace_diagnostics_refresh_tasks,
11572            ..
11573        }) = self
11574            .as_local_mut()
11575            .and_then(|local| local.language_servers.get_mut(&server_id))
11576        {
11577            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11578                diagnostics.refresh_tx.try_send(()).ok();
11579            }
11580        }
11581    }
11582
11583    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11584        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11585            return;
11586        };
11587        let Some(local) = self.as_local_mut() else {
11588            return;
11589        };
11590
11591        for server_id in buffer.update(cx, |buffer, cx| {
11592            local.language_server_ids_for_buffer(buffer, cx)
11593        }) {
11594            if let Some(LanguageServerState::Running {
11595                workspace_diagnostics_refresh_tasks,
11596                ..
11597            }) = local.language_servers.get_mut(&server_id)
11598            {
11599                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11600                    diagnostics.refresh_tx.try_send(()).ok();
11601                }
11602            }
11603        }
11604    }
11605
11606    fn apply_workspace_diagnostic_report(
11607        &mut self,
11608        server_id: LanguageServerId,
11609        report: lsp::WorkspaceDiagnosticReportResult,
11610        cx: &mut Context<Self>,
11611    ) {
11612        let workspace_diagnostics =
11613            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11614        let mut unchanged_buffers = HashSet::default();
11615        let mut changed_buffers = HashSet::default();
11616        let workspace_diagnostics_updates = workspace_diagnostics
11617            .into_iter()
11618            .filter_map(
11619                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11620                    LspPullDiagnostics::Response {
11621                        server_id,
11622                        uri,
11623                        diagnostics,
11624                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11625                    LspPullDiagnostics::Default => None,
11626                },
11627            )
11628            .fold(
11629                HashMap::default(),
11630                |mut acc, (server_id, uri, diagnostics, version)| {
11631                    let (result_id, diagnostics) = match diagnostics {
11632                        PulledDiagnostics::Unchanged { result_id } => {
11633                            unchanged_buffers.insert(uri.clone());
11634                            (Some(result_id), Vec::new())
11635                        }
11636                        PulledDiagnostics::Changed {
11637                            result_id,
11638                            diagnostics,
11639                        } => {
11640                            changed_buffers.insert(uri.clone());
11641                            (result_id, diagnostics)
11642                        }
11643                    };
11644                    let disk_based_sources = Cow::Owned(
11645                        self.language_server_adapter_for_id(server_id)
11646                            .as_ref()
11647                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11648                            .unwrap_or(&[])
11649                            .to_vec(),
11650                    );
11651                    acc.entry(server_id)
11652                        .or_insert_with(Vec::new)
11653                        .push(DocumentDiagnosticsUpdate {
11654                            server_id,
11655                            diagnostics: lsp::PublishDiagnosticsParams {
11656                                uri,
11657                                diagnostics,
11658                                version,
11659                            },
11660                            result_id,
11661                            disk_based_sources,
11662                        });
11663                    acc
11664                },
11665            );
11666
11667        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11668            self.merge_lsp_diagnostics(
11669                DiagnosticSourceKind::Pulled,
11670                diagnostic_updates,
11671                |buffer, old_diagnostic, cx| {
11672                    File::from_dyn(buffer.file())
11673                        .and_then(|file| {
11674                            let abs_path = file.as_local()?.abs_path(cx);
11675                            lsp::Uri::from_file_path(abs_path).ok()
11676                        })
11677                        .is_none_or(|buffer_uri| {
11678                            unchanged_buffers.contains(&buffer_uri)
11679                                || match old_diagnostic.source_kind {
11680                                    DiagnosticSourceKind::Pulled => {
11681                                        !changed_buffers.contains(&buffer_uri)
11682                                    }
11683                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11684                                        true
11685                                    }
11686                                }
11687                        })
11688                },
11689                cx,
11690            )
11691            .log_err();
11692        }
11693    }
11694
11695    fn register_server_capabilities(
11696        &mut self,
11697        server_id: LanguageServerId,
11698        params: lsp::RegistrationParams,
11699        cx: &mut Context<Self>,
11700    ) -> anyhow::Result<()> {
11701        let server = self
11702            .language_server_for_id(server_id)
11703            .with_context(|| format!("no server {server_id} found"))?;
11704        for reg in params.registrations {
11705            match reg.method.as_str() {
11706                "workspace/didChangeWatchedFiles" => {
11707                    if let Some(options) = reg.register_options {
11708                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11709                            let caps = serde_json::from_value(options)?;
11710                            local_lsp_store
11711                                .on_lsp_did_change_watched_files(server_id, ®.id, caps, cx);
11712                            true
11713                        } else {
11714                            false
11715                        };
11716                        if notify {
11717                            notify_server_capabilities_updated(&server, cx);
11718                        }
11719                    }
11720                }
11721                "workspace/didChangeConfiguration" => {
11722                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11723                }
11724                "workspace/didChangeWorkspaceFolders" => {
11725                    // In this case register options is an empty object, we can ignore it
11726                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11727                        supported: Some(true),
11728                        change_notifications: Some(OneOf::Right(reg.id)),
11729                    };
11730                    server.update_capabilities(|capabilities| {
11731                        capabilities
11732                            .workspace
11733                            .get_or_insert_default()
11734                            .workspace_folders = Some(caps);
11735                    });
11736                    notify_server_capabilities_updated(&server, cx);
11737                }
11738                "workspace/symbol" => {
11739                    let options = parse_register_capabilities(reg)?;
11740                    server.update_capabilities(|capabilities| {
11741                        capabilities.workspace_symbol_provider = Some(options);
11742                    });
11743                    notify_server_capabilities_updated(&server, cx);
11744                }
11745                "workspace/fileOperations" => {
11746                    if let Some(options) = reg.register_options {
11747                        let caps = serde_json::from_value(options)?;
11748                        server.update_capabilities(|capabilities| {
11749                            capabilities
11750                                .workspace
11751                                .get_or_insert_default()
11752                                .file_operations = Some(caps);
11753                        });
11754                        notify_server_capabilities_updated(&server, cx);
11755                    }
11756                }
11757                "workspace/executeCommand" => {
11758                    if let Some(options) = reg.register_options {
11759                        let options = serde_json::from_value(options)?;
11760                        server.update_capabilities(|capabilities| {
11761                            capabilities.execute_command_provider = Some(options);
11762                        });
11763                        notify_server_capabilities_updated(&server, cx);
11764                    }
11765                }
11766                "textDocument/rangeFormatting" => {
11767                    let options = parse_register_capabilities(reg)?;
11768                    server.update_capabilities(|capabilities| {
11769                        capabilities.document_range_formatting_provider = Some(options);
11770                    });
11771                    notify_server_capabilities_updated(&server, cx);
11772                }
11773                "textDocument/onTypeFormatting" => {
11774                    if let Some(options) = reg
11775                        .register_options
11776                        .map(serde_json::from_value)
11777                        .transpose()?
11778                    {
11779                        server.update_capabilities(|capabilities| {
11780                            capabilities.document_on_type_formatting_provider = Some(options);
11781                        });
11782                        notify_server_capabilities_updated(&server, cx);
11783                    }
11784                }
11785                "textDocument/formatting" => {
11786                    let options = parse_register_capabilities(reg)?;
11787                    server.update_capabilities(|capabilities| {
11788                        capabilities.document_formatting_provider = Some(options);
11789                    });
11790                    notify_server_capabilities_updated(&server, cx);
11791                }
11792                "textDocument/rename" => {
11793                    let options = parse_register_capabilities(reg)?;
11794                    server.update_capabilities(|capabilities| {
11795                        capabilities.rename_provider = Some(options);
11796                    });
11797                    notify_server_capabilities_updated(&server, cx);
11798                }
11799                "textDocument/inlayHint" => {
11800                    let options = parse_register_capabilities(reg)?;
11801                    server.update_capabilities(|capabilities| {
11802                        capabilities.inlay_hint_provider = Some(options);
11803                    });
11804                    notify_server_capabilities_updated(&server, cx);
11805                }
11806                "textDocument/documentSymbol" => {
11807                    let options = parse_register_capabilities(reg)?;
11808                    server.update_capabilities(|capabilities| {
11809                        capabilities.document_symbol_provider = Some(options);
11810                    });
11811                    notify_server_capabilities_updated(&server, cx);
11812                }
11813                "textDocument/codeAction" => {
11814                    let options = parse_register_capabilities(reg)?;
11815                    let provider = match options {
11816                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11817                        OneOf::Right(caps) => caps,
11818                    };
11819                    server.update_capabilities(|capabilities| {
11820                        capabilities.code_action_provider = Some(provider);
11821                    });
11822                    notify_server_capabilities_updated(&server, cx);
11823                }
11824                "textDocument/definition" => {
11825                    let options = parse_register_capabilities(reg)?;
11826                    server.update_capabilities(|capabilities| {
11827                        capabilities.definition_provider = Some(options);
11828                    });
11829                    notify_server_capabilities_updated(&server, cx);
11830                }
11831                "textDocument/completion" => {
11832                    if let Some(caps) = reg
11833                        .register_options
11834                        .map(serde_json::from_value)
11835                        .transpose()?
11836                    {
11837                        server.update_capabilities(|capabilities| {
11838                            capabilities.completion_provider = Some(caps);
11839                        });
11840                        notify_server_capabilities_updated(&server, cx);
11841                    }
11842                }
11843                "textDocument/hover" => {
11844                    let options = parse_register_capabilities(reg)?;
11845                    let provider = match options {
11846                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11847                        OneOf::Right(caps) => caps,
11848                    };
11849                    server.update_capabilities(|capabilities| {
11850                        capabilities.hover_provider = Some(provider);
11851                    });
11852                    notify_server_capabilities_updated(&server, cx);
11853                }
11854                "textDocument/signatureHelp" => {
11855                    if let Some(caps) = reg
11856                        .register_options
11857                        .map(serde_json::from_value)
11858                        .transpose()?
11859                    {
11860                        server.update_capabilities(|capabilities| {
11861                            capabilities.signature_help_provider = Some(caps);
11862                        });
11863                        notify_server_capabilities_updated(&server, cx);
11864                    }
11865                }
11866                "textDocument/didChange" => {
11867                    if let Some(sync_kind) = reg
11868                        .register_options
11869                        .and_then(|opts| opts.get("syncKind").cloned())
11870                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11871                        .transpose()?
11872                    {
11873                        server.update_capabilities(|capabilities| {
11874                            let mut sync_options =
11875                                Self::take_text_document_sync_options(capabilities);
11876                            sync_options.change = Some(sync_kind);
11877                            capabilities.text_document_sync =
11878                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11879                        });
11880                        notify_server_capabilities_updated(&server, cx);
11881                    }
11882                }
11883                "textDocument/didSave" => {
11884                    if let Some(include_text) = reg
11885                        .register_options
11886                        .map(|opts| {
11887                            let transpose = opts
11888                                .get("includeText")
11889                                .cloned()
11890                                .map(serde_json::from_value::<Option<bool>>)
11891                                .transpose();
11892                            match transpose {
11893                                Ok(value) => Ok(value.flatten()),
11894                                Err(e) => Err(e),
11895                            }
11896                        })
11897                        .transpose()?
11898                    {
11899                        server.update_capabilities(|capabilities| {
11900                            let mut sync_options =
11901                                Self::take_text_document_sync_options(capabilities);
11902                            sync_options.save =
11903                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11904                                    include_text,
11905                                }));
11906                            capabilities.text_document_sync =
11907                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11908                        });
11909                        notify_server_capabilities_updated(&server, cx);
11910                    }
11911                }
11912                "textDocument/codeLens" => {
11913                    if let Some(caps) = reg
11914                        .register_options
11915                        .map(serde_json::from_value)
11916                        .transpose()?
11917                    {
11918                        server.update_capabilities(|capabilities| {
11919                            capabilities.code_lens_provider = Some(caps);
11920                        });
11921                        notify_server_capabilities_updated(&server, cx);
11922                    }
11923                }
11924                "textDocument/diagnostic" => {
11925                    if let Some(caps) = reg
11926                        .register_options
11927                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
11928                        .transpose()?
11929                    {
11930                        let local = self
11931                            .as_local_mut()
11932                            .context("Expected LSP Store to be local")?;
11933                        let state = local
11934                            .language_servers
11935                            .get_mut(&server_id)
11936                            .context("Could not obtain Language Servers state")?;
11937                        local
11938                            .language_server_dynamic_registrations
11939                            .get_mut(&server_id)
11940                            .and_then(|registrations| {
11941                                registrations
11942                                    .diagnostics
11943                                    .insert(Some(reg.id.clone()), caps.clone())
11944                            });
11945
11946                        let mut can_now_provide_diagnostics = false;
11947                        if let LanguageServerState::Running {
11948                            workspace_diagnostics_refresh_tasks,
11949                            ..
11950                        } = state
11951                            && let Some(task) = lsp_workspace_diagnostics_refresh(
11952                                Some(reg.id.clone()),
11953                                caps.clone(),
11954                                server.clone(),
11955                                cx,
11956                            )
11957                        {
11958                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
11959                            can_now_provide_diagnostics = true;
11960                        }
11961
11962                        // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
11963                        // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
11964                        // as it'll think that they're not supported.
11965                        if can_now_provide_diagnostics {
11966                            server.update_capabilities(|capabilities| {
11967                                debug_assert!(capabilities.diagnostic_provider.is_none());
11968                                capabilities.diagnostic_provider = Some(caps);
11969                            });
11970                        }
11971
11972                        notify_server_capabilities_updated(&server, cx);
11973                    }
11974                }
11975                "textDocument/documentColor" => {
11976                    let options = parse_register_capabilities(reg)?;
11977                    let provider = match options {
11978                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
11979                        OneOf::Right(caps) => caps,
11980                    };
11981                    server.update_capabilities(|capabilities| {
11982                        capabilities.color_provider = Some(provider);
11983                    });
11984                    notify_server_capabilities_updated(&server, cx);
11985                }
11986                _ => log::warn!("unhandled capability registration: {reg:?}"),
11987            }
11988        }
11989
11990        Ok(())
11991    }
11992
11993    fn unregister_server_capabilities(
11994        &mut self,
11995        server_id: LanguageServerId,
11996        params: lsp::UnregistrationParams,
11997        cx: &mut Context<Self>,
11998    ) -> anyhow::Result<()> {
11999        let server = self
12000            .language_server_for_id(server_id)
12001            .with_context(|| format!("no server {server_id} found"))?;
12002        for unreg in params.unregisterations.iter() {
12003            match unreg.method.as_str() {
12004                "workspace/didChangeWatchedFiles" => {
12005                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12006                        local_lsp_store
12007                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12008                        true
12009                    } else {
12010                        false
12011                    };
12012                    if notify {
12013                        notify_server_capabilities_updated(&server, cx);
12014                    }
12015                }
12016                "workspace/didChangeConfiguration" => {
12017                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12018                }
12019                "workspace/didChangeWorkspaceFolders" => {
12020                    server.update_capabilities(|capabilities| {
12021                        capabilities
12022                            .workspace
12023                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12024                                workspace_folders: None,
12025                                file_operations: None,
12026                            })
12027                            .workspace_folders = None;
12028                    });
12029                    notify_server_capabilities_updated(&server, cx);
12030                }
12031                "workspace/symbol" => {
12032                    server.update_capabilities(|capabilities| {
12033                        capabilities.workspace_symbol_provider = None
12034                    });
12035                    notify_server_capabilities_updated(&server, cx);
12036                }
12037                "workspace/fileOperations" => {
12038                    server.update_capabilities(|capabilities| {
12039                        capabilities
12040                            .workspace
12041                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12042                                workspace_folders: None,
12043                                file_operations: None,
12044                            })
12045                            .file_operations = None;
12046                    });
12047                    notify_server_capabilities_updated(&server, cx);
12048                }
12049                "workspace/executeCommand" => {
12050                    server.update_capabilities(|capabilities| {
12051                        capabilities.execute_command_provider = None;
12052                    });
12053                    notify_server_capabilities_updated(&server, cx);
12054                }
12055                "textDocument/rangeFormatting" => {
12056                    server.update_capabilities(|capabilities| {
12057                        capabilities.document_range_formatting_provider = None
12058                    });
12059                    notify_server_capabilities_updated(&server, cx);
12060                }
12061                "textDocument/onTypeFormatting" => {
12062                    server.update_capabilities(|capabilities| {
12063                        capabilities.document_on_type_formatting_provider = None;
12064                    });
12065                    notify_server_capabilities_updated(&server, cx);
12066                }
12067                "textDocument/formatting" => {
12068                    server.update_capabilities(|capabilities| {
12069                        capabilities.document_formatting_provider = None;
12070                    });
12071                    notify_server_capabilities_updated(&server, cx);
12072                }
12073                "textDocument/rename" => {
12074                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12075                    notify_server_capabilities_updated(&server, cx);
12076                }
12077                "textDocument/codeAction" => {
12078                    server.update_capabilities(|capabilities| {
12079                        capabilities.code_action_provider = None;
12080                    });
12081                    notify_server_capabilities_updated(&server, cx);
12082                }
12083                "textDocument/definition" => {
12084                    server.update_capabilities(|capabilities| {
12085                        capabilities.definition_provider = None;
12086                    });
12087                    notify_server_capabilities_updated(&server, cx);
12088                }
12089                "textDocument/completion" => {
12090                    server.update_capabilities(|capabilities| {
12091                        capabilities.completion_provider = None;
12092                    });
12093                    notify_server_capabilities_updated(&server, cx);
12094                }
12095                "textDocument/hover" => {
12096                    server.update_capabilities(|capabilities| {
12097                        capabilities.hover_provider = None;
12098                    });
12099                    notify_server_capabilities_updated(&server, cx);
12100                }
12101                "textDocument/signatureHelp" => {
12102                    server.update_capabilities(|capabilities| {
12103                        capabilities.signature_help_provider = None;
12104                    });
12105                    notify_server_capabilities_updated(&server, cx);
12106                }
12107                "textDocument/didChange" => {
12108                    server.update_capabilities(|capabilities| {
12109                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12110                        sync_options.change = None;
12111                        capabilities.text_document_sync =
12112                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12113                    });
12114                    notify_server_capabilities_updated(&server, cx);
12115                }
12116                "textDocument/didSave" => {
12117                    server.update_capabilities(|capabilities| {
12118                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12119                        sync_options.save = None;
12120                        capabilities.text_document_sync =
12121                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12122                    });
12123                    notify_server_capabilities_updated(&server, cx);
12124                }
12125                "textDocument/codeLens" => {
12126                    server.update_capabilities(|capabilities| {
12127                        capabilities.code_lens_provider = None;
12128                    });
12129                    notify_server_capabilities_updated(&server, cx);
12130                }
12131                "textDocument/diagnostic" => {
12132                    let local = self
12133                        .as_local_mut()
12134                        .context("Expected LSP Store to be local")?;
12135
12136                    let state = local
12137                        .language_servers
12138                        .get_mut(&server_id)
12139                        .context("Could not obtain Language Servers state")?;
12140                    let options = local
12141                        .language_server_dynamic_registrations
12142                        .get_mut(&server_id)
12143                        .with_context(|| {
12144                            format!("Expected dynamic registration to exist for server {server_id}")
12145                        })?.diagnostics
12146                        .remove(&Some(unreg.id.clone()))
12147                        .with_context(|| format!(
12148                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12149                            unreg.id)
12150                        )?;
12151
12152                    let mut has_any_diagnostic_providers_still = true;
12153                    if let Some(identifier) = diagnostic_identifier(&options)
12154                        && let LanguageServerState::Running {
12155                            workspace_diagnostics_refresh_tasks,
12156                            ..
12157                        } = state
12158                    {
12159                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12160                        has_any_diagnostic_providers_still =
12161                            !workspace_diagnostics_refresh_tasks.is_empty();
12162                    }
12163
12164                    if !has_any_diagnostic_providers_still {
12165                        server.update_capabilities(|capabilities| {
12166                            debug_assert!(capabilities.diagnostic_provider.is_some());
12167                            capabilities.diagnostic_provider = None;
12168                        });
12169                    }
12170
12171                    notify_server_capabilities_updated(&server, cx);
12172                }
12173                "textDocument/documentColor" => {
12174                    server.update_capabilities(|capabilities| {
12175                        capabilities.color_provider = None;
12176                    });
12177                    notify_server_capabilities_updated(&server, cx);
12178                }
12179                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12180            }
12181        }
12182
12183        Ok(())
12184    }
12185
12186    async fn deduplicate_range_based_lsp_requests<T>(
12187        lsp_store: &Entity<Self>,
12188        server_id: Option<LanguageServerId>,
12189        lsp_request_id: LspRequestId,
12190        proto_request: &T::ProtoRequest,
12191        range: Range<Anchor>,
12192        cx: &mut AsyncApp,
12193    ) -> Result<()>
12194    where
12195        T: LspCommand,
12196        T::ProtoRequest: proto::LspRequestMessage,
12197    {
12198        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12199        let version = deserialize_version(proto_request.buffer_version());
12200        let buffer = lsp_store.update(cx, |this, cx| {
12201            this.buffer_store.read(cx).get_existing(buffer_id)
12202        })??;
12203        buffer
12204            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12205            .await?;
12206        lsp_store.update(cx, |lsp_store, cx| {
12207            let lsp_data = lsp_store
12208                .lsp_data
12209                .entry(buffer_id)
12210                .or_insert_with(|| BufferLspData::new(&buffer, cx));
12211            let chunks_queried_for = lsp_data
12212                .inlay_hints
12213                .applicable_chunks(&[range])
12214                .collect::<Vec<_>>();
12215            match chunks_queried_for.as_slice() {
12216                &[chunk] => {
12217                    let key = LspKey {
12218                        request_type: TypeId::of::<T>(),
12219                        server_queried: server_id,
12220                    };
12221                    let previous_request = lsp_data
12222                        .chunk_lsp_requests
12223                        .entry(key)
12224                        .or_default()
12225                        .insert(chunk, lsp_request_id);
12226                    if let Some((previous_request, running_requests)) =
12227                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12228                    {
12229                        running_requests.remove(&previous_request);
12230                    }
12231                }
12232                _ambiguous_chunks => {
12233                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12234                    // there, a buffer version-based check will be performed and outdated requests discarded.
12235                }
12236            }
12237            anyhow::Ok(())
12238        })??;
12239
12240        Ok(())
12241    }
12242
12243    async fn query_lsp_locally<T>(
12244        lsp_store: Entity<Self>,
12245        for_server_id: Option<LanguageServerId>,
12246        sender_id: proto::PeerId,
12247        lsp_request_id: LspRequestId,
12248        proto_request: T::ProtoRequest,
12249        position: Option<Anchor>,
12250        cx: &mut AsyncApp,
12251    ) -> Result<()>
12252    where
12253        T: LspCommand + Clone,
12254        T::ProtoRequest: proto::LspRequestMessage,
12255        <T::ProtoRequest as proto::RequestMessage>::Response:
12256            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12257    {
12258        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12259        let version = deserialize_version(proto_request.buffer_version());
12260        let buffer = lsp_store.update(cx, |this, cx| {
12261            this.buffer_store.read(cx).get_existing(buffer_id)
12262        })??;
12263        buffer
12264            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12265            .await?;
12266        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12267        let request =
12268            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12269        let key = LspKey {
12270            request_type: TypeId::of::<T>(),
12271            server_queried: for_server_id,
12272        };
12273        lsp_store.update(cx, |lsp_store, cx| {
12274            let request_task = match for_server_id {
12275                Some(server_id) => {
12276                    let server_task = lsp_store.request_lsp(
12277                        buffer.clone(),
12278                        LanguageServerToQuery::Other(server_id),
12279                        request.clone(),
12280                        cx,
12281                    );
12282                    cx.background_spawn(async move {
12283                        let mut responses = Vec::new();
12284                        match server_task.await {
12285                            Ok(response) => responses.push((server_id, response)),
12286                            Err(e) => log::error!(
12287                                "Error handling response for request {request:?}: {e:#}"
12288                            ),
12289                        }
12290                        responses
12291                    })
12292                }
12293                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12294            };
12295            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12296            if T::ProtoRequest::stop_previous_requests() {
12297                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12298                    lsp_requests.clear();
12299                }
12300            }
12301            lsp_data.lsp_requests.entry(key).or_default().insert(
12302                lsp_request_id,
12303                cx.spawn(async move |lsp_store, cx| {
12304                    let response = request_task.await;
12305                    lsp_store
12306                        .update(cx, |lsp_store, cx| {
12307                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12308                            {
12309                                let response = response
12310                                    .into_iter()
12311                                    .map(|(server_id, response)| {
12312                                        (
12313                                            server_id.to_proto(),
12314                                            T::response_to_proto(
12315                                                response,
12316                                                lsp_store,
12317                                                sender_id,
12318                                                &buffer_version,
12319                                                cx,
12320                                            )
12321                                            .into(),
12322                                        )
12323                                    })
12324                                    .collect::<HashMap<_, _>>();
12325                                match client.send_lsp_response::<T::ProtoRequest>(
12326                                    project_id,
12327                                    lsp_request_id,
12328                                    response,
12329                                ) {
12330                                    Ok(()) => {}
12331                                    Err(e) => {
12332                                        log::error!("Failed to send LSP response: {e:#}",)
12333                                    }
12334                                }
12335                            }
12336                        })
12337                        .ok();
12338                }),
12339            );
12340        })?;
12341        Ok(())
12342    }
12343
12344    fn take_text_document_sync_options(
12345        capabilities: &mut lsp::ServerCapabilities,
12346    ) -> lsp::TextDocumentSyncOptions {
12347        match capabilities.text_document_sync.take() {
12348            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12349            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12350                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12351                sync_options.change = Some(sync_kind);
12352                sync_options
12353            }
12354            None => lsp::TextDocumentSyncOptions::default(),
12355        }
12356    }
12357
12358    #[cfg(any(test, feature = "test-support"))]
12359    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12360        Some(
12361            self.lsp_data
12362                .get_mut(&buffer_id)?
12363                .code_lens
12364                .take()?
12365                .update
12366                .take()?
12367                .1,
12368        )
12369    }
12370
12371    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12372        self.downstream_client.clone()
12373    }
12374
12375    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12376        self.worktree_store.clone()
12377    }
12378
12379    /// Gets what's stored in the LSP data for the given buffer.
12380    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12381        self.lsp_data.get_mut(&buffer_id)
12382    }
12383
12384    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12385    /// new [`BufferLspData`] will be created to replace the previous state.
12386    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12387        let (buffer_id, buffer_version) =
12388            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12389        let lsp_data = self
12390            .lsp_data
12391            .entry(buffer_id)
12392            .or_insert_with(|| BufferLspData::new(buffer, cx));
12393        if buffer_version.changed_since(&lsp_data.buffer_version) {
12394            *lsp_data = BufferLspData::new(buffer, cx);
12395        }
12396        lsp_data
12397    }
12398}
12399
12400// Registration with registerOptions as null, should fallback to true.
12401// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12402fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12403    reg: lsp::Registration,
12404) -> Result<OneOf<bool, T>> {
12405    Ok(match reg.register_options {
12406        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12407        None => OneOf::Left(true),
12408    })
12409}
12410
12411fn subscribe_to_binary_statuses(
12412    languages: &Arc<LanguageRegistry>,
12413    cx: &mut Context<'_, LspStore>,
12414) -> Task<()> {
12415    let mut server_statuses = languages.language_server_binary_statuses();
12416    cx.spawn(async move |lsp_store, cx| {
12417        while let Some((server_name, binary_status)) = server_statuses.next().await {
12418            if lsp_store
12419                .update(cx, |_, cx| {
12420                    let mut message = None;
12421                    let binary_status = match binary_status {
12422                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12423                        BinaryStatus::CheckingForUpdate => {
12424                            proto::ServerBinaryStatus::CheckingForUpdate
12425                        }
12426                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12427                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12428                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12429                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12430                        BinaryStatus::Failed { error } => {
12431                            message = Some(error);
12432                            proto::ServerBinaryStatus::Failed
12433                        }
12434                    };
12435                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12436                        // Binary updates are about the binary that might not have any language server id at that point.
12437                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12438                        language_server_id: LanguageServerId(0),
12439                        name: Some(server_name),
12440                        message: proto::update_language_server::Variant::StatusUpdate(
12441                            proto::StatusUpdate {
12442                                message,
12443                                status: Some(proto::status_update::Status::Binary(
12444                                    binary_status as i32,
12445                                )),
12446                            },
12447                        ),
12448                    });
12449                })
12450                .is_err()
12451            {
12452                break;
12453            }
12454        }
12455    })
12456}
12457
12458fn lsp_workspace_diagnostics_refresh(
12459    registration_id: Option<String>,
12460    options: DiagnosticServerCapabilities,
12461    server: Arc<LanguageServer>,
12462    cx: &mut Context<'_, LspStore>,
12463) -> Option<WorkspaceRefreshTask> {
12464    let identifier = diagnostic_identifier(&options)?;
12465
12466    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12467    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12468    refresh_tx.try_send(()).ok();
12469
12470    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12471        let mut attempts = 0;
12472        let max_attempts = 50;
12473        let mut requests = 0;
12474
12475        loop {
12476            let Some(()) = refresh_rx.recv().await else {
12477                return;
12478            };
12479
12480            'request: loop {
12481                requests += 1;
12482                if attempts > max_attempts {
12483                    log::error!(
12484                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12485                    );
12486                    return;
12487                }
12488                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12489                cx.background_executor()
12490                    .timer(Duration::from_millis(backoff_millis))
12491                    .await;
12492                attempts += 1;
12493
12494                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12495                    lsp_store
12496                        .all_result_ids(server.server_id())
12497                        .into_iter()
12498                        .filter_map(|(abs_path, result_id)| {
12499                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12500                            Some(lsp::PreviousResultId {
12501                                uri,
12502                                value: result_id,
12503                            })
12504                        })
12505                        .collect()
12506                }) else {
12507                    return;
12508                };
12509
12510                let token = if let Some(identifier) = ®istration_id {
12511                    format!(
12512                        "workspace/diagnostic/{}/{requests}/id:{identifier}",
12513                        server.server_id(),
12514                    )
12515                } else {
12516                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12517                };
12518
12519                progress_rx.try_recv().ok();
12520                let timer =
12521                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12522                let progress = pin!(progress_rx.recv().fuse());
12523                let response_result = server
12524                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12525                        lsp::WorkspaceDiagnosticParams {
12526                            previous_result_ids,
12527                            identifier: identifier.clone(),
12528                            work_done_progress_params: Default::default(),
12529                            partial_result_params: lsp::PartialResultParams {
12530                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12531                            },
12532                        },
12533                        select(timer, progress).then(|either| match either {
12534                            Either::Left((message, ..)) => ready(message).left_future(),
12535                            Either::Right(..) => pending::<String>().right_future(),
12536                        }),
12537                    )
12538                    .await;
12539
12540                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12541                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12542                match response_result {
12543                    ConnectionResult::Timeout => {
12544                        log::error!("Timeout during workspace diagnostics pull");
12545                        continue 'request;
12546                    }
12547                    ConnectionResult::ConnectionReset => {
12548                        log::error!("Server closed a workspace diagnostics pull request");
12549                        continue 'request;
12550                    }
12551                    ConnectionResult::Result(Err(e)) => {
12552                        log::error!("Error during workspace diagnostics pull: {e:#}");
12553                        break 'request;
12554                    }
12555                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12556                        attempts = 0;
12557                        if lsp_store
12558                            .update(cx, |lsp_store, cx| {
12559                                lsp_store.apply_workspace_diagnostic_report(
12560                                    server.server_id(),
12561                                    pulled_diagnostics,
12562                                    cx,
12563                                )
12564                            })
12565                            .is_err()
12566                        {
12567                            return;
12568                        }
12569                        break 'request;
12570                    }
12571                }
12572            }
12573        }
12574    });
12575
12576    Some(WorkspaceRefreshTask {
12577        refresh_tx,
12578        progress_tx,
12579        task: workspace_query_language_server,
12580    })
12581}
12582
12583fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12584    match &options {
12585        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12586            if !diagnostic_options.workspace_diagnostics {
12587                return None;
12588            }
12589            Some(diagnostic_options.identifier.clone())
12590        }
12591        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12592            let diagnostic_options = ®istration_options.diagnostic_options;
12593            if !diagnostic_options.workspace_diagnostics {
12594                return None;
12595            }
12596            Some(diagnostic_options.identifier.clone())
12597        }
12598    }
12599}
12600
12601fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12602    let CompletionSource::BufferWord {
12603        word_range,
12604        resolved,
12605    } = &mut completion.source
12606    else {
12607        return;
12608    };
12609    if *resolved {
12610        return;
12611    }
12612
12613    if completion.new_text
12614        != snapshot
12615            .text_for_range(word_range.clone())
12616            .collect::<String>()
12617    {
12618        return;
12619    }
12620
12621    let mut offset = 0;
12622    for chunk in snapshot.chunks(word_range.clone(), true) {
12623        let end_offset = offset + chunk.text.len();
12624        if let Some(highlight_id) = chunk.syntax_highlight_id {
12625            completion
12626                .label
12627                .runs
12628                .push((offset..end_offset, highlight_id));
12629        }
12630        offset = end_offset;
12631    }
12632    *resolved = true;
12633}
12634
12635impl EventEmitter<LspStoreEvent> for LspStore {}
12636
12637fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12638    hover
12639        .contents
12640        .retain(|hover_block| !hover_block.text.trim().is_empty());
12641    if hover.contents.is_empty() {
12642        None
12643    } else {
12644        Some(hover)
12645    }
12646}
12647
12648async fn populate_labels_for_completions(
12649    new_completions: Vec<CoreCompletion>,
12650    language: Option<Arc<Language>>,
12651    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12652) -> Vec<Completion> {
12653    let lsp_completions = new_completions
12654        .iter()
12655        .filter_map(|new_completion| {
12656            new_completion
12657                .source
12658                .lsp_completion(true)
12659                .map(|lsp_completion| lsp_completion.into_owned())
12660        })
12661        .collect::<Vec<_>>();
12662
12663    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12664        lsp_adapter
12665            .labels_for_completions(&lsp_completions, language)
12666            .await
12667            .log_err()
12668            .unwrap_or_default()
12669    } else {
12670        Vec::new()
12671    }
12672    .into_iter()
12673    .fuse();
12674
12675    let mut completions = Vec::new();
12676    for completion in new_completions {
12677        match completion.source.lsp_completion(true) {
12678            Some(lsp_completion) => {
12679                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12680
12681                let mut label = labels.next().flatten().unwrap_or_else(|| {
12682                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12683                });
12684                ensure_uniform_list_compatible_label(&mut label);
12685                completions.push(Completion {
12686                    label,
12687                    documentation,
12688                    replace_range: completion.replace_range,
12689                    new_text: completion.new_text,
12690                    insert_text_mode: lsp_completion.insert_text_mode,
12691                    source: completion.source,
12692                    icon_path: None,
12693                    confirm: None,
12694                });
12695            }
12696            None => {
12697                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12698                ensure_uniform_list_compatible_label(&mut label);
12699                completions.push(Completion {
12700                    label,
12701                    documentation: None,
12702                    replace_range: completion.replace_range,
12703                    new_text: completion.new_text,
12704                    source: completion.source,
12705                    insert_text_mode: None,
12706                    icon_path: None,
12707                    confirm: None,
12708                });
12709            }
12710        }
12711    }
12712    completions
12713}
12714
12715#[derive(Debug)]
12716pub enum LanguageServerToQuery {
12717    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12718    FirstCapable,
12719    /// Query a specific language server.
12720    Other(LanguageServerId),
12721}
12722
12723#[derive(Default)]
12724struct RenamePathsWatchedForServer {
12725    did_rename: Vec<RenameActionPredicate>,
12726    will_rename: Vec<RenameActionPredicate>,
12727}
12728
12729impl RenamePathsWatchedForServer {
12730    fn with_did_rename_patterns(
12731        mut self,
12732        did_rename: Option<&FileOperationRegistrationOptions>,
12733    ) -> Self {
12734        if let Some(did_rename) = did_rename {
12735            self.did_rename = did_rename
12736                .filters
12737                .iter()
12738                .filter_map(|filter| filter.try_into().log_err())
12739                .collect();
12740        }
12741        self
12742    }
12743    fn with_will_rename_patterns(
12744        mut self,
12745        will_rename: Option<&FileOperationRegistrationOptions>,
12746    ) -> Self {
12747        if let Some(will_rename) = will_rename {
12748            self.will_rename = will_rename
12749                .filters
12750                .iter()
12751                .filter_map(|filter| filter.try_into().log_err())
12752                .collect();
12753        }
12754        self
12755    }
12756
12757    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12758        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12759    }
12760    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12761        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12762    }
12763}
12764
12765impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12766    type Error = globset::Error;
12767    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12768        Ok(Self {
12769            kind: ops.pattern.matches.clone(),
12770            glob: GlobBuilder::new(&ops.pattern.glob)
12771                .case_insensitive(
12772                    ops.pattern
12773                        .options
12774                        .as_ref()
12775                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12776                )
12777                .build()?
12778                .compile_matcher(),
12779        })
12780    }
12781}
12782struct RenameActionPredicate {
12783    glob: GlobMatcher,
12784    kind: Option<FileOperationPatternKind>,
12785}
12786
12787impl RenameActionPredicate {
12788    // Returns true if language server should be notified
12789    fn eval(&self, path: &str, is_dir: bool) -> bool {
12790        self.kind.as_ref().is_none_or(|kind| {
12791            let expected_kind = if is_dir {
12792                FileOperationPatternKind::Folder
12793            } else {
12794                FileOperationPatternKind::File
12795            };
12796            kind == &expected_kind
12797        }) && self.glob.is_match(path)
12798    }
12799}
12800
12801#[derive(Default)]
12802struct LanguageServerWatchedPaths {
12803    worktree_paths: HashMap<WorktreeId, GlobSet>,
12804    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12805}
12806
12807#[derive(Default)]
12808struct LanguageServerWatchedPathsBuilder {
12809    worktree_paths: HashMap<WorktreeId, GlobSet>,
12810    abs_paths: HashMap<Arc<Path>, GlobSet>,
12811}
12812
12813impl LanguageServerWatchedPathsBuilder {
12814    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12815        self.worktree_paths.insert(worktree_id, glob_set);
12816    }
12817    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12818        self.abs_paths.insert(path, glob_set);
12819    }
12820    fn build(
12821        self,
12822        fs: Arc<dyn Fs>,
12823        language_server_id: LanguageServerId,
12824        cx: &mut Context<LspStore>,
12825    ) -> LanguageServerWatchedPaths {
12826        let project = cx.weak_entity();
12827
12828        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12829        let abs_paths = self
12830            .abs_paths
12831            .into_iter()
12832            .map(|(abs_path, globset)| {
12833                let task = cx.spawn({
12834                    let abs_path = abs_path.clone();
12835                    let fs = fs.clone();
12836
12837                    let lsp_store = project.clone();
12838                    async move |_, cx| {
12839                        maybe!(async move {
12840                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12841                            while let Some(update) = push_updates.0.next().await {
12842                                let action = lsp_store
12843                                    .update(cx, |this, _| {
12844                                        let Some(local) = this.as_local() else {
12845                                            return ControlFlow::Break(());
12846                                        };
12847                                        let Some(watcher) = local
12848                                            .language_server_watched_paths
12849                                            .get(&language_server_id)
12850                                        else {
12851                                            return ControlFlow::Break(());
12852                                        };
12853                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12854                                            "Watched abs path is not registered with a watcher",
12855                                        );
12856                                        let matching_entries = update
12857                                            .into_iter()
12858                                            .filter(|event| globs.is_match(&event.path))
12859                                            .collect::<Vec<_>>();
12860                                        this.lsp_notify_abs_paths_changed(
12861                                            language_server_id,
12862                                            matching_entries,
12863                                        );
12864                                        ControlFlow::Continue(())
12865                                    })
12866                                    .ok()?;
12867
12868                                if action.is_break() {
12869                                    break;
12870                                }
12871                            }
12872                            Some(())
12873                        })
12874                        .await;
12875                    }
12876                });
12877                (abs_path, (globset, task))
12878            })
12879            .collect();
12880        LanguageServerWatchedPaths {
12881            worktree_paths: self.worktree_paths,
12882            abs_paths,
12883        }
12884    }
12885}
12886
12887struct LspBufferSnapshot {
12888    version: i32,
12889    snapshot: TextBufferSnapshot,
12890}
12891
12892/// A prompt requested by LSP server.
12893#[derive(Clone, Debug)]
12894pub struct LanguageServerPromptRequest {
12895    pub level: PromptLevel,
12896    pub message: String,
12897    pub actions: Vec<MessageActionItem>,
12898    pub lsp_name: String,
12899    pub(crate) response_channel: Sender<MessageActionItem>,
12900}
12901
12902impl LanguageServerPromptRequest {
12903    pub async fn respond(self, index: usize) -> Option<()> {
12904        if let Some(response) = self.actions.into_iter().nth(index) {
12905            self.response_channel.send(response).await.ok()
12906        } else {
12907            None
12908        }
12909    }
12910}
12911impl PartialEq for LanguageServerPromptRequest {
12912    fn eq(&self, other: &Self) -> bool {
12913        self.message == other.message && self.actions == other.actions
12914    }
12915}
12916
12917#[derive(Clone, Debug, PartialEq)]
12918pub enum LanguageServerLogType {
12919    Log(MessageType),
12920    Trace { verbose_info: Option<String> },
12921    Rpc { received: bool },
12922}
12923
12924impl LanguageServerLogType {
12925    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12926        match self {
12927            Self::Log(log_type) => {
12928                use proto::log_message::LogLevel;
12929                let level = match *log_type {
12930                    MessageType::ERROR => LogLevel::Error,
12931                    MessageType::WARNING => LogLevel::Warning,
12932                    MessageType::INFO => LogLevel::Info,
12933                    MessageType::LOG => LogLevel::Log,
12934                    other => {
12935                        log::warn!("Unknown lsp log message type: {other:?}");
12936                        LogLevel::Log
12937                    }
12938                };
12939                proto::language_server_log::LogType::Log(proto::LogMessage {
12940                    level: level as i32,
12941                })
12942            }
12943            Self::Trace { verbose_info } => {
12944                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12945                    verbose_info: verbose_info.to_owned(),
12946                })
12947            }
12948            Self::Rpc { received } => {
12949                let kind = if *received {
12950                    proto::rpc_message::Kind::Received
12951                } else {
12952                    proto::rpc_message::Kind::Sent
12953                };
12954                let kind = kind as i32;
12955                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12956            }
12957        }
12958    }
12959
12960    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12961        use proto::log_message::LogLevel;
12962        use proto::rpc_message;
12963        match log_type {
12964            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12965                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12966                    LogLevel::Error => MessageType::ERROR,
12967                    LogLevel::Warning => MessageType::WARNING,
12968                    LogLevel::Info => MessageType::INFO,
12969                    LogLevel::Log => MessageType::LOG,
12970                },
12971            ),
12972            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12973                verbose_info: trace_message.verbose_info,
12974            },
12975            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12976                received: match rpc_message::Kind::from_i32(message.kind)
12977                    .unwrap_or(rpc_message::Kind::Received)
12978                {
12979                    rpc_message::Kind::Received => true,
12980                    rpc_message::Kind::Sent => false,
12981                },
12982            },
12983        }
12984    }
12985}
12986
12987pub struct WorkspaceRefreshTask {
12988    refresh_tx: mpsc::Sender<()>,
12989    progress_tx: mpsc::Sender<()>,
12990    #[allow(dead_code)]
12991    task: Task<()>,
12992}
12993
12994pub enum LanguageServerState {
12995    Starting {
12996        startup: Task<Option<Arc<LanguageServer>>>,
12997        /// List of language servers that will be added to the workspace once it's initialization completes.
12998        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
12999    },
13000
13001    Running {
13002        adapter: Arc<CachedLspAdapter>,
13003        server: Arc<LanguageServer>,
13004        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13005        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13006    },
13007}
13008
13009impl LanguageServerState {
13010    fn add_workspace_folder(&self, uri: Uri) {
13011        match self {
13012            LanguageServerState::Starting {
13013                pending_workspace_folders,
13014                ..
13015            } => {
13016                pending_workspace_folders.lock().insert(uri);
13017            }
13018            LanguageServerState::Running { server, .. } => {
13019                server.add_workspace_folder(uri);
13020            }
13021        }
13022    }
13023    fn _remove_workspace_folder(&self, uri: Uri) {
13024        match self {
13025            LanguageServerState::Starting {
13026                pending_workspace_folders,
13027                ..
13028            } => {
13029                pending_workspace_folders.lock().remove(&uri);
13030            }
13031            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13032        }
13033    }
13034}
13035
13036impl std::fmt::Debug for LanguageServerState {
13037    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13038        match self {
13039            LanguageServerState::Starting { .. } => {
13040                f.debug_struct("LanguageServerState::Starting").finish()
13041            }
13042            LanguageServerState::Running { .. } => {
13043                f.debug_struct("LanguageServerState::Running").finish()
13044            }
13045        }
13046    }
13047}
13048
13049#[derive(Clone, Debug, Serialize)]
13050pub struct LanguageServerProgress {
13051    pub is_disk_based_diagnostics_progress: bool,
13052    pub is_cancellable: bool,
13053    pub title: Option<String>,
13054    pub message: Option<String>,
13055    pub percentage: Option<usize>,
13056    #[serde(skip_serializing)]
13057    pub last_update_at: Instant,
13058}
13059
13060#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13061pub struct DiagnosticSummary {
13062    pub error_count: usize,
13063    pub warning_count: usize,
13064}
13065
13066impl DiagnosticSummary {
13067    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13068        let mut this = Self {
13069            error_count: 0,
13070            warning_count: 0,
13071        };
13072
13073        for entry in diagnostics {
13074            if entry.diagnostic.is_primary {
13075                match entry.diagnostic.severity {
13076                    DiagnosticSeverity::ERROR => this.error_count += 1,
13077                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13078                    _ => {}
13079                }
13080            }
13081        }
13082
13083        this
13084    }
13085
13086    pub fn is_empty(&self) -> bool {
13087        self.error_count == 0 && self.warning_count == 0
13088    }
13089
13090    pub fn to_proto(
13091        self,
13092        language_server_id: LanguageServerId,
13093        path: &RelPath,
13094    ) -> proto::DiagnosticSummary {
13095        proto::DiagnosticSummary {
13096            path: path.to_proto(),
13097            language_server_id: language_server_id.0 as u64,
13098            error_count: self.error_count as u32,
13099            warning_count: self.warning_count as u32,
13100        }
13101    }
13102}
13103
13104#[derive(Clone, Debug)]
13105pub enum CompletionDocumentation {
13106    /// There is no documentation for this completion.
13107    Undocumented,
13108    /// A single line of documentation.
13109    SingleLine(SharedString),
13110    /// Multiple lines of plain text documentation.
13111    MultiLinePlainText(SharedString),
13112    /// Markdown documentation.
13113    MultiLineMarkdown(SharedString),
13114    /// Both single line and multiple lines of plain text documentation.
13115    SingleLineAndMultiLinePlainText {
13116        single_line: SharedString,
13117        plain_text: Option<SharedString>,
13118    },
13119}
13120
13121impl CompletionDocumentation {
13122    #[cfg(any(test, feature = "test-support"))]
13123    pub fn text(&self) -> SharedString {
13124        match self {
13125            CompletionDocumentation::Undocumented => "".into(),
13126            CompletionDocumentation::SingleLine(s) => s.clone(),
13127            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13128            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13129            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13130                single_line.clone()
13131            }
13132        }
13133    }
13134}
13135
13136impl From<lsp::Documentation> for CompletionDocumentation {
13137    fn from(docs: lsp::Documentation) -> Self {
13138        match docs {
13139            lsp::Documentation::String(text) => {
13140                if text.lines().count() <= 1 {
13141                    CompletionDocumentation::SingleLine(text.into())
13142                } else {
13143                    CompletionDocumentation::MultiLinePlainText(text.into())
13144                }
13145            }
13146
13147            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13148                lsp::MarkupKind::PlainText => {
13149                    if value.lines().count() <= 1 {
13150                        CompletionDocumentation::SingleLine(value.into())
13151                    } else {
13152                        CompletionDocumentation::MultiLinePlainText(value.into())
13153                    }
13154                }
13155
13156                lsp::MarkupKind::Markdown => {
13157                    CompletionDocumentation::MultiLineMarkdown(value.into())
13158                }
13159            },
13160        }
13161    }
13162}
13163
13164pub enum ResolvedHint {
13165    Resolved(InlayHint),
13166    Resolving(Shared<Task<()>>),
13167}
13168
13169fn glob_literal_prefix(glob: &Path) -> PathBuf {
13170    glob.components()
13171        .take_while(|component| match component {
13172            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13173            _ => true,
13174        })
13175        .collect()
13176}
13177
13178pub struct SshLspAdapter {
13179    name: LanguageServerName,
13180    binary: LanguageServerBinary,
13181    initialization_options: Option<String>,
13182    code_action_kinds: Option<Vec<CodeActionKind>>,
13183}
13184
13185impl SshLspAdapter {
13186    pub fn new(
13187        name: LanguageServerName,
13188        binary: LanguageServerBinary,
13189        initialization_options: Option<String>,
13190        code_action_kinds: Option<String>,
13191    ) -> Self {
13192        Self {
13193            name,
13194            binary,
13195            initialization_options,
13196            code_action_kinds: code_action_kinds
13197                .as_ref()
13198                .and_then(|c| serde_json::from_str(c).ok()),
13199        }
13200    }
13201}
13202
13203impl LspInstaller for SshLspAdapter {
13204    type BinaryVersion = ();
13205    async fn check_if_user_installed(
13206        &self,
13207        _: &dyn LspAdapterDelegate,
13208        _: Option<Toolchain>,
13209        _: &AsyncApp,
13210    ) -> Option<LanguageServerBinary> {
13211        Some(self.binary.clone())
13212    }
13213
13214    async fn cached_server_binary(
13215        &self,
13216        _: PathBuf,
13217        _: &dyn LspAdapterDelegate,
13218    ) -> Option<LanguageServerBinary> {
13219        None
13220    }
13221
13222    async fn fetch_latest_server_version(
13223        &self,
13224        _: &dyn LspAdapterDelegate,
13225        _: bool,
13226        _: &mut AsyncApp,
13227    ) -> Result<()> {
13228        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13229    }
13230
13231    async fn fetch_server_binary(
13232        &self,
13233        _: (),
13234        _: PathBuf,
13235        _: &dyn LspAdapterDelegate,
13236    ) -> Result<LanguageServerBinary> {
13237        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13238    }
13239}
13240
13241#[async_trait(?Send)]
13242impl LspAdapter for SshLspAdapter {
13243    fn name(&self) -> LanguageServerName {
13244        self.name.clone()
13245    }
13246
13247    async fn initialization_options(
13248        self: Arc<Self>,
13249        _: &Arc<dyn LspAdapterDelegate>,
13250    ) -> Result<Option<serde_json::Value>> {
13251        let Some(options) = &self.initialization_options else {
13252            return Ok(None);
13253        };
13254        let result = serde_json::from_str(options)?;
13255        Ok(result)
13256    }
13257
13258    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13259        self.code_action_kinds.clone()
13260    }
13261}
13262
13263pub fn language_server_settings<'a>(
13264    delegate: &'a dyn LspAdapterDelegate,
13265    language: &LanguageServerName,
13266    cx: &'a App,
13267) -> Option<&'a LspSettings> {
13268    language_server_settings_for(
13269        SettingsLocation {
13270            worktree_id: delegate.worktree_id(),
13271            path: RelPath::empty(),
13272        },
13273        language,
13274        cx,
13275    )
13276}
13277
13278pub(crate) fn language_server_settings_for<'a>(
13279    location: SettingsLocation<'a>,
13280    language: &LanguageServerName,
13281    cx: &'a App,
13282) -> Option<&'a LspSettings> {
13283    ProjectSettings::get(Some(location), cx).lsp.get(language)
13284}
13285
13286pub struct LocalLspAdapterDelegate {
13287    lsp_store: WeakEntity<LspStore>,
13288    worktree: worktree::Snapshot,
13289    fs: Arc<dyn Fs>,
13290    http_client: Arc<dyn HttpClient>,
13291    language_registry: Arc<LanguageRegistry>,
13292    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13293}
13294
13295impl LocalLspAdapterDelegate {
13296    pub fn new(
13297        language_registry: Arc<LanguageRegistry>,
13298        environment: &Entity<ProjectEnvironment>,
13299        lsp_store: WeakEntity<LspStore>,
13300        worktree: &Entity<Worktree>,
13301        http_client: Arc<dyn HttpClient>,
13302        fs: Arc<dyn Fs>,
13303        cx: &mut App,
13304    ) -> Arc<Self> {
13305        let load_shell_env_task = environment.update(cx, |env, cx| {
13306            env.get_worktree_environment(worktree.clone(), cx)
13307        });
13308
13309        Arc::new(Self {
13310            lsp_store,
13311            worktree: worktree.read(cx).snapshot(),
13312            fs,
13313            http_client,
13314            language_registry,
13315            load_shell_env_task,
13316        })
13317    }
13318
13319    fn from_local_lsp(
13320        local: &LocalLspStore,
13321        worktree: &Entity<Worktree>,
13322        cx: &mut App,
13323    ) -> Arc<Self> {
13324        Self::new(
13325            local.languages.clone(),
13326            &local.environment,
13327            local.weak.clone(),
13328            worktree,
13329            local.http_client.clone(),
13330            local.fs.clone(),
13331            cx,
13332        )
13333    }
13334}
13335
13336#[async_trait]
13337impl LspAdapterDelegate for LocalLspAdapterDelegate {
13338    fn show_notification(&self, message: &str, cx: &mut App) {
13339        self.lsp_store
13340            .update(cx, |_, cx| {
13341                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13342            })
13343            .ok();
13344    }
13345
13346    fn http_client(&self) -> Arc<dyn HttpClient> {
13347        self.http_client.clone()
13348    }
13349
13350    fn worktree_id(&self) -> WorktreeId {
13351        self.worktree.id()
13352    }
13353
13354    fn worktree_root_path(&self) -> &Path {
13355        self.worktree.abs_path().as_ref()
13356    }
13357
13358    async fn shell_env(&self) -> HashMap<String, String> {
13359        let task = self.load_shell_env_task.clone();
13360        task.await.unwrap_or_default()
13361    }
13362
13363    async fn npm_package_installed_version(
13364        &self,
13365        package_name: &str,
13366    ) -> Result<Option<(PathBuf, String)>> {
13367        let local_package_directory = self.worktree_root_path();
13368        let node_modules_directory = local_package_directory.join("node_modules");
13369
13370        if let Some(version) =
13371            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13372        {
13373            return Ok(Some((node_modules_directory, version)));
13374        }
13375        let Some(npm) = self.which("npm".as_ref()).await else {
13376            log::warn!(
13377                "Failed to find npm executable for {:?}",
13378                local_package_directory
13379            );
13380            return Ok(None);
13381        };
13382
13383        let env = self.shell_env().await;
13384        let output = util::command::new_smol_command(&npm)
13385            .args(["root", "-g"])
13386            .envs(env)
13387            .current_dir(local_package_directory)
13388            .output()
13389            .await?;
13390        let global_node_modules =
13391            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13392
13393        if let Some(version) =
13394            read_package_installed_version(global_node_modules.clone(), package_name).await?
13395        {
13396            return Ok(Some((global_node_modules, version)));
13397        }
13398        return Ok(None);
13399    }
13400
13401    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13402        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13403        if self.fs.is_file(&worktree_abs_path).await {
13404            worktree_abs_path.pop();
13405        }
13406
13407        let env = self.shell_env().await;
13408
13409        let shell_path = env.get("PATH").cloned();
13410
13411        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13412    }
13413
13414    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13415        let mut working_dir = self.worktree_root_path().to_path_buf();
13416        if self.fs.is_file(&working_dir).await {
13417            working_dir.pop();
13418        }
13419        let output = util::command::new_smol_command(&command.path)
13420            .args(command.arguments)
13421            .envs(command.env.clone().unwrap_or_default())
13422            .current_dir(working_dir)
13423            .output()
13424            .await?;
13425
13426        anyhow::ensure!(
13427            output.status.success(),
13428            "{}, stdout: {:?}, stderr: {:?}",
13429            output.status,
13430            String::from_utf8_lossy(&output.stdout),
13431            String::from_utf8_lossy(&output.stderr)
13432        );
13433        Ok(())
13434    }
13435
13436    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13437        self.language_registry
13438            .update_lsp_binary_status(server_name, status);
13439    }
13440
13441    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13442        self.language_registry
13443            .all_lsp_adapters()
13444            .into_iter()
13445            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13446            .collect()
13447    }
13448
13449    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13450        let dir = self.language_registry.language_server_download_dir(name)?;
13451
13452        if !dir.exists() {
13453            smol::fs::create_dir_all(&dir)
13454                .await
13455                .context("failed to create container directory")
13456                .log_err()?;
13457        }
13458
13459        Some(dir)
13460    }
13461
13462    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13463        let entry = self
13464            .worktree
13465            .entry_for_path(path)
13466            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13467        let abs_path = self.worktree.absolutize(&entry.path);
13468        self.fs.load(&abs_path).await
13469    }
13470}
13471
13472async fn populate_labels_for_symbols(
13473    symbols: Vec<CoreSymbol>,
13474    language_registry: &Arc<LanguageRegistry>,
13475    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13476    output: &mut Vec<Symbol>,
13477) {
13478    #[allow(clippy::mutable_key_type)]
13479    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13480
13481    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13482    for symbol in symbols {
13483        let Some(file_name) = symbol.path.file_name() else {
13484            continue;
13485        };
13486        let language = language_registry
13487            .load_language_for_file_path(Path::new(file_name))
13488            .await
13489            .ok()
13490            .or_else(|| {
13491                unknown_paths.insert(file_name.into());
13492                None
13493            });
13494        symbols_by_language
13495            .entry(language)
13496            .or_default()
13497            .push(symbol);
13498    }
13499
13500    for unknown_path in unknown_paths {
13501        log::info!("no language found for symbol in file {unknown_path:?}");
13502    }
13503
13504    let mut label_params = Vec::new();
13505    for (language, mut symbols) in symbols_by_language {
13506        label_params.clear();
13507        label_params.extend(
13508            symbols
13509                .iter_mut()
13510                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13511        );
13512
13513        let mut labels = Vec::new();
13514        if let Some(language) = language {
13515            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13516                language_registry
13517                    .lsp_adapters(&language.name())
13518                    .first()
13519                    .cloned()
13520            });
13521            if let Some(lsp_adapter) = lsp_adapter {
13522                labels = lsp_adapter
13523                    .labels_for_symbols(&label_params, &language)
13524                    .await
13525                    .log_err()
13526                    .unwrap_or_default();
13527            }
13528        }
13529
13530        for ((symbol, (name, _)), label) in symbols
13531            .into_iter()
13532            .zip(label_params.drain(..))
13533            .zip(labels.into_iter().chain(iter::repeat(None)))
13534        {
13535            output.push(Symbol {
13536                language_server_name: symbol.language_server_name,
13537                source_worktree_id: symbol.source_worktree_id,
13538                source_language_server_id: symbol.source_language_server_id,
13539                path: symbol.path,
13540                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13541                name,
13542                kind: symbol.kind,
13543                range: symbol.range,
13544            });
13545        }
13546    }
13547}
13548
13549fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13550    match server.capabilities().text_document_sync.as_ref()? {
13551        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13552            // Server wants didSave but didn't specify includeText.
13553            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13554            // Server doesn't want didSave at all.
13555            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13556            // Server provided SaveOptions.
13557            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13558                Some(save_options.include_text.unwrap_or(false))
13559            }
13560        },
13561        // We do not have any save info. Kind affects didChange only.
13562        lsp::TextDocumentSyncCapability::Kind(_) => None,
13563    }
13564}
13565
13566/// Completion items are displayed in a `UniformList`.
13567/// Usually, those items are single-line strings, but in LSP responses,
13568/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13569/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13570/// 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,
13571/// breaking the completions menu presentation.
13572///
13573/// 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.
13574fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13575    let mut new_text = String::with_capacity(label.text.len());
13576    let mut offset_map = vec![0; label.text.len() + 1];
13577    let mut last_char_was_space = false;
13578    let mut new_idx = 0;
13579    let chars = label.text.char_indices().fuse();
13580    let mut newlines_removed = false;
13581
13582    for (idx, c) in chars {
13583        offset_map[idx] = new_idx;
13584
13585        match c {
13586            '\n' if last_char_was_space => {
13587                newlines_removed = true;
13588            }
13589            '\t' | ' ' if last_char_was_space => {}
13590            '\n' if !last_char_was_space => {
13591                new_text.push(' ');
13592                new_idx += 1;
13593                last_char_was_space = true;
13594                newlines_removed = true;
13595            }
13596            ' ' | '\t' => {
13597                new_text.push(' ');
13598                new_idx += 1;
13599                last_char_was_space = true;
13600            }
13601            _ => {
13602                new_text.push(c);
13603                new_idx += c.len_utf8();
13604                last_char_was_space = false;
13605            }
13606        }
13607    }
13608    offset_map[label.text.len()] = new_idx;
13609
13610    // Only modify the label if newlines were removed.
13611    if !newlines_removed {
13612        return;
13613    }
13614
13615    let last_index = new_idx;
13616    let mut run_ranges_errors = Vec::new();
13617    label.runs.retain_mut(|(range, _)| {
13618        match offset_map.get(range.start) {
13619            Some(&start) => range.start = start,
13620            None => {
13621                run_ranges_errors.push(range.clone());
13622                return false;
13623            }
13624        }
13625
13626        match offset_map.get(range.end) {
13627            Some(&end) => range.end = end,
13628            None => {
13629                run_ranges_errors.push(range.clone());
13630                range.end = last_index;
13631            }
13632        }
13633        true
13634    });
13635    if !run_ranges_errors.is_empty() {
13636        log::error!(
13637            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13638            label.text
13639        );
13640    }
13641
13642    let mut wrong_filter_range = None;
13643    if label.filter_range == (0..label.text.len()) {
13644        label.filter_range = 0..new_text.len();
13645    } else {
13646        let mut original_filter_range = Some(label.filter_range.clone());
13647        match offset_map.get(label.filter_range.start) {
13648            Some(&start) => label.filter_range.start = start,
13649            None => {
13650                wrong_filter_range = original_filter_range.take();
13651                label.filter_range.start = last_index;
13652            }
13653        }
13654
13655        match offset_map.get(label.filter_range.end) {
13656            Some(&end) => label.filter_range.end = end,
13657            None => {
13658                wrong_filter_range = original_filter_range.take();
13659                label.filter_range.end = last_index;
13660            }
13661        }
13662    }
13663    if let Some(wrong_filter_range) = wrong_filter_range {
13664        log::error!(
13665            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13666            label.text
13667        );
13668    }
13669
13670    label.text = new_text;
13671}
13672
13673#[cfg(test)]
13674mod tests {
13675    use language::HighlightId;
13676
13677    use super::*;
13678
13679    #[test]
13680    fn test_glob_literal_prefix() {
13681        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13682        assert_eq!(
13683            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13684            Path::new("node_modules")
13685        );
13686        assert_eq!(
13687            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13688            Path::new("foo")
13689        );
13690        assert_eq!(
13691            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13692            Path::new("foo/bar/baz.js")
13693        );
13694
13695        #[cfg(target_os = "windows")]
13696        {
13697            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13698            assert_eq!(
13699                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13700                Path::new("node_modules")
13701            );
13702            assert_eq!(
13703                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13704                Path::new("foo")
13705            );
13706            assert_eq!(
13707                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13708                Path::new("foo/bar/baz.js")
13709            );
13710        }
13711    }
13712
13713    #[test]
13714    fn test_multi_len_chars_normalization() {
13715        let mut label = CodeLabel::new(
13716            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13717            0..6,
13718            vec![(0..6, HighlightId(1))],
13719        );
13720        ensure_uniform_list_compatible_label(&mut label);
13721        assert_eq!(
13722            label,
13723            CodeLabel::new(
13724                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13725                0..6,
13726                vec![(0..6, HighlightId(1))],
13727            )
13728        );
13729    }
13730}