lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        inlay_hint_cache::BufferChunk,
   33        log_store::{GlobalLogStore, LanguageServerKind},
   34    },
   35    manifest_tree::{
   36        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   37        ManifestTree,
   38    },
   39    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   40    project_settings::{LspSettings, ProjectSettings},
   41    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   59    WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76};
   77use lsp::{
   78    AdapterServerCapabilities, CodeActionKind, CompletionContext, DiagnosticServerCapabilities,
   79    DiagnosticSeverity, DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit,
   80    FileOperationFilter, FileOperationPatternKind, FileOperationRegistrationOptions, FileRename,
   81    FileSystemWatcher, LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary,
   82    LanguageServerBinaryOptions, LanguageServerId, LanguageServerName, LanguageServerSelector,
   83    LspRequestFuture, MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind,
   84    TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles, WorkDoneProgressCancelParams,
   85    WorkspaceFolder, notification::DidRenameFiles,
   86};
   87use node_runtime::read_package_installed_version;
   88use parking_lot::Mutex;
   89use postage::{mpsc, sink::Sink, stream::Stream, watch};
   90use rand::prelude::*;
   91use rpc::{
   92    AnyProtoClient, ErrorCode, ErrorExt as _,
   93    proto::{LspRequestId, LspRequestMessage as _},
   94};
   95use serde::Serialize;
   96use settings::{Settings, SettingsLocation, SettingsStore};
   97use sha2::{Digest, Sha256};
   98use smol::channel::Sender;
   99use snippet::Snippet;
  100use std::{
  101    any::TypeId,
  102    borrow::Cow,
  103    cell::RefCell,
  104    cmp::{Ordering, Reverse},
  105    convert::TryInto,
  106    ffi::OsStr,
  107    future::ready,
  108    iter, mem,
  109    ops::{ControlFlow, Range},
  110    path::{self, Path, PathBuf},
  111    pin::pin,
  112    rc::Rc,
  113    sync::{
  114        Arc,
  115        atomic::{self, AtomicUsize},
  116    },
  117    time::{Duration, Instant},
  118};
  119use sum_tree::Dimensions;
  120use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, Point, ToPoint as _};
  121
  122use util::{
  123    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  124    paths::{PathStyle, SanitizedPath},
  125    post_inc,
  126    rel_path::RelPath,
  127};
  128
  129pub use fs::*;
  130pub use language::Location;
  131pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  132#[cfg(any(test, feature = "test-support"))]
  133pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  134pub use worktree::{
  135    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  136    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  137};
  138
  139const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  140pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  141
  142#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  143pub enum FormatTrigger {
  144    Save,
  145    Manual,
  146}
  147
  148pub enum LspFormatTarget {
  149    Buffers,
  150    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  151}
  152
  153pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  154
  155impl FormatTrigger {
  156    fn from_proto(value: i32) -> FormatTrigger {
  157        match value {
  158            0 => FormatTrigger::Save,
  159            1 => FormatTrigger::Manual,
  160            _ => FormatTrigger::Save,
  161        }
  162    }
  163}
  164
  165#[derive(Clone)]
  166struct UnifiedLanguageServer {
  167    id: LanguageServerId,
  168    project_roots: HashSet<Arc<RelPath>>,
  169}
  170
  171#[derive(Clone, Hash, PartialEq, Eq)]
  172struct LanguageServerSeed {
  173    worktree_id: WorktreeId,
  174    name: LanguageServerName,
  175    toolchain: Option<Toolchain>,
  176    settings: Arc<LspSettings>,
  177}
  178
  179#[derive(Debug)]
  180pub struct DocumentDiagnosticsUpdate<'a, D> {
  181    pub diagnostics: D,
  182    pub result_id: Option<String>,
  183    pub server_id: LanguageServerId,
  184    pub disk_based_sources: Cow<'a, [String]>,
  185}
  186
  187pub struct DocumentDiagnostics {
  188    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  189    document_abs_path: PathBuf,
  190    version: Option<i32>,
  191}
  192
  193#[derive(Default)]
  194struct DynamicRegistrations {
  195    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  196    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  197}
  198
  199pub struct LocalLspStore {
  200    weak: WeakEntity<LspStore>,
  201    worktree_store: Entity<WorktreeStore>,
  202    toolchain_store: Entity<LocalToolchainStore>,
  203    http_client: Arc<dyn HttpClient>,
  204    environment: Entity<ProjectEnvironment>,
  205    fs: Arc<dyn Fs>,
  206    languages: Arc<LanguageRegistry>,
  207    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  208    yarn: Entity<YarnPathStore>,
  209    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  210    buffers_being_formatted: HashSet<BufferId>,
  211    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  212    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  213    watched_manifest_filenames: HashSet<ManifestName>,
  214    language_server_paths_watched_for_rename:
  215        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  216    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  217    supplementary_language_servers:
  218        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  219    prettier_store: Entity<PrettierStore>,
  220    next_diagnostic_group_id: usize,
  221    diagnostics: HashMap<
  222        WorktreeId,
  223        HashMap<
  224            Arc<RelPath>,
  225            Vec<(
  226                LanguageServerId,
  227                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  228            )>,
  229        >,
  230    >,
  231    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  232    _subscription: gpui::Subscription,
  233    lsp_tree: LanguageServerTree,
  234    registered_buffers: HashMap<BufferId, usize>,
  235    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  236    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  237}
  238
  239impl LocalLspStore {
  240    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  241    pub fn running_language_server_for_id(
  242        &self,
  243        id: LanguageServerId,
  244    ) -> Option<&Arc<LanguageServer>> {
  245        let language_server_state = self.language_servers.get(&id)?;
  246
  247        match language_server_state {
  248            LanguageServerState::Running { server, .. } => Some(server),
  249            LanguageServerState::Starting { .. } => None,
  250        }
  251    }
  252
  253    fn get_or_insert_language_server(
  254        &mut self,
  255        worktree_handle: &Entity<Worktree>,
  256        delegate: Arc<LocalLspAdapterDelegate>,
  257        disposition: &Arc<LaunchDisposition>,
  258        language_name: &LanguageName,
  259        cx: &mut App,
  260    ) -> LanguageServerId {
  261        let key = LanguageServerSeed {
  262            worktree_id: worktree_handle.read(cx).id(),
  263            name: disposition.server_name.clone(),
  264            settings: disposition.settings.clone(),
  265            toolchain: disposition.toolchain.clone(),
  266        };
  267        if let Some(state) = self.language_server_ids.get_mut(&key) {
  268            state.project_roots.insert(disposition.path.path.clone());
  269            state.id
  270        } else {
  271            let adapter = self
  272                .languages
  273                .lsp_adapters(language_name)
  274                .into_iter()
  275                .find(|adapter| adapter.name() == disposition.server_name)
  276                .expect("To find LSP adapter");
  277            let new_language_server_id = self.start_language_server(
  278                worktree_handle,
  279                delegate,
  280                adapter,
  281                disposition.settings.clone(),
  282                key.clone(),
  283                cx,
  284            );
  285            if let Some(state) = self.language_server_ids.get_mut(&key) {
  286                state.project_roots.insert(disposition.path.path.clone());
  287            } else {
  288                debug_assert!(
  289                    false,
  290                    "Expected `start_language_server` to ensure that `key` exists in a map"
  291                );
  292            }
  293            new_language_server_id
  294        }
  295    }
  296
  297    fn start_language_server(
  298        &mut self,
  299        worktree_handle: &Entity<Worktree>,
  300        delegate: Arc<LocalLspAdapterDelegate>,
  301        adapter: Arc<CachedLspAdapter>,
  302        settings: Arc<LspSettings>,
  303        key: LanguageServerSeed,
  304        cx: &mut App,
  305    ) -> LanguageServerId {
  306        let worktree = worktree_handle.read(cx);
  307
  308        let root_path = worktree.abs_path();
  309        let toolchain = key.toolchain.clone();
  310        let override_options = settings.initialization_options.clone();
  311
  312        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  313
  314        let server_id = self.languages.next_language_server_id();
  315        log::trace!(
  316            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  317            adapter.name.0
  318        );
  319
  320        let binary = self.get_language_server_binary(
  321            adapter.clone(),
  322            settings,
  323            toolchain.clone(),
  324            delegate.clone(),
  325            true,
  326            cx,
  327        );
  328        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  329
  330        let pending_server = cx.spawn({
  331            let adapter = adapter.clone();
  332            let server_name = adapter.name.clone();
  333            let stderr_capture = stderr_capture.clone();
  334            #[cfg(any(test, feature = "test-support"))]
  335            let lsp_store = self.weak.clone();
  336            let pending_workspace_folders = pending_workspace_folders.clone();
  337            async move |cx| {
  338                let binary = binary.await?;
  339                #[cfg(any(test, feature = "test-support"))]
  340                if let Some(server) = lsp_store
  341                    .update(&mut cx.clone(), |this, cx| {
  342                        this.languages.create_fake_language_server(
  343                            server_id,
  344                            &server_name,
  345                            binary.clone(),
  346                            &mut cx.to_async(),
  347                        )
  348                    })
  349                    .ok()
  350                    .flatten()
  351                {
  352                    return Ok(server);
  353                }
  354
  355                let code_action_kinds = adapter.code_action_kinds();
  356                lsp::LanguageServer::new(
  357                    stderr_capture,
  358                    server_id,
  359                    server_name,
  360                    binary,
  361                    &root_path,
  362                    code_action_kinds,
  363                    Some(pending_workspace_folders),
  364                    cx,
  365                )
  366            }
  367        });
  368
  369        let startup = {
  370            let server_name = adapter.name.0.clone();
  371            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  372            let key = key.clone();
  373            let adapter = adapter.clone();
  374            let lsp_store = self.weak.clone();
  375            let pending_workspace_folders = pending_workspace_folders.clone();
  376
  377            let pull_diagnostics = ProjectSettings::get_global(cx)
  378                .diagnostics
  379                .lsp_pull_diagnostics
  380                .enabled;
  381            cx.spawn(async move |cx| {
  382                let result = async {
  383                    let language_server = pending_server.await?;
  384
  385                    let workspace_config = Self::workspace_configuration_for_adapter(
  386                        adapter.adapter.clone(),
  387                        &delegate,
  388                        toolchain,
  389                        cx,
  390                    )
  391                    .await?;
  392
  393                    let mut initialization_options = Self::initialization_options_for_adapter(
  394                        adapter.adapter.clone(),
  395                        &delegate,
  396                    )
  397                    .await?;
  398
  399                    match (&mut initialization_options, override_options) {
  400                        (Some(initialization_options), Some(override_options)) => {
  401                            merge_json_value_into(override_options, initialization_options);
  402                        }
  403                        (None, override_options) => initialization_options = override_options,
  404                        _ => {}
  405                    }
  406
  407                    let initialization_params = cx.update(|cx| {
  408                        let mut params =
  409                            language_server.default_initialize_params(pull_diagnostics, cx);
  410                        params.initialization_options = initialization_options;
  411                        adapter.adapter.prepare_initialize_params(params, cx)
  412                    })??;
  413
  414                    Self::setup_lsp_messages(
  415                        lsp_store.clone(),
  416                        &language_server,
  417                        delegate.clone(),
  418                        adapter.clone(),
  419                    );
  420
  421                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  422                        settings: workspace_config,
  423                    };
  424                    let language_server = cx
  425                        .update(|cx| {
  426                            language_server.initialize(
  427                                initialization_params,
  428                                Arc::new(did_change_configuration_params.clone()),
  429                                cx,
  430                            )
  431                        })?
  432                        .await
  433                        .inspect_err(|_| {
  434                            if let Some(lsp_store) = lsp_store.upgrade() {
  435                                lsp_store
  436                                    .update(cx, |lsp_store, cx| {
  437                                        lsp_store.cleanup_lsp_data(server_id);
  438                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  439                                    })
  440                                    .ok();
  441                            }
  442                        })?;
  443
  444                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  445                        did_change_configuration_params,
  446                    )?;
  447
  448                    anyhow::Ok(language_server)
  449                }
  450                .await;
  451
  452                match result {
  453                    Ok(server) => {
  454                        lsp_store
  455                            .update(cx, |lsp_store, cx| {
  456                                lsp_store.insert_newly_running_language_server(
  457                                    adapter,
  458                                    server.clone(),
  459                                    server_id,
  460                                    key,
  461                                    pending_workspace_folders,
  462                                    cx,
  463                                );
  464                            })
  465                            .ok();
  466                        stderr_capture.lock().take();
  467                        Some(server)
  468                    }
  469
  470                    Err(err) => {
  471                        let log = stderr_capture.lock().take().unwrap_or_default();
  472                        delegate.update_status(
  473                            adapter.name(),
  474                            BinaryStatus::Failed {
  475                                error: if log.is_empty() {
  476                                    format!("{err:#}")
  477                                } else {
  478                                    format!("{err:#}\n-- stderr --\n{log}")
  479                                },
  480                            },
  481                        );
  482                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  483                        if !log.is_empty() {
  484                            log::error!("server stderr: {log}");
  485                        }
  486                        None
  487                    }
  488                }
  489            })
  490        };
  491        let state = LanguageServerState::Starting {
  492            startup,
  493            pending_workspace_folders,
  494        };
  495
  496        self.languages
  497            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  498
  499        self.language_servers.insert(server_id, state);
  500        self.language_server_ids
  501            .entry(key)
  502            .or_insert(UnifiedLanguageServer {
  503                id: server_id,
  504                project_roots: Default::default(),
  505            });
  506        server_id
  507    }
  508
  509    fn get_language_server_binary(
  510        &self,
  511        adapter: Arc<CachedLspAdapter>,
  512        settings: Arc<LspSettings>,
  513        toolchain: Option<Toolchain>,
  514        delegate: Arc<dyn LspAdapterDelegate>,
  515        allow_binary_download: bool,
  516        cx: &mut App,
  517    ) -> Task<Result<LanguageServerBinary>> {
  518        if let Some(settings) = settings.binary.as_ref()
  519            && settings.path.is_some()
  520        {
  521            let settings = settings.clone();
  522
  523            return cx.background_spawn(async move {
  524                let mut env = delegate.shell_env().await;
  525                env.extend(settings.env.unwrap_or_default());
  526
  527                Ok(LanguageServerBinary {
  528                    path: PathBuf::from(&settings.path.unwrap()),
  529                    env: Some(env),
  530                    arguments: settings
  531                        .arguments
  532                        .unwrap_or_default()
  533                        .iter()
  534                        .map(Into::into)
  535                        .collect(),
  536                })
  537            });
  538        }
  539        let lsp_binary_options = LanguageServerBinaryOptions {
  540            allow_path_lookup: !settings
  541                .binary
  542                .as_ref()
  543                .and_then(|b| b.ignore_system_version)
  544                .unwrap_or_default(),
  545            allow_binary_download,
  546            pre_release: settings
  547                .fetch
  548                .as_ref()
  549                .and_then(|f| f.pre_release)
  550                .unwrap_or(false),
  551        };
  552
  553        cx.spawn(async move |cx| {
  554            let binary_result = adapter
  555                .clone()
  556                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  557                .await;
  558
  559            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  560
  561            let mut binary = binary_result?;
  562            let mut shell_env = delegate.shell_env().await;
  563
  564            shell_env.extend(binary.env.unwrap_or_default());
  565
  566            if let Some(settings) = settings.binary.as_ref() {
  567                if let Some(arguments) = &settings.arguments {
  568                    binary.arguments = arguments.iter().map(Into::into).collect();
  569                }
  570                if let Some(env) = &settings.env {
  571                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  572                }
  573            }
  574
  575            binary.env = Some(shell_env);
  576            Ok(binary)
  577        })
  578    }
  579
  580    fn setup_lsp_messages(
  581        lsp_store: WeakEntity<LspStore>,
  582        language_server: &LanguageServer,
  583        delegate: Arc<dyn LspAdapterDelegate>,
  584        adapter: Arc<CachedLspAdapter>,
  585    ) {
  586        let name = language_server.name();
  587        let server_id = language_server.server_id();
  588        language_server
  589            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  590                let adapter = adapter.clone();
  591                let this = lsp_store.clone();
  592                move |mut params, cx| {
  593                    let adapter = adapter.clone();
  594                    if let Some(this) = this.upgrade() {
  595                        this.update(cx, |this, cx| {
  596                            {
  597                                let buffer = params
  598                                    .uri
  599                                    .to_file_path()
  600                                    .map(|file_path| this.get_buffer(&file_path, cx))
  601                                    .ok()
  602                                    .flatten();
  603                                adapter.process_diagnostics(&mut params, server_id, buffer);
  604                            }
  605
  606                            this.merge_lsp_diagnostics(
  607                                DiagnosticSourceKind::Pushed,
  608                                vec![DocumentDiagnosticsUpdate {
  609                                    server_id,
  610                                    diagnostics: params,
  611                                    result_id: None,
  612                                    disk_based_sources: Cow::Borrowed(
  613                                        &adapter.disk_based_diagnostic_sources,
  614                                    ),
  615                                }],
  616                                |_, diagnostic, cx| match diagnostic.source_kind {
  617                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  618                                        adapter.retain_old_diagnostic(diagnostic, cx)
  619                                    }
  620                                    DiagnosticSourceKind::Pulled => true,
  621                                },
  622                                cx,
  623                            )
  624                            .log_err();
  625                        })
  626                        .ok();
  627                    }
  628                }
  629            })
  630            .detach();
  631        language_server
  632            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  633                let adapter = adapter.adapter.clone();
  634                let delegate = delegate.clone();
  635                let this = lsp_store.clone();
  636                move |params, cx| {
  637                    let adapter = adapter.clone();
  638                    let delegate = delegate.clone();
  639                    let this = this.clone();
  640                    let mut cx = cx.clone();
  641                    async move {
  642                        let toolchain_for_id = this
  643                            .update(&mut cx, |this, _| {
  644                                this.as_local()?.language_server_ids.iter().find_map(
  645                                    |(seed, value)| {
  646                                        (value.id == server_id).then(|| seed.toolchain.clone())
  647                                    },
  648                                )
  649                            })?
  650                            .context("Expected the LSP store to be in a local mode")?;
  651                        let workspace_config = Self::workspace_configuration_for_adapter(
  652                            adapter.clone(),
  653                            &delegate,
  654                            toolchain_for_id,
  655                            &mut cx,
  656                        )
  657                        .await?;
  658
  659                        Ok(params
  660                            .items
  661                            .into_iter()
  662                            .map(|item| {
  663                                if let Some(section) = &item.section {
  664                                    workspace_config
  665                                        .get(section)
  666                                        .cloned()
  667                                        .unwrap_or(serde_json::Value::Null)
  668                                } else {
  669                                    workspace_config.clone()
  670                                }
  671                            })
  672                            .collect())
  673                    }
  674                }
  675            })
  676            .detach();
  677
  678        language_server
  679            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  680                let this = lsp_store.clone();
  681                move |_, cx| {
  682                    let this = this.clone();
  683                    let cx = cx.clone();
  684                    async move {
  685                        let Some(server) =
  686                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  687                        else {
  688                            return Ok(None);
  689                        };
  690                        let root = server.workspace_folders();
  691                        Ok(Some(
  692                            root.into_iter()
  693                                .map(|uri| WorkspaceFolder {
  694                                    uri,
  695                                    name: Default::default(),
  696                                })
  697                                .collect(),
  698                        ))
  699                    }
  700                }
  701            })
  702            .detach();
  703        // Even though we don't have handling for these requests, respond to them to
  704        // avoid stalling any language server like `gopls` which waits for a response
  705        // to these requests when initializing.
  706        language_server
  707            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  708                let this = lsp_store.clone();
  709                move |params, cx| {
  710                    let this = this.clone();
  711                    let mut cx = cx.clone();
  712                    async move {
  713                        this.update(&mut cx, |this, _| {
  714                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  715                                && let lsp::NumberOrString::String(token) = params.token
  716                            {
  717                                status.progress_tokens.insert(token);
  718                            }
  719                        })?;
  720
  721                        Ok(())
  722                    }
  723                }
  724            })
  725            .detach();
  726
  727        language_server
  728            .on_request::<lsp::request::RegisterCapability, _, _>({
  729                let lsp_store = lsp_store.clone();
  730                move |params, cx| {
  731                    let lsp_store = lsp_store.clone();
  732                    let mut cx = cx.clone();
  733                    async move {
  734                        lsp_store
  735                            .update(&mut cx, |lsp_store, cx| {
  736                                if lsp_store.as_local().is_some() {
  737                                    match lsp_store
  738                                        .register_server_capabilities(server_id, params, cx)
  739                                    {
  740                                        Ok(()) => {}
  741                                        Err(e) => {
  742                                            log::error!(
  743                                                "Failed to register server capabilities: {e:#}"
  744                                            );
  745                                        }
  746                                    };
  747                                }
  748                            })
  749                            .ok();
  750                        Ok(())
  751                    }
  752                }
  753            })
  754            .detach();
  755
  756        language_server
  757            .on_request::<lsp::request::UnregisterCapability, _, _>({
  758                let lsp_store = lsp_store.clone();
  759                move |params, cx| {
  760                    let lsp_store = lsp_store.clone();
  761                    let mut cx = cx.clone();
  762                    async move {
  763                        lsp_store
  764                            .update(&mut cx, |lsp_store, cx| {
  765                                if lsp_store.as_local().is_some() {
  766                                    match lsp_store
  767                                        .unregister_server_capabilities(server_id, params, cx)
  768                                    {
  769                                        Ok(()) => {}
  770                                        Err(e) => {
  771                                            log::error!(
  772                                                "Failed to unregister server capabilities: {e:#}"
  773                                            );
  774                                        }
  775                                    }
  776                                }
  777                            })
  778                            .ok();
  779                        Ok(())
  780                    }
  781                }
  782            })
  783            .detach();
  784
  785        language_server
  786            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  787                let this = lsp_store.clone();
  788                move |params, cx| {
  789                    let mut cx = cx.clone();
  790                    let this = this.clone();
  791                    async move {
  792                        LocalLspStore::on_lsp_workspace_edit(
  793                            this.clone(),
  794                            params,
  795                            server_id,
  796                            &mut cx,
  797                        )
  798                        .await
  799                    }
  800                }
  801            })
  802            .detach();
  803
  804        language_server
  805            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  806                let lsp_store = lsp_store.clone();
  807                let request_id = Arc::new(AtomicUsize::new(0));
  808                move |(), cx| {
  809                    let lsp_store = lsp_store.clone();
  810                    let request_id = request_id.clone();
  811                    let mut cx = cx.clone();
  812                    async move {
  813                        lsp_store
  814                            .update(&mut cx, |lsp_store, cx| {
  815                                let request_id =
  816                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  817                                cx.emit(LspStoreEvent::RefreshInlayHints {
  818                                    server_id,
  819                                    request_id,
  820                                });
  821                                lsp_store
  822                                    .downstream_client
  823                                    .as_ref()
  824                                    .map(|(client, project_id)| {
  825                                        client.send(proto::RefreshInlayHints {
  826                                            project_id: *project_id,
  827                                            server_id: server_id.to_proto(),
  828                                            request_id: request_id.map(|id| id as u64),
  829                                        })
  830                                    })
  831                            })?
  832                            .transpose()?;
  833                        Ok(())
  834                    }
  835                }
  836            })
  837            .detach();
  838
  839        language_server
  840            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  841                let this = lsp_store.clone();
  842                move |(), cx| {
  843                    let this = this.clone();
  844                    let mut cx = cx.clone();
  845                    async move {
  846                        this.update(&mut cx, |this, cx| {
  847                            cx.emit(LspStoreEvent::RefreshCodeLens);
  848                            this.downstream_client.as_ref().map(|(client, project_id)| {
  849                                client.send(proto::RefreshCodeLens {
  850                                    project_id: *project_id,
  851                                })
  852                            })
  853                        })?
  854                        .transpose()?;
  855                        Ok(())
  856                    }
  857                }
  858            })
  859            .detach();
  860
  861        language_server
  862            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  863                let this = lsp_store.clone();
  864                move |(), cx| {
  865                    let this = this.clone();
  866                    let mut cx = cx.clone();
  867                    async move {
  868                        this.update(&mut cx, |lsp_store, _| {
  869                            lsp_store.pull_workspace_diagnostics(server_id);
  870                            lsp_store
  871                                .downstream_client
  872                                .as_ref()
  873                                .map(|(client, project_id)| {
  874                                    client.send(proto::PullWorkspaceDiagnostics {
  875                                        project_id: *project_id,
  876                                        server_id: server_id.to_proto(),
  877                                    })
  878                                })
  879                        })?
  880                        .transpose()?;
  881                        Ok(())
  882                    }
  883                }
  884            })
  885            .detach();
  886
  887        language_server
  888            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  889                let this = lsp_store.clone();
  890                let name = name.to_string();
  891                move |params, cx| {
  892                    let this = this.clone();
  893                    let name = name.to_string();
  894                    let mut cx = cx.clone();
  895                    async move {
  896                        let actions = params.actions.unwrap_or_default();
  897                        let (tx, rx) = smol::channel::bounded(1);
  898                        let request = LanguageServerPromptRequest {
  899                            level: match params.typ {
  900                                lsp::MessageType::ERROR => PromptLevel::Critical,
  901                                lsp::MessageType::WARNING => PromptLevel::Warning,
  902                                _ => PromptLevel::Info,
  903                            },
  904                            message: params.message,
  905                            actions,
  906                            response_channel: tx,
  907                            lsp_name: name.clone(),
  908                        };
  909
  910                        let did_update = this
  911                            .update(&mut cx, |_, cx| {
  912                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  913                            })
  914                            .is_ok();
  915                        if did_update {
  916                            let response = rx.recv().await.ok();
  917                            Ok(response)
  918                        } else {
  919                            Ok(None)
  920                        }
  921                    }
  922                }
  923            })
  924            .detach();
  925        language_server
  926            .on_notification::<lsp::notification::ShowMessage, _>({
  927                let this = lsp_store.clone();
  928                let name = name.to_string();
  929                move |params, cx| {
  930                    let this = this.clone();
  931                    let name = name.to_string();
  932                    let mut cx = cx.clone();
  933
  934                    let (tx, _) = smol::channel::bounded(1);
  935                    let request = LanguageServerPromptRequest {
  936                        level: match params.typ {
  937                            lsp::MessageType::ERROR => PromptLevel::Critical,
  938                            lsp::MessageType::WARNING => PromptLevel::Warning,
  939                            _ => PromptLevel::Info,
  940                        },
  941                        message: params.message,
  942                        actions: vec![],
  943                        response_channel: tx,
  944                        lsp_name: name,
  945                    };
  946
  947                    let _ = this.update(&mut cx, |_, cx| {
  948                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  949                    });
  950                }
  951            })
  952            .detach();
  953
  954        let disk_based_diagnostics_progress_token =
  955            adapter.disk_based_diagnostics_progress_token.clone();
  956
  957        language_server
  958            .on_notification::<lsp::notification::Progress, _>({
  959                let this = lsp_store.clone();
  960                move |params, cx| {
  961                    if let Some(this) = this.upgrade() {
  962                        this.update(cx, |this, cx| {
  963                            this.on_lsp_progress(
  964                                params,
  965                                server_id,
  966                                disk_based_diagnostics_progress_token.clone(),
  967                                cx,
  968                            );
  969                        })
  970                        .ok();
  971                    }
  972                }
  973            })
  974            .detach();
  975
  976        language_server
  977            .on_notification::<lsp::notification::LogMessage, _>({
  978                let this = lsp_store.clone();
  979                move |params, cx| {
  980                    if let Some(this) = this.upgrade() {
  981                        this.update(cx, |_, cx| {
  982                            cx.emit(LspStoreEvent::LanguageServerLog(
  983                                server_id,
  984                                LanguageServerLogType::Log(params.typ),
  985                                params.message,
  986                            ));
  987                        })
  988                        .ok();
  989                    }
  990                }
  991            })
  992            .detach();
  993
  994        language_server
  995            .on_notification::<lsp::notification::LogTrace, _>({
  996                let this = lsp_store.clone();
  997                move |params, cx| {
  998                    let mut cx = cx.clone();
  999                    if let Some(this) = this.upgrade() {
 1000                        this.update(&mut cx, |_, cx| {
 1001                            cx.emit(LspStoreEvent::LanguageServerLog(
 1002                                server_id,
 1003                                LanguageServerLogType::Trace {
 1004                                    verbose_info: params.verbose,
 1005                                },
 1006                                params.message,
 1007                            ));
 1008                        })
 1009                        .ok();
 1010                    }
 1011                }
 1012            })
 1013            .detach();
 1014
 1015        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1016        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1017        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1018        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1019    }
 1020
 1021    fn shutdown_language_servers_on_quit(
 1022        &mut self,
 1023        _: &mut Context<LspStore>,
 1024    ) -> impl Future<Output = ()> + use<> {
 1025        let shutdown_futures = self
 1026            .language_servers
 1027            .drain()
 1028            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1029            .collect::<Vec<_>>();
 1030
 1031        async move {
 1032            join_all(shutdown_futures).await;
 1033        }
 1034    }
 1035
 1036    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1037        match server_state {
 1038            LanguageServerState::Running { server, .. } => {
 1039                if let Some(shutdown) = server.shutdown() {
 1040                    shutdown.await;
 1041                }
 1042            }
 1043            LanguageServerState::Starting { startup, .. } => {
 1044                if let Some(server) = startup.await
 1045                    && let Some(shutdown) = server.shutdown()
 1046                {
 1047                    shutdown.await;
 1048                }
 1049            }
 1050        }
 1051        Ok(())
 1052    }
 1053
 1054    fn language_servers_for_worktree(
 1055        &self,
 1056        worktree_id: WorktreeId,
 1057    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1058        self.language_server_ids
 1059            .iter()
 1060            .filter_map(move |(seed, state)| {
 1061                if seed.worktree_id != worktree_id {
 1062                    return None;
 1063                }
 1064
 1065                if let Some(LanguageServerState::Running { server, .. }) =
 1066                    self.language_servers.get(&state.id)
 1067                {
 1068                    Some(server)
 1069                } else {
 1070                    None
 1071                }
 1072            })
 1073    }
 1074
 1075    fn language_server_ids_for_project_path(
 1076        &self,
 1077        project_path: ProjectPath,
 1078        language: &Language,
 1079        cx: &mut App,
 1080    ) -> Vec<LanguageServerId> {
 1081        let Some(worktree) = self
 1082            .worktree_store
 1083            .read(cx)
 1084            .worktree_for_id(project_path.worktree_id, cx)
 1085        else {
 1086            return Vec::new();
 1087        };
 1088        let delegate: Arc<dyn ManifestDelegate> =
 1089            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1090
 1091        self.lsp_tree
 1092            .get(
 1093                project_path,
 1094                language.name(),
 1095                language.manifest(),
 1096                &delegate,
 1097                cx,
 1098            )
 1099            .collect::<Vec<_>>()
 1100    }
 1101
 1102    fn language_server_ids_for_buffer(
 1103        &self,
 1104        buffer: &Buffer,
 1105        cx: &mut App,
 1106    ) -> Vec<LanguageServerId> {
 1107        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1108            let worktree_id = file.worktree_id(cx);
 1109
 1110            let path: Arc<RelPath> = file
 1111                .path()
 1112                .parent()
 1113                .map(Arc::from)
 1114                .unwrap_or_else(|| file.path().clone());
 1115            let worktree_path = ProjectPath { worktree_id, path };
 1116            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1117        } else {
 1118            Vec::new()
 1119        }
 1120    }
 1121
 1122    fn language_servers_for_buffer<'a>(
 1123        &'a self,
 1124        buffer: &'a Buffer,
 1125        cx: &'a mut App,
 1126    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1127        self.language_server_ids_for_buffer(buffer, cx)
 1128            .into_iter()
 1129            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1130                LanguageServerState::Running {
 1131                    adapter, server, ..
 1132                } => Some((adapter, server)),
 1133                _ => None,
 1134            })
 1135    }
 1136
 1137    async fn execute_code_action_kind_locally(
 1138        lsp_store: WeakEntity<LspStore>,
 1139        mut buffers: Vec<Entity<Buffer>>,
 1140        kind: CodeActionKind,
 1141        push_to_history: bool,
 1142        cx: &mut AsyncApp,
 1143    ) -> anyhow::Result<ProjectTransaction> {
 1144        // Do not allow multiple concurrent code actions requests for the
 1145        // same buffer.
 1146        lsp_store.update(cx, |this, cx| {
 1147            let this = this.as_local_mut().unwrap();
 1148            buffers.retain(|buffer| {
 1149                this.buffers_being_formatted
 1150                    .insert(buffer.read(cx).remote_id())
 1151            });
 1152        })?;
 1153        let _cleanup = defer({
 1154            let this = lsp_store.clone();
 1155            let mut cx = cx.clone();
 1156            let buffers = &buffers;
 1157            move || {
 1158                this.update(&mut cx, |this, cx| {
 1159                    let this = this.as_local_mut().unwrap();
 1160                    for buffer in buffers {
 1161                        this.buffers_being_formatted
 1162                            .remove(&buffer.read(cx).remote_id());
 1163                    }
 1164                })
 1165                .ok();
 1166            }
 1167        });
 1168        let mut project_transaction = ProjectTransaction::default();
 1169
 1170        for buffer in &buffers {
 1171            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1172                buffer.update(cx, |buffer, cx| {
 1173                    lsp_store
 1174                        .as_local()
 1175                        .unwrap()
 1176                        .language_servers_for_buffer(buffer, cx)
 1177                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1178                        .collect::<Vec<_>>()
 1179                })
 1180            })?;
 1181            for (_, language_server) in adapters_and_servers.iter() {
 1182                let actions = Self::get_server_code_actions_from_action_kinds(
 1183                    &lsp_store,
 1184                    language_server.server_id(),
 1185                    vec![kind.clone()],
 1186                    buffer,
 1187                    cx,
 1188                )
 1189                .await?;
 1190                Self::execute_code_actions_on_server(
 1191                    &lsp_store,
 1192                    language_server,
 1193                    actions,
 1194                    push_to_history,
 1195                    &mut project_transaction,
 1196                    cx,
 1197                )
 1198                .await?;
 1199            }
 1200        }
 1201        Ok(project_transaction)
 1202    }
 1203
 1204    async fn format_locally(
 1205        lsp_store: WeakEntity<LspStore>,
 1206        mut buffers: Vec<FormattableBuffer>,
 1207        push_to_history: bool,
 1208        trigger: FormatTrigger,
 1209        logger: zlog::Logger,
 1210        cx: &mut AsyncApp,
 1211    ) -> anyhow::Result<ProjectTransaction> {
 1212        // Do not allow multiple concurrent formatting requests for the
 1213        // same buffer.
 1214        lsp_store.update(cx, |this, cx| {
 1215            let this = this.as_local_mut().unwrap();
 1216            buffers.retain(|buffer| {
 1217                this.buffers_being_formatted
 1218                    .insert(buffer.handle.read(cx).remote_id())
 1219            });
 1220        })?;
 1221
 1222        let _cleanup = defer({
 1223            let this = lsp_store.clone();
 1224            let mut cx = cx.clone();
 1225            let buffers = &buffers;
 1226            move || {
 1227                this.update(&mut cx, |this, cx| {
 1228                    let this = this.as_local_mut().unwrap();
 1229                    for buffer in buffers {
 1230                        this.buffers_being_formatted
 1231                            .remove(&buffer.handle.read(cx).remote_id());
 1232                    }
 1233                })
 1234                .ok();
 1235            }
 1236        });
 1237
 1238        let mut project_transaction = ProjectTransaction::default();
 1239
 1240        for buffer in &buffers {
 1241            zlog::debug!(
 1242                logger =>
 1243                "formatting buffer '{:?}'",
 1244                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1245            );
 1246            // Create an empty transaction to hold all of the formatting edits.
 1247            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1248                // ensure no transactions created while formatting are
 1249                // grouped with the previous transaction in the history
 1250                // based on the transaction group interval
 1251                buffer.finalize_last_transaction();
 1252                buffer
 1253                    .start_transaction()
 1254                    .context("transaction already open")?;
 1255                buffer.end_transaction(cx);
 1256                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1257                buffer.finalize_last_transaction();
 1258                anyhow::Ok(transaction_id)
 1259            })??;
 1260
 1261            let result = Self::format_buffer_locally(
 1262                lsp_store.clone(),
 1263                buffer,
 1264                formatting_transaction_id,
 1265                trigger,
 1266                logger,
 1267                cx,
 1268            )
 1269            .await;
 1270
 1271            buffer.handle.update(cx, |buffer, cx| {
 1272                let Some(formatting_transaction) =
 1273                    buffer.get_transaction(formatting_transaction_id).cloned()
 1274                else {
 1275                    zlog::warn!(logger => "no formatting transaction");
 1276                    return;
 1277                };
 1278                if formatting_transaction.edit_ids.is_empty() {
 1279                    zlog::debug!(logger => "no changes made while formatting");
 1280                    buffer.forget_transaction(formatting_transaction_id);
 1281                    return;
 1282                }
 1283                if !push_to_history {
 1284                    zlog::trace!(logger => "forgetting format transaction");
 1285                    buffer.forget_transaction(formatting_transaction.id);
 1286                }
 1287                project_transaction
 1288                    .0
 1289                    .insert(cx.entity(), formatting_transaction);
 1290            })?;
 1291
 1292            result?;
 1293        }
 1294
 1295        Ok(project_transaction)
 1296    }
 1297
 1298    async fn format_buffer_locally(
 1299        lsp_store: WeakEntity<LspStore>,
 1300        buffer: &FormattableBuffer,
 1301        formatting_transaction_id: clock::Lamport,
 1302        trigger: FormatTrigger,
 1303        logger: zlog::Logger,
 1304        cx: &mut AsyncApp,
 1305    ) -> Result<()> {
 1306        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1307            buffer.handle.update(cx, |buffer, cx| {
 1308                let adapters_and_servers = lsp_store
 1309                    .as_local()
 1310                    .unwrap()
 1311                    .language_servers_for_buffer(buffer, cx)
 1312                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1313                    .collect::<Vec<_>>();
 1314                let settings =
 1315                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1316                        .into_owned();
 1317                (adapters_and_servers, settings)
 1318            })
 1319        })?;
 1320
 1321        /// Apply edits to the buffer that will become part of the formatting transaction.
 1322        /// Fails if the buffer has been edited since the start of that transaction.
 1323        fn extend_formatting_transaction(
 1324            buffer: &FormattableBuffer,
 1325            formatting_transaction_id: text::TransactionId,
 1326            cx: &mut AsyncApp,
 1327            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1328        ) -> anyhow::Result<()> {
 1329            buffer.handle.update(cx, |buffer, cx| {
 1330                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1331                if last_transaction_id != Some(formatting_transaction_id) {
 1332                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1333                }
 1334                buffer.start_transaction();
 1335                operation(buffer, cx);
 1336                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1337                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1338                }
 1339                Ok(())
 1340            })?
 1341        }
 1342
 1343        // handle whitespace formatting
 1344        if settings.remove_trailing_whitespace_on_save {
 1345            zlog::trace!(logger => "removing trailing whitespace");
 1346            let diff = buffer
 1347                .handle
 1348                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1349                .await;
 1350            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1351                buffer.apply_diff(diff, cx);
 1352            })?;
 1353        }
 1354
 1355        if settings.ensure_final_newline_on_save {
 1356            zlog::trace!(logger => "ensuring final newline");
 1357            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1358                buffer.ensure_final_newline(cx);
 1359            })?;
 1360        }
 1361
 1362        // Formatter for `code_actions_on_format` that runs before
 1363        // the rest of the formatters
 1364        let mut code_actions_on_format_formatters = None;
 1365        let should_run_code_actions_on_format = !matches!(
 1366            (trigger, &settings.format_on_save),
 1367            (FormatTrigger::Save, &FormatOnSave::Off)
 1368        );
 1369        if should_run_code_actions_on_format {
 1370            let have_code_actions_to_run_on_format = settings
 1371                .code_actions_on_format
 1372                .values()
 1373                .any(|enabled| *enabled);
 1374            if have_code_actions_to_run_on_format {
 1375                zlog::trace!(logger => "going to run code actions on format");
 1376                code_actions_on_format_formatters = Some(
 1377                    settings
 1378                        .code_actions_on_format
 1379                        .iter()
 1380                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1381                        .cloned()
 1382                        .map(Formatter::CodeAction)
 1383                        .collect::<Vec<_>>(),
 1384                );
 1385            }
 1386        }
 1387
 1388        let formatters = match (trigger, &settings.format_on_save) {
 1389            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1390            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1391                settings.formatter.as_ref()
 1392            }
 1393        };
 1394
 1395        let formatters = code_actions_on_format_formatters
 1396            .iter()
 1397            .flatten()
 1398            .chain(formatters);
 1399
 1400        for formatter in formatters {
 1401            let formatter = if formatter == &Formatter::Auto {
 1402                if settings.prettier.allowed {
 1403                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1404                    &Formatter::Prettier
 1405                } else {
 1406                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1407                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1408                }
 1409            } else {
 1410                formatter
 1411            };
 1412            match formatter {
 1413                Formatter::Auto => unreachable!("Auto resolved above"),
 1414                Formatter::Prettier => {
 1415                    let logger = zlog::scoped!(logger => "prettier");
 1416                    zlog::trace!(logger => "formatting");
 1417                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1418
 1419                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1420                        lsp_store.prettier_store().unwrap().downgrade()
 1421                    })?;
 1422                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1423                        .await
 1424                        .transpose()?;
 1425                    let Some(diff) = diff else {
 1426                        zlog::trace!(logger => "No changes");
 1427                        continue;
 1428                    };
 1429
 1430                    extend_formatting_transaction(
 1431                        buffer,
 1432                        formatting_transaction_id,
 1433                        cx,
 1434                        |buffer, cx| {
 1435                            buffer.apply_diff(diff, cx);
 1436                        },
 1437                    )?;
 1438                }
 1439                Formatter::External { command, arguments } => {
 1440                    let logger = zlog::scoped!(logger => "command");
 1441                    zlog::trace!(logger => "formatting");
 1442                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1443
 1444                    let diff = Self::format_via_external_command(
 1445                        buffer,
 1446                        command.as_ref(),
 1447                        arguments.as_deref(),
 1448                        cx,
 1449                    )
 1450                    .await
 1451                    .with_context(|| {
 1452                        format!("Failed to format buffer via external command: {}", command)
 1453                    })?;
 1454                    let Some(diff) = diff else {
 1455                        zlog::trace!(logger => "No changes");
 1456                        continue;
 1457                    };
 1458
 1459                    extend_formatting_transaction(
 1460                        buffer,
 1461                        formatting_transaction_id,
 1462                        cx,
 1463                        |buffer, cx| {
 1464                            buffer.apply_diff(diff, cx);
 1465                        },
 1466                    )?;
 1467                }
 1468                Formatter::LanguageServer(specifier) => {
 1469                    let logger = zlog::scoped!(logger => "language-server");
 1470                    zlog::trace!(logger => "formatting");
 1471                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1472
 1473                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1474                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1475                        continue;
 1476                    };
 1477
 1478                    let language_server = match specifier {
 1479                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1480                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1481                                if adapter.name.0.as_ref() == name {
 1482                                    Some(server.clone())
 1483                                } else {
 1484                                    None
 1485                                }
 1486                            })
 1487                        }
 1488                        settings::LanguageServerFormatterSpecifier::Current => {
 1489                            adapters_and_servers.first().map(|e| e.1.clone())
 1490                        }
 1491                    };
 1492
 1493                    let Some(language_server) = language_server else {
 1494                        log::debug!(
 1495                            "No language server found to format buffer '{:?}'. Skipping",
 1496                            buffer_path_abs.as_path().to_string_lossy()
 1497                        );
 1498                        continue;
 1499                    };
 1500
 1501                    zlog::trace!(
 1502                        logger =>
 1503                        "Formatting buffer '{:?}' using language server '{:?}'",
 1504                        buffer_path_abs.as_path().to_string_lossy(),
 1505                        language_server.name()
 1506                    );
 1507
 1508                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1509                        zlog::trace!(logger => "formatting ranges");
 1510                        Self::format_ranges_via_lsp(
 1511                            &lsp_store,
 1512                            &buffer.handle,
 1513                            ranges,
 1514                            buffer_path_abs,
 1515                            &language_server,
 1516                            &settings,
 1517                            cx,
 1518                        )
 1519                        .await
 1520                        .context("Failed to format ranges via language server")?
 1521                    } else {
 1522                        zlog::trace!(logger => "formatting full");
 1523                        Self::format_via_lsp(
 1524                            &lsp_store,
 1525                            &buffer.handle,
 1526                            buffer_path_abs,
 1527                            &language_server,
 1528                            &settings,
 1529                            cx,
 1530                        )
 1531                        .await
 1532                        .context("failed to format via language server")?
 1533                    };
 1534
 1535                    if edits.is_empty() {
 1536                        zlog::trace!(logger => "No changes");
 1537                        continue;
 1538                    }
 1539                    extend_formatting_transaction(
 1540                        buffer,
 1541                        formatting_transaction_id,
 1542                        cx,
 1543                        |buffer, cx| {
 1544                            buffer.edit(edits, None, cx);
 1545                        },
 1546                    )?;
 1547                }
 1548                Formatter::CodeAction(code_action_name) => {
 1549                    let logger = zlog::scoped!(logger => "code-actions");
 1550                    zlog::trace!(logger => "formatting");
 1551                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1552
 1553                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1554                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1555                        continue;
 1556                    };
 1557
 1558                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1559                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1560
 1561                    let mut actions_and_servers = Vec::new();
 1562
 1563                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1564                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1565                            &lsp_store,
 1566                            language_server.server_id(),
 1567                            vec![code_action_kind.clone()],
 1568                            &buffer.handle,
 1569                            cx,
 1570                        )
 1571                        .await
 1572                        .with_context(|| {
 1573                            format!(
 1574                                "Failed to resolve code action {:?} with language server {}",
 1575                                code_action_kind,
 1576                                language_server.name()
 1577                            )
 1578                        });
 1579                        let Ok(actions) = actions_result else {
 1580                            // note: it may be better to set result to the error and break formatters here
 1581                            // but for now we try to execute the actions that we can resolve and skip the rest
 1582                            zlog::error!(
 1583                                logger =>
 1584                                "Failed to resolve code action {:?} with language server {}",
 1585                                code_action_kind,
 1586                                language_server.name()
 1587                            );
 1588                            continue;
 1589                        };
 1590                        for action in actions {
 1591                            actions_and_servers.push((action, index));
 1592                        }
 1593                    }
 1594
 1595                    if actions_and_servers.is_empty() {
 1596                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1597                        continue;
 1598                    }
 1599
 1600                    'actions: for (mut action, server_index) in actions_and_servers {
 1601                        let server = &adapters_and_servers[server_index].1;
 1602
 1603                        let describe_code_action = |action: &CodeAction| {
 1604                            format!(
 1605                                "code action '{}' with title \"{}\" on server {}",
 1606                                action
 1607                                    .lsp_action
 1608                                    .action_kind()
 1609                                    .unwrap_or("unknown".into())
 1610                                    .as_str(),
 1611                                action.lsp_action.title(),
 1612                                server.name(),
 1613                            )
 1614                        };
 1615
 1616                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1617
 1618                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1619                            zlog::error!(
 1620                                logger =>
 1621                                "Failed to resolve {}. Error: {}",
 1622                                describe_code_action(&action),
 1623                                err
 1624                            );
 1625                            continue;
 1626                        }
 1627
 1628                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1629                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1630                            // but filters out and logs warnings for code actions that require unreasonably
 1631                            // difficult handling on our part, such as:
 1632                            // - applying edits that call commands
 1633                            //   which can result in arbitrary workspace edits being sent from the server that
 1634                            //   have no way of being tied back to the command that initiated them (i.e. we
 1635                            //   can't know which edits are part of the format request, or if the server is done sending
 1636                            //   actions in response to the command)
 1637                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1638                            //   as we then would need to handle such changes correctly in the local history as well
 1639                            //   as the remote history through the ProjectTransaction
 1640                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1641                            // Supporting these actions is not impossible, but not supported as of yet.
 1642                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1643                                zlog::trace!(
 1644                                    logger =>
 1645                                    "No changes for code action. Skipping {}",
 1646                                    describe_code_action(&action),
 1647                                );
 1648                                continue;
 1649                            }
 1650
 1651                            let mut operations = Vec::new();
 1652                            if let Some(document_changes) = edit.document_changes {
 1653                                match document_changes {
 1654                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1655                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1656                                    ),
 1657                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1658                                }
 1659                            } else if let Some(changes) = edit.changes {
 1660                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1661                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1662                                        text_document:
 1663                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1664                                                uri,
 1665                                                version: None,
 1666                                            },
 1667                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1668                                    })
 1669                                }));
 1670                            }
 1671
 1672                            let mut edits = Vec::with_capacity(operations.len());
 1673
 1674                            if operations.is_empty() {
 1675                                zlog::trace!(
 1676                                    logger =>
 1677                                    "No changes for code action. Skipping {}",
 1678                                    describe_code_action(&action),
 1679                                );
 1680                                continue;
 1681                            }
 1682                            for operation in operations {
 1683                                let op = match operation {
 1684                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1685                                    lsp::DocumentChangeOperation::Op(_) => {
 1686                                        zlog::warn!(
 1687                                            logger =>
 1688                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1689                                            describe_code_action(&action),
 1690                                        );
 1691                                        continue 'actions;
 1692                                    }
 1693                                };
 1694                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1695                                    zlog::warn!(
 1696                                        logger =>
 1697                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1698                                        &op.text_document.uri,
 1699                                        describe_code_action(&action),
 1700                                    );
 1701                                    continue 'actions;
 1702                                };
 1703                                if &file_path != buffer_path_abs {
 1704                                    zlog::warn!(
 1705                                        logger =>
 1706                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1707                                        file_path,
 1708                                        buffer_path_abs,
 1709                                        describe_code_action(&action),
 1710                                    );
 1711                                    continue 'actions;
 1712                                }
 1713
 1714                                let mut lsp_edits = Vec::new();
 1715                                for edit in op.edits {
 1716                                    match edit {
 1717                                        Edit::Plain(edit) => {
 1718                                            if !lsp_edits.contains(&edit) {
 1719                                                lsp_edits.push(edit);
 1720                                            }
 1721                                        }
 1722                                        Edit::Annotated(edit) => {
 1723                                            if !lsp_edits.contains(&edit.text_edit) {
 1724                                                lsp_edits.push(edit.text_edit);
 1725                                            }
 1726                                        }
 1727                                        Edit::Snippet(_) => {
 1728                                            zlog::warn!(
 1729                                                logger =>
 1730                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1731                                                describe_code_action(&action),
 1732                                            );
 1733                                            continue 'actions;
 1734                                        }
 1735                                    }
 1736                                }
 1737                                let edits_result = lsp_store
 1738                                    .update(cx, |lsp_store, cx| {
 1739                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1740                                            &buffer.handle,
 1741                                            lsp_edits,
 1742                                            server.server_id(),
 1743                                            op.text_document.version,
 1744                                            cx,
 1745                                        )
 1746                                    })?
 1747                                    .await;
 1748                                let Ok(resolved_edits) = edits_result else {
 1749                                    zlog::warn!(
 1750                                        logger =>
 1751                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1752                                        buffer_path_abs.as_path(),
 1753                                        describe_code_action(&action),
 1754                                    );
 1755                                    continue 'actions;
 1756                                };
 1757                                edits.extend(resolved_edits);
 1758                            }
 1759
 1760                            if edits.is_empty() {
 1761                                zlog::warn!(logger => "No edits resolved from LSP");
 1762                                continue;
 1763                            }
 1764
 1765                            extend_formatting_transaction(
 1766                                buffer,
 1767                                formatting_transaction_id,
 1768                                cx,
 1769                                |buffer, cx| {
 1770                                    zlog::info!(
 1771                                        "Applying edits {edits:?}. Content: {:?}",
 1772                                        buffer.text()
 1773                                    );
 1774                                    buffer.edit(edits, None, cx);
 1775                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1776                                },
 1777                            )?;
 1778                        }
 1779
 1780                        if let Some(command) = action.lsp_action.command() {
 1781                            zlog::warn!(
 1782                                logger =>
 1783                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1784                                &command.command,
 1785                            );
 1786
 1787                            // bail early if command is invalid
 1788                            let server_capabilities = server.capabilities();
 1789                            let available_commands = server_capabilities
 1790                                .execute_command_provider
 1791                                .as_ref()
 1792                                .map(|options| options.commands.as_slice())
 1793                                .unwrap_or_default();
 1794                            if !available_commands.contains(&command.command) {
 1795                                zlog::warn!(
 1796                                    logger =>
 1797                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1798                                    command.command,
 1799                                    server.name(),
 1800                                );
 1801                                continue;
 1802                            }
 1803
 1804                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1805                            extend_formatting_transaction(
 1806                                buffer,
 1807                                formatting_transaction_id,
 1808                                cx,
 1809                                |_, _| {},
 1810                            )?;
 1811                            zlog::info!(logger => "Executing command {}", &command.command);
 1812
 1813                            lsp_store.update(cx, |this, _| {
 1814                                this.as_local_mut()
 1815                                    .unwrap()
 1816                                    .last_workspace_edits_by_language_server
 1817                                    .remove(&server.server_id());
 1818                            })?;
 1819
 1820                            let execute_command_result = server
 1821                                .request::<lsp::request::ExecuteCommand>(
 1822                                    lsp::ExecuteCommandParams {
 1823                                        command: command.command.clone(),
 1824                                        arguments: command.arguments.clone().unwrap_or_default(),
 1825                                        ..Default::default()
 1826                                    },
 1827                                )
 1828                                .await
 1829                                .into_response();
 1830
 1831                            if execute_command_result.is_err() {
 1832                                zlog::error!(
 1833                                    logger =>
 1834                                    "Failed to execute command '{}' as part of {}",
 1835                                    &command.command,
 1836                                    describe_code_action(&action),
 1837                                );
 1838                                continue 'actions;
 1839                            }
 1840
 1841                            let mut project_transaction_command =
 1842                                lsp_store.update(cx, |this, _| {
 1843                                    this.as_local_mut()
 1844                                        .unwrap()
 1845                                        .last_workspace_edits_by_language_server
 1846                                        .remove(&server.server_id())
 1847                                        .unwrap_or_default()
 1848                                })?;
 1849
 1850                            if let Some(transaction) =
 1851                                project_transaction_command.0.remove(&buffer.handle)
 1852                            {
 1853                                zlog::trace!(
 1854                                    logger =>
 1855                                    "Successfully captured {} edits that resulted from command {}",
 1856                                    transaction.edit_ids.len(),
 1857                                    &command.command,
 1858                                );
 1859                                let transaction_id_project_transaction = transaction.id;
 1860                                buffer.handle.update(cx, |buffer, _| {
 1861                                    // it may have been removed from history if push_to_history was
 1862                                    // false in deserialize_workspace_edit. If so push it so we
 1863                                    // can merge it with the format transaction
 1864                                    // and pop the combined transaction off the history stack
 1865                                    // later if push_to_history is false
 1866                                    if buffer.get_transaction(transaction.id).is_none() {
 1867                                        buffer.push_transaction(transaction, Instant::now());
 1868                                    }
 1869                                    buffer.merge_transactions(
 1870                                        transaction_id_project_transaction,
 1871                                        formatting_transaction_id,
 1872                                    );
 1873                                })?;
 1874                            }
 1875
 1876                            if !project_transaction_command.0.is_empty() {
 1877                                let mut extra_buffers = String::new();
 1878                                for buffer in project_transaction_command.0.keys() {
 1879                                    buffer
 1880                                        .read_with(cx, |b, cx| {
 1881                                            if let Some(path) = b.project_path(cx) {
 1882                                                if !extra_buffers.is_empty() {
 1883                                                    extra_buffers.push_str(", ");
 1884                                                }
 1885                                                extra_buffers.push_str(path.path.as_unix_str());
 1886                                            }
 1887                                        })
 1888                                        .ok();
 1889                                }
 1890                                zlog::warn!(
 1891                                    logger =>
 1892                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1893                                    &command.command,
 1894                                    extra_buffers,
 1895                                );
 1896                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1897                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1898                                // add it so it's included, and merge it into the format transaction when its created later
 1899                            }
 1900                        }
 1901                    }
 1902                }
 1903            }
 1904        }
 1905
 1906        Ok(())
 1907    }
 1908
 1909    pub async fn format_ranges_via_lsp(
 1910        this: &WeakEntity<LspStore>,
 1911        buffer_handle: &Entity<Buffer>,
 1912        ranges: &[Range<Anchor>],
 1913        abs_path: &Path,
 1914        language_server: &Arc<LanguageServer>,
 1915        settings: &LanguageSettings,
 1916        cx: &mut AsyncApp,
 1917    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1918        let capabilities = &language_server.capabilities();
 1919        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1920        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1921            anyhow::bail!(
 1922                "{} language server does not support range formatting",
 1923                language_server.name()
 1924            );
 1925        }
 1926
 1927        let uri = file_path_to_lsp_url(abs_path)?;
 1928        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1929
 1930        let lsp_edits = {
 1931            let mut lsp_ranges = Vec::new();
 1932            this.update(cx, |_this, cx| {
 1933                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1934                // not have been sent to the language server. This seems like a fairly systemic
 1935                // issue, though, the resolution probably is not specific to formatting.
 1936                //
 1937                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1938                // LSP.
 1939                let snapshot = buffer_handle.read(cx).snapshot();
 1940                for range in ranges {
 1941                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1942                }
 1943                anyhow::Ok(())
 1944            })??;
 1945
 1946            let mut edits = None;
 1947            for range in lsp_ranges {
 1948                if let Some(mut edit) = language_server
 1949                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1950                        text_document: text_document.clone(),
 1951                        range,
 1952                        options: lsp_command::lsp_formatting_options(settings),
 1953                        work_done_progress_params: Default::default(),
 1954                    })
 1955                    .await
 1956                    .into_response()?
 1957                {
 1958                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 1959                }
 1960            }
 1961            edits
 1962        };
 1963
 1964        if let Some(lsp_edits) = lsp_edits {
 1965            this.update(cx, |this, cx| {
 1966                this.as_local_mut().unwrap().edits_from_lsp(
 1967                    buffer_handle,
 1968                    lsp_edits,
 1969                    language_server.server_id(),
 1970                    None,
 1971                    cx,
 1972                )
 1973            })?
 1974            .await
 1975        } else {
 1976            Ok(Vec::with_capacity(0))
 1977        }
 1978    }
 1979
 1980    async fn format_via_lsp(
 1981        this: &WeakEntity<LspStore>,
 1982        buffer: &Entity<Buffer>,
 1983        abs_path: &Path,
 1984        language_server: &Arc<LanguageServer>,
 1985        settings: &LanguageSettings,
 1986        cx: &mut AsyncApp,
 1987    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1988        let logger = zlog::scoped!("lsp_format");
 1989        zlog::info!(logger => "Formatting via LSP");
 1990
 1991        let uri = file_path_to_lsp_url(abs_path)?;
 1992        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1993        let capabilities = &language_server.capabilities();
 1994
 1995        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 1996        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1997
 1998        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1999            let _timer = zlog::time!(logger => "format-full");
 2000            language_server
 2001                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2002                    text_document,
 2003                    options: lsp_command::lsp_formatting_options(settings),
 2004                    work_done_progress_params: Default::default(),
 2005                })
 2006                .await
 2007                .into_response()?
 2008        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2009            let _timer = zlog::time!(logger => "format-range");
 2010            let buffer_start = lsp::Position::new(0, 0);
 2011            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2012            language_server
 2013                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2014                    text_document: text_document.clone(),
 2015                    range: lsp::Range::new(buffer_start, buffer_end),
 2016                    options: lsp_command::lsp_formatting_options(settings),
 2017                    work_done_progress_params: Default::default(),
 2018                })
 2019                .await
 2020                .into_response()?
 2021        } else {
 2022            None
 2023        };
 2024
 2025        if let Some(lsp_edits) = lsp_edits {
 2026            this.update(cx, |this, cx| {
 2027                this.as_local_mut().unwrap().edits_from_lsp(
 2028                    buffer,
 2029                    lsp_edits,
 2030                    language_server.server_id(),
 2031                    None,
 2032                    cx,
 2033                )
 2034            })?
 2035            .await
 2036        } else {
 2037            Ok(Vec::with_capacity(0))
 2038        }
 2039    }
 2040
 2041    async fn format_via_external_command(
 2042        buffer: &FormattableBuffer,
 2043        command: &str,
 2044        arguments: Option<&[String]>,
 2045        cx: &mut AsyncApp,
 2046    ) -> Result<Option<Diff>> {
 2047        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2048            let file = File::from_dyn(buffer.file())?;
 2049            let worktree = file.worktree.read(cx);
 2050            let mut worktree_path = worktree.abs_path().to_path_buf();
 2051            if worktree.root_entry()?.is_file() {
 2052                worktree_path.pop();
 2053            }
 2054            Some(worktree_path)
 2055        })?;
 2056
 2057        let mut child = util::command::new_smol_command(command);
 2058
 2059        if let Some(buffer_env) = buffer.env.as_ref() {
 2060            child.envs(buffer_env);
 2061        }
 2062
 2063        if let Some(working_dir_path) = working_dir_path {
 2064            child.current_dir(working_dir_path);
 2065        }
 2066
 2067        if let Some(arguments) = arguments {
 2068            child.args(arguments.iter().map(|arg| {
 2069                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2070                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2071                } else {
 2072                    arg.replace("{buffer_path}", "Untitled")
 2073                }
 2074            }));
 2075        }
 2076
 2077        let mut child = child
 2078            .stdin(smol::process::Stdio::piped())
 2079            .stdout(smol::process::Stdio::piped())
 2080            .stderr(smol::process::Stdio::piped())
 2081            .spawn()?;
 2082
 2083        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2084        let text = buffer
 2085            .handle
 2086            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2087        for chunk in text.chunks() {
 2088            stdin.write_all(chunk.as_bytes()).await?;
 2089        }
 2090        stdin.flush().await?;
 2091
 2092        let output = child.output().await?;
 2093        anyhow::ensure!(
 2094            output.status.success(),
 2095            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2096            output.status.code(),
 2097            String::from_utf8_lossy(&output.stdout),
 2098            String::from_utf8_lossy(&output.stderr),
 2099        );
 2100
 2101        let stdout = String::from_utf8(output.stdout)?;
 2102        Ok(Some(
 2103            buffer
 2104                .handle
 2105                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2106                .await,
 2107        ))
 2108    }
 2109
 2110    async fn try_resolve_code_action(
 2111        lang_server: &LanguageServer,
 2112        action: &mut CodeAction,
 2113    ) -> anyhow::Result<()> {
 2114        match &mut action.lsp_action {
 2115            LspAction::Action(lsp_action) => {
 2116                if !action.resolved
 2117                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2118                    && lsp_action.data.is_some()
 2119                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2120                {
 2121                    *lsp_action = Box::new(
 2122                        lang_server
 2123                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2124                            .await
 2125                            .into_response()?,
 2126                    );
 2127                }
 2128            }
 2129            LspAction::CodeLens(lens) => {
 2130                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2131                    *lens = lang_server
 2132                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2133                        .await
 2134                        .into_response()?;
 2135                }
 2136            }
 2137            LspAction::Command(_) => {}
 2138        }
 2139
 2140        action.resolved = true;
 2141        anyhow::Ok(())
 2142    }
 2143
 2144    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2145        let buffer = buffer_handle.read(cx);
 2146
 2147        let file = buffer.file().cloned();
 2148
 2149        let Some(file) = File::from_dyn(file.as_ref()) else {
 2150            return;
 2151        };
 2152        if !file.is_local() {
 2153            return;
 2154        }
 2155        let path = ProjectPath::from_file(file, cx);
 2156        let worktree_id = file.worktree_id(cx);
 2157        let language = buffer.language().cloned();
 2158
 2159        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2160            for (server_id, diagnostics) in
 2161                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2162            {
 2163                self.update_buffer_diagnostics(
 2164                    buffer_handle,
 2165                    server_id,
 2166                    None,
 2167                    None,
 2168                    diagnostics,
 2169                    Vec::new(),
 2170                    cx,
 2171                )
 2172                .log_err();
 2173            }
 2174        }
 2175        let Some(language) = language else {
 2176            return;
 2177        };
 2178        let Some(snapshot) = self
 2179            .worktree_store
 2180            .read(cx)
 2181            .worktree_for_id(worktree_id, cx)
 2182            .map(|worktree| worktree.read(cx).snapshot())
 2183        else {
 2184            return;
 2185        };
 2186        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2187
 2188        for server_id in
 2189            self.lsp_tree
 2190                .get(path, language.name(), language.manifest(), &delegate, cx)
 2191        {
 2192            let server = self
 2193                .language_servers
 2194                .get(&server_id)
 2195                .and_then(|server_state| {
 2196                    if let LanguageServerState::Running { server, .. } = server_state {
 2197                        Some(server.clone())
 2198                    } else {
 2199                        None
 2200                    }
 2201                });
 2202            let server = match server {
 2203                Some(server) => server,
 2204                None => continue,
 2205            };
 2206
 2207            buffer_handle.update(cx, |buffer, cx| {
 2208                buffer.set_completion_triggers(
 2209                    server.server_id(),
 2210                    server
 2211                        .capabilities()
 2212                        .completion_provider
 2213                        .as_ref()
 2214                        .and_then(|provider| {
 2215                            provider
 2216                                .trigger_characters
 2217                                .as_ref()
 2218                                .map(|characters| characters.iter().cloned().collect())
 2219                        })
 2220                        .unwrap_or_default(),
 2221                    cx,
 2222                );
 2223            });
 2224        }
 2225    }
 2226
 2227    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2228        buffer.update(cx, |buffer, cx| {
 2229            let Some(language) = buffer.language() else {
 2230                return;
 2231            };
 2232            let path = ProjectPath {
 2233                worktree_id: old_file.worktree_id(cx),
 2234                path: old_file.path.clone(),
 2235            };
 2236            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2237                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2238                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2239            }
 2240        });
 2241    }
 2242
 2243    fn update_buffer_diagnostics(
 2244        &mut self,
 2245        buffer: &Entity<Buffer>,
 2246        server_id: LanguageServerId,
 2247        result_id: Option<String>,
 2248        version: Option<i32>,
 2249        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2250        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2251        cx: &mut Context<LspStore>,
 2252    ) -> Result<()> {
 2253        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2254            Ordering::Equal
 2255                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2256                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2257                .then_with(|| a.severity.cmp(&b.severity))
 2258                .then_with(|| a.message.cmp(&b.message))
 2259        }
 2260
 2261        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2262        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2263        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2264
 2265        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2266            Ordering::Equal
 2267                .then_with(|| a.range.start.cmp(&b.range.start))
 2268                .then_with(|| b.range.end.cmp(&a.range.end))
 2269                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2270        });
 2271
 2272        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2273
 2274        let edits_since_save = std::cell::LazyCell::new(|| {
 2275            let saved_version = buffer.read(cx).saved_version();
 2276            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2277        });
 2278
 2279        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2280
 2281        for (new_diagnostic, entry) in diagnostics {
 2282            let start;
 2283            let end;
 2284            if new_diagnostic && entry.diagnostic.is_disk_based {
 2285                // Some diagnostics are based on files on disk instead of buffers'
 2286                // current contents. Adjust these diagnostics' ranges to reflect
 2287                // any unsaved edits.
 2288                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2289                // and were properly adjusted on reuse.
 2290                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2291                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2292            } else {
 2293                start = entry.range.start;
 2294                end = entry.range.end;
 2295            }
 2296
 2297            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2298                ..snapshot.clip_point_utf16(end, Bias::Right);
 2299
 2300            // Expand empty ranges by one codepoint
 2301            if range.start == range.end {
 2302                // This will be go to the next boundary when being clipped
 2303                range.end.column += 1;
 2304                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2305                if range.start == range.end && range.end.column > 0 {
 2306                    range.start.column -= 1;
 2307                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2308                }
 2309            }
 2310
 2311            sanitized_diagnostics.push(DiagnosticEntry {
 2312                range,
 2313                diagnostic: entry.diagnostic,
 2314            });
 2315        }
 2316        drop(edits_since_save);
 2317
 2318        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2319        buffer.update(cx, |buffer, cx| {
 2320            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2321                self.buffer_pull_diagnostics_result_ids
 2322                    .entry(server_id)
 2323                    .or_default()
 2324                    .insert(abs_path, result_id);
 2325            }
 2326
 2327            buffer.update_diagnostics(server_id, set, cx)
 2328        });
 2329
 2330        Ok(())
 2331    }
 2332
 2333    fn register_language_server_for_invisible_worktree(
 2334        &mut self,
 2335        worktree: &Entity<Worktree>,
 2336        language_server_id: LanguageServerId,
 2337        cx: &mut App,
 2338    ) {
 2339        let worktree = worktree.read(cx);
 2340        let worktree_id = worktree.id();
 2341        debug_assert!(!worktree.is_visible());
 2342        let Some(mut origin_seed) = self
 2343            .language_server_ids
 2344            .iter()
 2345            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2346        else {
 2347            return;
 2348        };
 2349        origin_seed.worktree_id = worktree_id;
 2350        self.language_server_ids
 2351            .entry(origin_seed)
 2352            .or_insert_with(|| UnifiedLanguageServer {
 2353                id: language_server_id,
 2354                project_roots: Default::default(),
 2355            });
 2356    }
 2357
 2358    fn register_buffer_with_language_servers(
 2359        &mut self,
 2360        buffer_handle: &Entity<Buffer>,
 2361        only_register_servers: HashSet<LanguageServerSelector>,
 2362        cx: &mut Context<LspStore>,
 2363    ) {
 2364        let buffer = buffer_handle.read(cx);
 2365        let buffer_id = buffer.remote_id();
 2366
 2367        let Some(file) = File::from_dyn(buffer.file()) else {
 2368            return;
 2369        };
 2370        if !file.is_local() {
 2371            return;
 2372        }
 2373
 2374        let abs_path = file.abs_path(cx);
 2375        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2376            return;
 2377        };
 2378        let initial_snapshot = buffer.text_snapshot();
 2379        let worktree_id = file.worktree_id(cx);
 2380
 2381        let Some(language) = buffer.language().cloned() else {
 2382            return;
 2383        };
 2384        let path: Arc<RelPath> = file
 2385            .path()
 2386            .parent()
 2387            .map(Arc::from)
 2388            .unwrap_or_else(|| file.path().clone());
 2389        let Some(worktree) = self
 2390            .worktree_store
 2391            .read(cx)
 2392            .worktree_for_id(worktree_id, cx)
 2393        else {
 2394            return;
 2395        };
 2396        let language_name = language.name();
 2397        let (reused, delegate, servers) = self
 2398            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2399            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2400            .unwrap_or_else(|| {
 2401                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2402                let delegate: Arc<dyn ManifestDelegate> =
 2403                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2404
 2405                let servers = self
 2406                    .lsp_tree
 2407                    .walk(
 2408                        ProjectPath { worktree_id, path },
 2409                        language.name(),
 2410                        language.manifest(),
 2411                        &delegate,
 2412                        cx,
 2413                    )
 2414                    .collect::<Vec<_>>();
 2415                (false, lsp_delegate, servers)
 2416            });
 2417        let servers_and_adapters = servers
 2418            .into_iter()
 2419            .filter_map(|server_node| {
 2420                if reused && server_node.server_id().is_none() {
 2421                    return None;
 2422                }
 2423                if !only_register_servers.is_empty() {
 2424                    if let Some(server_id) = server_node.server_id()
 2425                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2426                    {
 2427                        return None;
 2428                    }
 2429                    if let Some(name) = server_node.name()
 2430                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2431                    {
 2432                        return None;
 2433                    }
 2434                }
 2435
 2436                let server_id = server_node.server_id_or_init(|disposition| {
 2437                    let path = &disposition.path;
 2438
 2439                    {
 2440                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2441
 2442                        let server_id = self.get_or_insert_language_server(
 2443                            &worktree,
 2444                            delegate.clone(),
 2445                            disposition,
 2446                            &language_name,
 2447                            cx,
 2448                        );
 2449
 2450                        if let Some(state) = self.language_servers.get(&server_id)
 2451                            && let Ok(uri) = uri
 2452                        {
 2453                            state.add_workspace_folder(uri);
 2454                        };
 2455                        server_id
 2456                    }
 2457                })?;
 2458                let server_state = self.language_servers.get(&server_id)?;
 2459                if let LanguageServerState::Running {
 2460                    server, adapter, ..
 2461                } = server_state
 2462                {
 2463                    Some((server.clone(), adapter.clone()))
 2464                } else {
 2465                    None
 2466                }
 2467            })
 2468            .collect::<Vec<_>>();
 2469        for (server, adapter) in servers_and_adapters {
 2470            buffer_handle.update(cx, |buffer, cx| {
 2471                buffer.set_completion_triggers(
 2472                    server.server_id(),
 2473                    server
 2474                        .capabilities()
 2475                        .completion_provider
 2476                        .as_ref()
 2477                        .and_then(|provider| {
 2478                            provider
 2479                                .trigger_characters
 2480                                .as_ref()
 2481                                .map(|characters| characters.iter().cloned().collect())
 2482                        })
 2483                        .unwrap_or_default(),
 2484                    cx,
 2485                );
 2486            });
 2487
 2488            let snapshot = LspBufferSnapshot {
 2489                version: 0,
 2490                snapshot: initial_snapshot.clone(),
 2491            };
 2492
 2493            let mut registered = false;
 2494            self.buffer_snapshots
 2495                .entry(buffer_id)
 2496                .or_default()
 2497                .entry(server.server_id())
 2498                .or_insert_with(|| {
 2499                    registered = true;
 2500                    server.register_buffer(
 2501                        uri.clone(),
 2502                        adapter.language_id(&language.name()),
 2503                        0,
 2504                        initial_snapshot.text(),
 2505                    );
 2506
 2507                    vec![snapshot]
 2508                });
 2509
 2510            self.buffers_opened_in_servers
 2511                .entry(buffer_id)
 2512                .or_default()
 2513                .insert(server.server_id());
 2514            if registered {
 2515                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2516                    language_server_id: server.server_id(),
 2517                    name: None,
 2518                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2519                        proto::RegisteredForBuffer {
 2520                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2521                            buffer_id: buffer_id.to_proto(),
 2522                        },
 2523                    ),
 2524                });
 2525            }
 2526        }
 2527    }
 2528
 2529    fn reuse_existing_language_server<'lang_name>(
 2530        &self,
 2531        server_tree: &LanguageServerTree,
 2532        worktree: &Entity<Worktree>,
 2533        language_name: &'lang_name LanguageName,
 2534        cx: &mut App,
 2535    ) -> Option<(
 2536        Arc<LocalLspAdapterDelegate>,
 2537        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2538    )> {
 2539        if worktree.read(cx).is_visible() {
 2540            return None;
 2541        }
 2542
 2543        let worktree_store = self.worktree_store.read(cx);
 2544        let servers = server_tree
 2545            .instances
 2546            .iter()
 2547            .filter(|(worktree_id, _)| {
 2548                worktree_store
 2549                    .worktree_for_id(**worktree_id, cx)
 2550                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2551            })
 2552            .flat_map(|(worktree_id, servers)| {
 2553                servers
 2554                    .roots
 2555                    .iter()
 2556                    .flat_map(|(_, language_servers)| language_servers)
 2557                    .map(move |(_, (server_node, server_languages))| {
 2558                        (worktree_id, server_node, server_languages)
 2559                    })
 2560                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2561                    .map(|(worktree_id, server_node, _)| {
 2562                        (
 2563                            *worktree_id,
 2564                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2565                        )
 2566                    })
 2567            })
 2568            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2569                acc.entry(worktree_id)
 2570                    .or_insert_with(Vec::new)
 2571                    .push(server_node);
 2572                acc
 2573            })
 2574            .into_values()
 2575            .max_by_key(|servers| servers.len())?;
 2576
 2577        let worktree_id = worktree.read(cx).id();
 2578        let apply = move |tree: &mut LanguageServerTree| {
 2579            for server_node in &servers {
 2580                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2581            }
 2582            servers
 2583        };
 2584
 2585        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2586        Some((delegate, apply))
 2587    }
 2588
 2589    pub(crate) fn unregister_old_buffer_from_language_servers(
 2590        &mut self,
 2591        buffer: &Entity<Buffer>,
 2592        old_file: &File,
 2593        cx: &mut App,
 2594    ) {
 2595        let old_path = match old_file.as_local() {
 2596            Some(local) => local.abs_path(cx),
 2597            None => return,
 2598        };
 2599
 2600        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2601            debug_panic!("{old_path:?} is not parseable as an URI");
 2602            return;
 2603        };
 2604        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2605    }
 2606
 2607    pub(crate) fn unregister_buffer_from_language_servers(
 2608        &mut self,
 2609        buffer: &Entity<Buffer>,
 2610        file_url: &lsp::Uri,
 2611        cx: &mut App,
 2612    ) {
 2613        buffer.update(cx, |buffer, cx| {
 2614            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2615
 2616            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2617                language_server.unregister_buffer(file_url.clone());
 2618            }
 2619        });
 2620    }
 2621
 2622    fn buffer_snapshot_for_lsp_version(
 2623        &mut self,
 2624        buffer: &Entity<Buffer>,
 2625        server_id: LanguageServerId,
 2626        version: Option<i32>,
 2627        cx: &App,
 2628    ) -> Result<TextBufferSnapshot> {
 2629        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2630
 2631        if let Some(version) = version {
 2632            let buffer_id = buffer.read(cx).remote_id();
 2633            let snapshots = if let Some(snapshots) = self
 2634                .buffer_snapshots
 2635                .get_mut(&buffer_id)
 2636                .and_then(|m| m.get_mut(&server_id))
 2637            {
 2638                snapshots
 2639            } else if version == 0 {
 2640                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2641                // We detect this case and treat it as if the version was `None`.
 2642                return Ok(buffer.read(cx).text_snapshot());
 2643            } else {
 2644                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2645            };
 2646
 2647            let found_snapshot = snapshots
 2648                    .binary_search_by_key(&version, |e| e.version)
 2649                    .map(|ix| snapshots[ix].snapshot.clone())
 2650                    .map_err(|_| {
 2651                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2652                    })?;
 2653
 2654            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2655            Ok(found_snapshot)
 2656        } else {
 2657            Ok((buffer.read(cx)).text_snapshot())
 2658        }
 2659    }
 2660
 2661    async fn get_server_code_actions_from_action_kinds(
 2662        lsp_store: &WeakEntity<LspStore>,
 2663        language_server_id: LanguageServerId,
 2664        code_action_kinds: Vec<lsp::CodeActionKind>,
 2665        buffer: &Entity<Buffer>,
 2666        cx: &mut AsyncApp,
 2667    ) -> Result<Vec<CodeAction>> {
 2668        let actions = lsp_store
 2669            .update(cx, move |this, cx| {
 2670                let request = GetCodeActions {
 2671                    range: text::Anchor::MIN..text::Anchor::MAX,
 2672                    kinds: Some(code_action_kinds),
 2673                };
 2674                let server = LanguageServerToQuery::Other(language_server_id);
 2675                this.request_lsp(buffer.clone(), server, request, cx)
 2676            })?
 2677            .await?;
 2678        Ok(actions)
 2679    }
 2680
 2681    pub async fn execute_code_actions_on_server(
 2682        lsp_store: &WeakEntity<LspStore>,
 2683        language_server: &Arc<LanguageServer>,
 2684
 2685        actions: Vec<CodeAction>,
 2686        push_to_history: bool,
 2687        project_transaction: &mut ProjectTransaction,
 2688        cx: &mut AsyncApp,
 2689    ) -> anyhow::Result<()> {
 2690        for mut action in actions {
 2691            Self::try_resolve_code_action(language_server, &mut action)
 2692                .await
 2693                .context("resolving a formatting code action")?;
 2694
 2695            if let Some(edit) = action.lsp_action.edit() {
 2696                if edit.changes.is_none() && edit.document_changes.is_none() {
 2697                    continue;
 2698                }
 2699
 2700                let new = Self::deserialize_workspace_edit(
 2701                    lsp_store.upgrade().context("project dropped")?,
 2702                    edit.clone(),
 2703                    push_to_history,
 2704                    language_server.clone(),
 2705                    cx,
 2706                )
 2707                .await?;
 2708                project_transaction.0.extend(new.0);
 2709            }
 2710
 2711            if let Some(command) = action.lsp_action.command() {
 2712                let server_capabilities = language_server.capabilities();
 2713                let available_commands = server_capabilities
 2714                    .execute_command_provider
 2715                    .as_ref()
 2716                    .map(|options| options.commands.as_slice())
 2717                    .unwrap_or_default();
 2718                if available_commands.contains(&command.command) {
 2719                    lsp_store.update(cx, |lsp_store, _| {
 2720                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2721                            mode.last_workspace_edits_by_language_server
 2722                                .remove(&language_server.server_id());
 2723                        }
 2724                    })?;
 2725
 2726                    language_server
 2727                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2728                            command: command.command.clone(),
 2729                            arguments: command.arguments.clone().unwrap_or_default(),
 2730                            ..Default::default()
 2731                        })
 2732                        .await
 2733                        .into_response()
 2734                        .context("execute command")?;
 2735
 2736                    lsp_store.update(cx, |this, _| {
 2737                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2738                            project_transaction.0.extend(
 2739                                mode.last_workspace_edits_by_language_server
 2740                                    .remove(&language_server.server_id())
 2741                                    .unwrap_or_default()
 2742                                    .0,
 2743                            )
 2744                        }
 2745                    })?;
 2746                } else {
 2747                    log::warn!(
 2748                        "Cannot execute a command {} not listed in the language server capabilities",
 2749                        command.command
 2750                    )
 2751                }
 2752            }
 2753        }
 2754        Ok(())
 2755    }
 2756
 2757    pub async fn deserialize_text_edits(
 2758        this: Entity<LspStore>,
 2759        buffer_to_edit: Entity<Buffer>,
 2760        edits: Vec<lsp::TextEdit>,
 2761        push_to_history: bool,
 2762        _: Arc<CachedLspAdapter>,
 2763        language_server: Arc<LanguageServer>,
 2764        cx: &mut AsyncApp,
 2765    ) -> Result<Option<Transaction>> {
 2766        let edits = this
 2767            .update(cx, |this, cx| {
 2768                this.as_local_mut().unwrap().edits_from_lsp(
 2769                    &buffer_to_edit,
 2770                    edits,
 2771                    language_server.server_id(),
 2772                    None,
 2773                    cx,
 2774                )
 2775            })?
 2776            .await?;
 2777
 2778        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2779            buffer.finalize_last_transaction();
 2780            buffer.start_transaction();
 2781            for (range, text) in edits {
 2782                buffer.edit([(range, text)], None, cx);
 2783            }
 2784
 2785            if buffer.end_transaction(cx).is_some() {
 2786                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2787                if !push_to_history {
 2788                    buffer.forget_transaction(transaction.id);
 2789                }
 2790                Some(transaction)
 2791            } else {
 2792                None
 2793            }
 2794        })?;
 2795
 2796        Ok(transaction)
 2797    }
 2798
 2799    #[allow(clippy::type_complexity)]
 2800    pub(crate) fn edits_from_lsp(
 2801        &mut self,
 2802        buffer: &Entity<Buffer>,
 2803        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2804        server_id: LanguageServerId,
 2805        version: Option<i32>,
 2806        cx: &mut Context<LspStore>,
 2807    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2808        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2809        cx.background_spawn(async move {
 2810            let snapshot = snapshot?;
 2811            let mut lsp_edits = lsp_edits
 2812                .into_iter()
 2813                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2814                .collect::<Vec<_>>();
 2815
 2816            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2817
 2818            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2819            let mut edits = Vec::new();
 2820            while let Some((range, mut new_text)) = lsp_edits.next() {
 2821                // Clip invalid ranges provided by the language server.
 2822                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2823                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2824
 2825                // Combine any LSP edits that are adjacent.
 2826                //
 2827                // Also, combine LSP edits that are separated from each other by only
 2828                // a newline. This is important because for some code actions,
 2829                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2830                // are separated by unchanged newline characters.
 2831                //
 2832                // In order for the diffing logic below to work properly, any edits that
 2833                // cancel each other out must be combined into one.
 2834                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2835                    if next_range.start.0 > range.end {
 2836                        if next_range.start.0.row > range.end.row + 1
 2837                            || next_range.start.0.column > 0
 2838                            || snapshot.clip_point_utf16(
 2839                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2840                                Bias::Left,
 2841                            ) > range.end
 2842                        {
 2843                            break;
 2844                        }
 2845                        new_text.push('\n');
 2846                    }
 2847                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2848                    new_text.push_str(next_text);
 2849                    lsp_edits.next();
 2850                }
 2851
 2852                // For multiline edits, perform a diff of the old and new text so that
 2853                // we can identify the changes more precisely, preserving the locations
 2854                // of any anchors positioned in the unchanged regions.
 2855                if range.end.row > range.start.row {
 2856                    let offset = range.start.to_offset(&snapshot);
 2857                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2858                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2859                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2860                        (
 2861                            snapshot.anchor_after(offset + range.start)
 2862                                ..snapshot.anchor_before(offset + range.end),
 2863                            replacement,
 2864                        )
 2865                    }));
 2866                } else if range.end == range.start {
 2867                    let anchor = snapshot.anchor_after(range.start);
 2868                    edits.push((anchor..anchor, new_text.into()));
 2869                } else {
 2870                    let edit_start = snapshot.anchor_after(range.start);
 2871                    let edit_end = snapshot.anchor_before(range.end);
 2872                    edits.push((edit_start..edit_end, new_text.into()));
 2873                }
 2874            }
 2875
 2876            Ok(edits)
 2877        })
 2878    }
 2879
 2880    pub(crate) async fn deserialize_workspace_edit(
 2881        this: Entity<LspStore>,
 2882        edit: lsp::WorkspaceEdit,
 2883        push_to_history: bool,
 2884        language_server: Arc<LanguageServer>,
 2885        cx: &mut AsyncApp,
 2886    ) -> Result<ProjectTransaction> {
 2887        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2888
 2889        let mut operations = Vec::new();
 2890        if let Some(document_changes) = edit.document_changes {
 2891            match document_changes {
 2892                lsp::DocumentChanges::Edits(edits) => {
 2893                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2894                }
 2895                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2896            }
 2897        } else if let Some(changes) = edit.changes {
 2898            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2899                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2900                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2901                        uri,
 2902                        version: None,
 2903                    },
 2904                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2905                })
 2906            }));
 2907        }
 2908
 2909        let mut project_transaction = ProjectTransaction::default();
 2910        for operation in operations {
 2911            match operation {
 2912                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2913                    let abs_path = op
 2914                        .uri
 2915                        .to_file_path()
 2916                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2917
 2918                    if let Some(parent_path) = abs_path.parent() {
 2919                        fs.create_dir(parent_path).await?;
 2920                    }
 2921                    if abs_path.ends_with("/") {
 2922                        fs.create_dir(&abs_path).await?;
 2923                    } else {
 2924                        fs.create_file(
 2925                            &abs_path,
 2926                            op.options
 2927                                .map(|options| fs::CreateOptions {
 2928                                    overwrite: options.overwrite.unwrap_or(false),
 2929                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2930                                })
 2931                                .unwrap_or_default(),
 2932                        )
 2933                        .await?;
 2934                    }
 2935                }
 2936
 2937                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2938                    let source_abs_path = op
 2939                        .old_uri
 2940                        .to_file_path()
 2941                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2942                    let target_abs_path = op
 2943                        .new_uri
 2944                        .to_file_path()
 2945                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2946                    fs.rename(
 2947                        &source_abs_path,
 2948                        &target_abs_path,
 2949                        op.options
 2950                            .map(|options| fs::RenameOptions {
 2951                                overwrite: options.overwrite.unwrap_or(false),
 2952                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2953                            })
 2954                            .unwrap_or_default(),
 2955                    )
 2956                    .await?;
 2957                }
 2958
 2959                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 2960                    let abs_path = op
 2961                        .uri
 2962                        .to_file_path()
 2963                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2964                    let options = op
 2965                        .options
 2966                        .map(|options| fs::RemoveOptions {
 2967                            recursive: options.recursive.unwrap_or(false),
 2968                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 2969                        })
 2970                        .unwrap_or_default();
 2971                    if abs_path.ends_with("/") {
 2972                        fs.remove_dir(&abs_path, options).await?;
 2973                    } else {
 2974                        fs.remove_file(&abs_path, options).await?;
 2975                    }
 2976                }
 2977
 2978                lsp::DocumentChangeOperation::Edit(op) => {
 2979                    let buffer_to_edit = this
 2980                        .update(cx, |this, cx| {
 2981                            this.open_local_buffer_via_lsp(
 2982                                op.text_document.uri.clone(),
 2983                                language_server.server_id(),
 2984                                cx,
 2985                            )
 2986                        })?
 2987                        .await?;
 2988
 2989                    let edits = this
 2990                        .update(cx, |this, cx| {
 2991                            let path = buffer_to_edit.read(cx).project_path(cx);
 2992                            let active_entry = this.active_entry;
 2993                            let is_active_entry = path.is_some_and(|project_path| {
 2994                                this.worktree_store
 2995                                    .read(cx)
 2996                                    .entry_for_path(&project_path, cx)
 2997                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 2998                            });
 2999                            let local = this.as_local_mut().unwrap();
 3000
 3001                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3002                            for edit in op.edits {
 3003                                match edit {
 3004                                    Edit::Plain(edit) => {
 3005                                        if !edits.contains(&edit) {
 3006                                            edits.push(edit)
 3007                                        }
 3008                                    }
 3009                                    Edit::Annotated(edit) => {
 3010                                        if !edits.contains(&edit.text_edit) {
 3011                                            edits.push(edit.text_edit)
 3012                                        }
 3013                                    }
 3014                                    Edit::Snippet(edit) => {
 3015                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3016                                        else {
 3017                                            continue;
 3018                                        };
 3019
 3020                                        if is_active_entry {
 3021                                            snippet_edits.push((edit.range, snippet));
 3022                                        } else {
 3023                                            // Since this buffer is not focused, apply a normal edit.
 3024                                            let new_edit = TextEdit {
 3025                                                range: edit.range,
 3026                                                new_text: snippet.text,
 3027                                            };
 3028                                            if !edits.contains(&new_edit) {
 3029                                                edits.push(new_edit);
 3030                                            }
 3031                                        }
 3032                                    }
 3033                                }
 3034                            }
 3035                            if !snippet_edits.is_empty() {
 3036                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3037                                let version = if let Some(buffer_version) = op.text_document.version
 3038                                {
 3039                                    local
 3040                                        .buffer_snapshot_for_lsp_version(
 3041                                            &buffer_to_edit,
 3042                                            language_server.server_id(),
 3043                                            Some(buffer_version),
 3044                                            cx,
 3045                                        )
 3046                                        .ok()
 3047                                        .map(|snapshot| snapshot.version)
 3048                                } else {
 3049                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3050                                };
 3051
 3052                                let most_recent_edit =
 3053                                    version.and_then(|version| version.most_recent());
 3054                                // Check if the edit that triggered that edit has been made by this participant.
 3055
 3056                                if let Some(most_recent_edit) = most_recent_edit {
 3057                                    cx.emit(LspStoreEvent::SnippetEdit {
 3058                                        buffer_id,
 3059                                        edits: snippet_edits,
 3060                                        most_recent_edit,
 3061                                    });
 3062                                }
 3063                            }
 3064
 3065                            local.edits_from_lsp(
 3066                                &buffer_to_edit,
 3067                                edits,
 3068                                language_server.server_id(),
 3069                                op.text_document.version,
 3070                                cx,
 3071                            )
 3072                        })?
 3073                        .await?;
 3074
 3075                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3076                        buffer.finalize_last_transaction();
 3077                        buffer.start_transaction();
 3078                        for (range, text) in edits {
 3079                            buffer.edit([(range, text)], None, cx);
 3080                        }
 3081
 3082                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3083                            if push_to_history {
 3084                                buffer.finalize_last_transaction();
 3085                                buffer.get_transaction(transaction_id).cloned()
 3086                            } else {
 3087                                buffer.forget_transaction(transaction_id)
 3088                            }
 3089                        })
 3090                    })?;
 3091                    if let Some(transaction) = transaction {
 3092                        project_transaction.0.insert(buffer_to_edit, transaction);
 3093                    }
 3094                }
 3095            }
 3096        }
 3097
 3098        Ok(project_transaction)
 3099    }
 3100
 3101    async fn on_lsp_workspace_edit(
 3102        this: WeakEntity<LspStore>,
 3103        params: lsp::ApplyWorkspaceEditParams,
 3104        server_id: LanguageServerId,
 3105        cx: &mut AsyncApp,
 3106    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3107        let this = this.upgrade().context("project project closed")?;
 3108        let language_server = this
 3109            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3110            .context("language server not found")?;
 3111        let transaction = Self::deserialize_workspace_edit(
 3112            this.clone(),
 3113            params.edit,
 3114            true,
 3115            language_server.clone(),
 3116            cx,
 3117        )
 3118        .await
 3119        .log_err();
 3120        this.update(cx, |this, _| {
 3121            if let Some(transaction) = transaction {
 3122                this.as_local_mut()
 3123                    .unwrap()
 3124                    .last_workspace_edits_by_language_server
 3125                    .insert(server_id, transaction);
 3126            }
 3127        })?;
 3128        Ok(lsp::ApplyWorkspaceEditResponse {
 3129            applied: true,
 3130            failed_change: None,
 3131            failure_reason: None,
 3132        })
 3133    }
 3134
 3135    fn remove_worktree(
 3136        &mut self,
 3137        id_to_remove: WorktreeId,
 3138        cx: &mut Context<LspStore>,
 3139    ) -> Vec<LanguageServerId> {
 3140        self.diagnostics.remove(&id_to_remove);
 3141        self.prettier_store.update(cx, |prettier_store, cx| {
 3142            prettier_store.remove_worktree(id_to_remove, cx);
 3143        });
 3144
 3145        let mut servers_to_remove = BTreeSet::default();
 3146        let mut servers_to_preserve = HashSet::default();
 3147        for (seed, state) in &self.language_server_ids {
 3148            if seed.worktree_id == id_to_remove {
 3149                servers_to_remove.insert(state.id);
 3150            } else {
 3151                servers_to_preserve.insert(state.id);
 3152            }
 3153        }
 3154        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3155        self.language_server_ids
 3156            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3157        for server_id_to_remove in &servers_to_remove {
 3158            self.language_server_watched_paths
 3159                .remove(server_id_to_remove);
 3160            self.language_server_paths_watched_for_rename
 3161                .remove(server_id_to_remove);
 3162            self.last_workspace_edits_by_language_server
 3163                .remove(server_id_to_remove);
 3164            self.language_servers.remove(server_id_to_remove);
 3165            self.buffer_pull_diagnostics_result_ids
 3166                .remove(server_id_to_remove);
 3167            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3168                buffer_servers.remove(server_id_to_remove);
 3169            }
 3170            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3171        }
 3172        servers_to_remove.into_iter().collect()
 3173    }
 3174
 3175    fn rebuild_watched_paths_inner<'a>(
 3176        &'a self,
 3177        language_server_id: LanguageServerId,
 3178        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3179        cx: &mut Context<LspStore>,
 3180    ) -> LanguageServerWatchedPathsBuilder {
 3181        let worktrees = self
 3182            .worktree_store
 3183            .read(cx)
 3184            .worktrees()
 3185            .filter_map(|worktree| {
 3186                self.language_servers_for_worktree(worktree.read(cx).id())
 3187                    .find(|server| server.server_id() == language_server_id)
 3188                    .map(|_| worktree)
 3189            })
 3190            .collect::<Vec<_>>();
 3191
 3192        let mut worktree_globs = HashMap::default();
 3193        let mut abs_globs = HashMap::default();
 3194        log::trace!(
 3195            "Processing new watcher paths for language server with id {}",
 3196            language_server_id
 3197        );
 3198
 3199        for watcher in watchers {
 3200            if let Some((worktree, literal_prefix, pattern)) =
 3201                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3202            {
 3203                worktree.update(cx, |worktree, _| {
 3204                    if let Some((tree, glob)) =
 3205                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3206                    {
 3207                        tree.add_path_prefix_to_scan(literal_prefix);
 3208                        worktree_globs
 3209                            .entry(tree.id())
 3210                            .or_insert_with(GlobSetBuilder::new)
 3211                            .add(glob);
 3212                    }
 3213                });
 3214            } else {
 3215                let (path, pattern) = match &watcher.glob_pattern {
 3216                    lsp::GlobPattern::String(s) => {
 3217                        let watcher_path = SanitizedPath::new(s);
 3218                        let path = glob_literal_prefix(watcher_path.as_path());
 3219                        let pattern = watcher_path
 3220                            .as_path()
 3221                            .strip_prefix(&path)
 3222                            .map(|p| p.to_string_lossy().into_owned())
 3223                            .unwrap_or_else(|e| {
 3224                                debug_panic!(
 3225                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3226                                    s,
 3227                                    path.display(),
 3228                                    e
 3229                                );
 3230                                watcher_path.as_path().to_string_lossy().into_owned()
 3231                            });
 3232                        (path, pattern)
 3233                    }
 3234                    lsp::GlobPattern::Relative(rp) => {
 3235                        let Ok(mut base_uri) = match &rp.base_uri {
 3236                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3237                            lsp::OneOf::Right(base_uri) => base_uri,
 3238                        }
 3239                        .to_file_path() else {
 3240                            continue;
 3241                        };
 3242
 3243                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3244                        let pattern = Path::new(&rp.pattern)
 3245                            .strip_prefix(&path)
 3246                            .map(|p| p.to_string_lossy().into_owned())
 3247                            .unwrap_or_else(|e| {
 3248                                debug_panic!(
 3249                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3250                                    rp.pattern,
 3251                                    path.display(),
 3252                                    e
 3253                                );
 3254                                rp.pattern.clone()
 3255                            });
 3256                        base_uri.push(path);
 3257                        (base_uri, pattern)
 3258                    }
 3259                };
 3260
 3261                if let Some(glob) = Glob::new(&pattern).log_err() {
 3262                    if !path
 3263                        .components()
 3264                        .any(|c| matches!(c, path::Component::Normal(_)))
 3265                    {
 3266                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3267                        // rather than adding a new watcher for `/`.
 3268                        for worktree in &worktrees {
 3269                            worktree_globs
 3270                                .entry(worktree.read(cx).id())
 3271                                .or_insert_with(GlobSetBuilder::new)
 3272                                .add(glob.clone());
 3273                        }
 3274                    } else {
 3275                        abs_globs
 3276                            .entry(path.into())
 3277                            .or_insert_with(GlobSetBuilder::new)
 3278                            .add(glob);
 3279                    }
 3280                }
 3281            }
 3282        }
 3283
 3284        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3285        for (worktree_id, builder) in worktree_globs {
 3286            if let Ok(globset) = builder.build() {
 3287                watch_builder.watch_worktree(worktree_id, globset);
 3288            }
 3289        }
 3290        for (abs_path, builder) in abs_globs {
 3291            if let Ok(globset) = builder.build() {
 3292                watch_builder.watch_abs_path(abs_path, globset);
 3293            }
 3294        }
 3295        watch_builder
 3296    }
 3297
 3298    fn worktree_and_path_for_file_watcher(
 3299        worktrees: &[Entity<Worktree>],
 3300        watcher: &FileSystemWatcher,
 3301        cx: &App,
 3302    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3303        worktrees.iter().find_map(|worktree| {
 3304            let tree = worktree.read(cx);
 3305            let worktree_root_path = tree.abs_path();
 3306            let path_style = tree.path_style();
 3307            match &watcher.glob_pattern {
 3308                lsp::GlobPattern::String(s) => {
 3309                    let watcher_path = SanitizedPath::new(s);
 3310                    let relative = watcher_path
 3311                        .as_path()
 3312                        .strip_prefix(&worktree_root_path)
 3313                        .ok()?;
 3314                    let literal_prefix = glob_literal_prefix(relative);
 3315                    Some((
 3316                        worktree.clone(),
 3317                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3318                        relative.to_string_lossy().into_owned(),
 3319                    ))
 3320                }
 3321                lsp::GlobPattern::Relative(rp) => {
 3322                    let base_uri = match &rp.base_uri {
 3323                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3324                        lsp::OneOf::Right(base_uri) => base_uri,
 3325                    }
 3326                    .to_file_path()
 3327                    .ok()?;
 3328                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3329                    let mut literal_prefix = relative.to_owned();
 3330                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3331                    Some((
 3332                        worktree.clone(),
 3333                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3334                        rp.pattern.clone(),
 3335                    ))
 3336                }
 3337            }
 3338        })
 3339    }
 3340
 3341    fn rebuild_watched_paths(
 3342        &mut self,
 3343        language_server_id: LanguageServerId,
 3344        cx: &mut Context<LspStore>,
 3345    ) {
 3346        let Some(registrations) = self
 3347            .language_server_dynamic_registrations
 3348            .get(&language_server_id)
 3349        else {
 3350            return;
 3351        };
 3352
 3353        let watch_builder = self.rebuild_watched_paths_inner(
 3354            language_server_id,
 3355            registrations.did_change_watched_files.values().flatten(),
 3356            cx,
 3357        );
 3358        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3359        self.language_server_watched_paths
 3360            .insert(language_server_id, watcher);
 3361
 3362        cx.notify();
 3363    }
 3364
 3365    fn on_lsp_did_change_watched_files(
 3366        &mut self,
 3367        language_server_id: LanguageServerId,
 3368        registration_id: &str,
 3369        params: DidChangeWatchedFilesRegistrationOptions,
 3370        cx: &mut Context<LspStore>,
 3371    ) {
 3372        let registrations = self
 3373            .language_server_dynamic_registrations
 3374            .entry(language_server_id)
 3375            .or_default();
 3376
 3377        registrations
 3378            .did_change_watched_files
 3379            .insert(registration_id.to_string(), params.watchers);
 3380
 3381        self.rebuild_watched_paths(language_server_id, cx);
 3382    }
 3383
 3384    fn on_lsp_unregister_did_change_watched_files(
 3385        &mut self,
 3386        language_server_id: LanguageServerId,
 3387        registration_id: &str,
 3388        cx: &mut Context<LspStore>,
 3389    ) {
 3390        let registrations = self
 3391            .language_server_dynamic_registrations
 3392            .entry(language_server_id)
 3393            .or_default();
 3394
 3395        if registrations
 3396            .did_change_watched_files
 3397            .remove(registration_id)
 3398            .is_some()
 3399        {
 3400            log::info!(
 3401                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3402                language_server_id,
 3403                registration_id
 3404            );
 3405        } else {
 3406            log::warn!(
 3407                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3408                language_server_id,
 3409                registration_id
 3410            );
 3411        }
 3412
 3413        self.rebuild_watched_paths(language_server_id, cx);
 3414    }
 3415
 3416    async fn initialization_options_for_adapter(
 3417        adapter: Arc<dyn LspAdapter>,
 3418        delegate: &Arc<dyn LspAdapterDelegate>,
 3419    ) -> Result<Option<serde_json::Value>> {
 3420        let Some(mut initialization_config) =
 3421            adapter.clone().initialization_options(delegate).await?
 3422        else {
 3423            return Ok(None);
 3424        };
 3425
 3426        for other_adapter in delegate.registered_lsp_adapters() {
 3427            if other_adapter.name() == adapter.name() {
 3428                continue;
 3429            }
 3430            if let Ok(Some(target_config)) = other_adapter
 3431                .clone()
 3432                .additional_initialization_options(adapter.name(), delegate)
 3433                .await
 3434            {
 3435                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3436            }
 3437        }
 3438
 3439        Ok(Some(initialization_config))
 3440    }
 3441
 3442    async fn workspace_configuration_for_adapter(
 3443        adapter: Arc<dyn LspAdapter>,
 3444        delegate: &Arc<dyn LspAdapterDelegate>,
 3445        toolchain: Option<Toolchain>,
 3446        cx: &mut AsyncApp,
 3447    ) -> Result<serde_json::Value> {
 3448        let mut workspace_config = adapter
 3449            .clone()
 3450            .workspace_configuration(delegate, toolchain, cx)
 3451            .await?;
 3452
 3453        for other_adapter in delegate.registered_lsp_adapters() {
 3454            if other_adapter.name() == adapter.name() {
 3455                continue;
 3456            }
 3457            if let Ok(Some(target_config)) = other_adapter
 3458                .clone()
 3459                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3460                .await
 3461            {
 3462                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3463            }
 3464        }
 3465
 3466        Ok(workspace_config)
 3467    }
 3468
 3469    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3470        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3471            Some(server.clone())
 3472        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3473            Some(Arc::clone(server))
 3474        } else {
 3475            None
 3476        }
 3477    }
 3478}
 3479
 3480fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3481    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3482        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3483            language_server_id: server.server_id(),
 3484            name: Some(server.name()),
 3485            message: proto::update_language_server::Variant::MetadataUpdated(
 3486                proto::ServerMetadataUpdated {
 3487                    capabilities: Some(capabilities),
 3488                },
 3489            ),
 3490        });
 3491    }
 3492}
 3493
 3494#[derive(Debug)]
 3495pub struct FormattableBuffer {
 3496    handle: Entity<Buffer>,
 3497    abs_path: Option<PathBuf>,
 3498    env: Option<HashMap<String, String>>,
 3499    ranges: Option<Vec<Range<Anchor>>>,
 3500}
 3501
 3502pub struct RemoteLspStore {
 3503    upstream_client: Option<AnyProtoClient>,
 3504    upstream_project_id: u64,
 3505}
 3506
 3507pub(crate) enum LspStoreMode {
 3508    Local(LocalLspStore),   // ssh host and collab host
 3509    Remote(RemoteLspStore), // collab guest
 3510}
 3511
 3512impl LspStoreMode {
 3513    fn is_local(&self) -> bool {
 3514        matches!(self, LspStoreMode::Local(_))
 3515    }
 3516}
 3517
 3518pub struct LspStore {
 3519    mode: LspStoreMode,
 3520    last_formatting_failure: Option<String>,
 3521    downstream_client: Option<(AnyProtoClient, u64)>,
 3522    nonce: u128,
 3523    buffer_store: Entity<BufferStore>,
 3524    worktree_store: Entity<WorktreeStore>,
 3525    pub languages: Arc<LanguageRegistry>,
 3526    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3527    active_entry: Option<ProjectEntryId>,
 3528    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3529    _maintain_buffer_languages: Task<()>,
 3530    diagnostic_summaries:
 3531        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3532    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3533    lsp_data: HashMap<BufferId, BufferLspData>,
 3534    next_hint_id: Arc<AtomicUsize>,
 3535}
 3536
 3537#[derive(Debug)]
 3538pub struct BufferLspData {
 3539    buffer_version: Global,
 3540    document_colors: Option<DocumentColorData>,
 3541    code_lens: Option<CodeLensData>,
 3542    inlay_hints: BufferInlayHints,
 3543    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3544    chunk_lsp_requests: HashMap<LspKey, HashMap<BufferChunk, LspRequestId>>,
 3545}
 3546
 3547#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3548struct LspKey {
 3549    request_type: TypeId,
 3550    server_queried: Option<LanguageServerId>,
 3551}
 3552
 3553impl BufferLspData {
 3554    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3555        Self {
 3556            buffer_version: buffer.read(cx).version(),
 3557            document_colors: None,
 3558            code_lens: None,
 3559            inlay_hints: BufferInlayHints::new(buffer, cx),
 3560            lsp_requests: HashMap::default(),
 3561            chunk_lsp_requests: HashMap::default(),
 3562        }
 3563    }
 3564
 3565    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3566        if let Some(document_colors) = &mut self.document_colors {
 3567            document_colors.colors.remove(&for_server);
 3568            document_colors.cache_version += 1;
 3569        }
 3570
 3571        if let Some(code_lens) = &mut self.code_lens {
 3572            code_lens.lens.remove(&for_server);
 3573        }
 3574
 3575        self.inlay_hints.remove_server_data(for_server);
 3576    }
 3577
 3578    #[cfg(any(test, feature = "test-support"))]
 3579    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3580        &self.inlay_hints
 3581    }
 3582}
 3583
 3584#[derive(Debug, Default, Clone)]
 3585pub struct DocumentColors {
 3586    pub colors: HashSet<DocumentColor>,
 3587    pub cache_version: Option<usize>,
 3588}
 3589
 3590type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3591type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3592
 3593#[derive(Debug, Default)]
 3594struct DocumentColorData {
 3595    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3596    cache_version: usize,
 3597    colors_update: Option<(Global, DocumentColorTask)>,
 3598}
 3599
 3600#[derive(Debug, Default)]
 3601struct CodeLensData {
 3602    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3603    update: Option<(Global, CodeLensTask)>,
 3604}
 3605
 3606#[derive(Debug)]
 3607pub enum LspStoreEvent {
 3608    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3609    LanguageServerRemoved(LanguageServerId),
 3610    LanguageServerUpdate {
 3611        language_server_id: LanguageServerId,
 3612        name: Option<LanguageServerName>,
 3613        message: proto::update_language_server::Variant,
 3614    },
 3615    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3616    LanguageServerPrompt(LanguageServerPromptRequest),
 3617    LanguageDetected {
 3618        buffer: Entity<Buffer>,
 3619        new_language: Option<Arc<Language>>,
 3620    },
 3621    Notification(String),
 3622    RefreshInlayHints {
 3623        server_id: LanguageServerId,
 3624        request_id: Option<usize>,
 3625    },
 3626    RefreshCodeLens,
 3627    DiagnosticsUpdated {
 3628        server_id: LanguageServerId,
 3629        paths: Vec<ProjectPath>,
 3630    },
 3631    DiskBasedDiagnosticsStarted {
 3632        language_server_id: LanguageServerId,
 3633    },
 3634    DiskBasedDiagnosticsFinished {
 3635        language_server_id: LanguageServerId,
 3636    },
 3637    SnippetEdit {
 3638        buffer_id: BufferId,
 3639        edits: Vec<(lsp::Range, Snippet)>,
 3640        most_recent_edit: clock::Lamport,
 3641    },
 3642}
 3643
 3644#[derive(Clone, Debug, Serialize)]
 3645pub struct LanguageServerStatus {
 3646    pub name: LanguageServerName,
 3647    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 3648    pub has_pending_diagnostic_updates: bool,
 3649    progress_tokens: HashSet<String>,
 3650    pub worktree: Option<WorktreeId>,
 3651}
 3652
 3653#[derive(Clone, Debug)]
 3654struct CoreSymbol {
 3655    pub language_server_name: LanguageServerName,
 3656    pub source_worktree_id: WorktreeId,
 3657    pub source_language_server_id: LanguageServerId,
 3658    pub path: SymbolLocation,
 3659    pub name: String,
 3660    pub kind: lsp::SymbolKind,
 3661    pub range: Range<Unclipped<PointUtf16>>,
 3662}
 3663
 3664#[derive(Clone, Debug, PartialEq, Eq)]
 3665pub enum SymbolLocation {
 3666    InProject(ProjectPath),
 3667    OutsideProject {
 3668        abs_path: Arc<Path>,
 3669        signature: [u8; 32],
 3670    },
 3671}
 3672
 3673impl SymbolLocation {
 3674    fn file_name(&self) -> Option<&str> {
 3675        match self {
 3676            Self::InProject(path) => path.path.file_name(),
 3677            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3678        }
 3679    }
 3680}
 3681
 3682impl LspStore {
 3683    pub fn init(client: &AnyProtoClient) {
 3684        client.add_entity_request_handler(Self::handle_lsp_query);
 3685        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3686        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3687        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3688        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3689        client.add_entity_message_handler(Self::handle_start_language_server);
 3690        client.add_entity_message_handler(Self::handle_update_language_server);
 3691        client.add_entity_message_handler(Self::handle_language_server_log);
 3692        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3693        client.add_entity_request_handler(Self::handle_format_buffers);
 3694        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3695        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3696        client.add_entity_request_handler(Self::handle_apply_code_action);
 3697        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3698        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3699        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3700        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3701        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3702        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3703        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3704        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3705        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3706        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3707        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3708        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3709        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3710        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3711        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3712        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3713        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3714
 3715        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3716        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3717        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3718        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3719        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3720        client.add_entity_request_handler(
 3721            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3722        );
 3723        client.add_entity_request_handler(
 3724            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3725        );
 3726        client.add_entity_request_handler(
 3727            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3728        );
 3729    }
 3730
 3731    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3732        match &self.mode {
 3733            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3734            _ => None,
 3735        }
 3736    }
 3737
 3738    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3739        match &self.mode {
 3740            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3741            _ => None,
 3742        }
 3743    }
 3744
 3745    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3746        match &mut self.mode {
 3747            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3748            _ => None,
 3749        }
 3750    }
 3751
 3752    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3753        match &self.mode {
 3754            LspStoreMode::Remote(RemoteLspStore {
 3755                upstream_client: Some(upstream_client),
 3756                upstream_project_id,
 3757                ..
 3758            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3759
 3760            LspStoreMode::Remote(RemoteLspStore {
 3761                upstream_client: None,
 3762                ..
 3763            }) => None,
 3764            LspStoreMode::Local(_) => None,
 3765        }
 3766    }
 3767
 3768    pub fn new_local(
 3769        buffer_store: Entity<BufferStore>,
 3770        worktree_store: Entity<WorktreeStore>,
 3771        prettier_store: Entity<PrettierStore>,
 3772        toolchain_store: Entity<LocalToolchainStore>,
 3773        environment: Entity<ProjectEnvironment>,
 3774        manifest_tree: Entity<ManifestTree>,
 3775        languages: Arc<LanguageRegistry>,
 3776        http_client: Arc<dyn HttpClient>,
 3777        fs: Arc<dyn Fs>,
 3778        cx: &mut Context<Self>,
 3779    ) -> Self {
 3780        let yarn = YarnPathStore::new(fs.clone(), cx);
 3781        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3782            .detach();
 3783        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3784            .detach();
 3785        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3786            .detach();
 3787        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3788            .detach();
 3789        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3790            .detach();
 3791        subscribe_to_binary_statuses(&languages, cx).detach();
 3792
 3793        let _maintain_workspace_config = {
 3794            let (sender, receiver) = watch::channel();
 3795            (Self::maintain_workspace_config(receiver, cx), sender)
 3796        };
 3797
 3798        Self {
 3799            mode: LspStoreMode::Local(LocalLspStore {
 3800                weak: cx.weak_entity(),
 3801                worktree_store: worktree_store.clone(),
 3802
 3803                supplementary_language_servers: Default::default(),
 3804                languages: languages.clone(),
 3805                language_server_ids: Default::default(),
 3806                language_servers: Default::default(),
 3807                last_workspace_edits_by_language_server: Default::default(),
 3808                language_server_watched_paths: Default::default(),
 3809                language_server_paths_watched_for_rename: Default::default(),
 3810                language_server_dynamic_registrations: Default::default(),
 3811                buffers_being_formatted: Default::default(),
 3812                buffer_snapshots: Default::default(),
 3813                prettier_store,
 3814                environment,
 3815                http_client,
 3816                fs,
 3817                yarn,
 3818                next_diagnostic_group_id: Default::default(),
 3819                diagnostics: Default::default(),
 3820                _subscription: cx.on_app_quit(|this, cx| {
 3821                    this.as_local_mut()
 3822                        .unwrap()
 3823                        .shutdown_language_servers_on_quit(cx)
 3824                }),
 3825                lsp_tree: LanguageServerTree::new(
 3826                    manifest_tree,
 3827                    languages.clone(),
 3828                    toolchain_store.clone(),
 3829                ),
 3830                toolchain_store,
 3831                registered_buffers: HashMap::default(),
 3832                buffers_opened_in_servers: HashMap::default(),
 3833                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3834                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3835                    .manifest_file_names(),
 3836            }),
 3837            last_formatting_failure: None,
 3838            downstream_client: None,
 3839            buffer_store,
 3840            worktree_store,
 3841            languages: languages.clone(),
 3842            language_server_statuses: Default::default(),
 3843            nonce: StdRng::from_os_rng().random(),
 3844            diagnostic_summaries: HashMap::default(),
 3845            lsp_server_capabilities: HashMap::default(),
 3846            lsp_data: HashMap::default(),
 3847            next_hint_id: Arc::default(),
 3848            active_entry: None,
 3849            _maintain_workspace_config,
 3850            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3851        }
 3852    }
 3853
 3854    fn send_lsp_proto_request<R: LspCommand>(
 3855        &self,
 3856        buffer: Entity<Buffer>,
 3857        client: AnyProtoClient,
 3858        upstream_project_id: u64,
 3859        request: R,
 3860        cx: &mut Context<LspStore>,
 3861    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3862        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3863            return Task::ready(Ok(R::Response::default()));
 3864        }
 3865        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3866        cx.spawn(async move |this, cx| {
 3867            let response = client.request(message).await?;
 3868            let this = this.upgrade().context("project dropped")?;
 3869            request
 3870                .response_from_proto(response, this, buffer, cx.clone())
 3871                .await
 3872        })
 3873    }
 3874
 3875    pub(super) fn new_remote(
 3876        buffer_store: Entity<BufferStore>,
 3877        worktree_store: Entity<WorktreeStore>,
 3878        languages: Arc<LanguageRegistry>,
 3879        upstream_client: AnyProtoClient,
 3880        project_id: u64,
 3881        cx: &mut Context<Self>,
 3882    ) -> Self {
 3883        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3884            .detach();
 3885        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3886            .detach();
 3887        subscribe_to_binary_statuses(&languages, cx).detach();
 3888        let _maintain_workspace_config = {
 3889            let (sender, receiver) = watch::channel();
 3890            (Self::maintain_workspace_config(receiver, cx), sender)
 3891        };
 3892        Self {
 3893            mode: LspStoreMode::Remote(RemoteLspStore {
 3894                upstream_client: Some(upstream_client),
 3895                upstream_project_id: project_id,
 3896            }),
 3897            downstream_client: None,
 3898            last_formatting_failure: None,
 3899            buffer_store,
 3900            worktree_store,
 3901            languages: languages.clone(),
 3902            language_server_statuses: Default::default(),
 3903            nonce: StdRng::from_os_rng().random(),
 3904            diagnostic_summaries: HashMap::default(),
 3905            lsp_server_capabilities: HashMap::default(),
 3906            next_hint_id: Arc::default(),
 3907            lsp_data: HashMap::default(),
 3908            active_entry: None,
 3909
 3910            _maintain_workspace_config,
 3911            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3912        }
 3913    }
 3914
 3915    fn on_buffer_store_event(
 3916        &mut self,
 3917        _: Entity<BufferStore>,
 3918        event: &BufferStoreEvent,
 3919        cx: &mut Context<Self>,
 3920    ) {
 3921        match event {
 3922            BufferStoreEvent::BufferAdded(buffer) => {
 3923                self.on_buffer_added(buffer, cx).log_err();
 3924            }
 3925            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3926                let buffer_id = buffer.read(cx).remote_id();
 3927                if let Some(local) = self.as_local_mut()
 3928                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3929                {
 3930                    local.reset_buffer(buffer, old_file, cx);
 3931
 3932                    if local.registered_buffers.contains_key(&buffer_id) {
 3933                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3934                    }
 3935                }
 3936
 3937                self.detect_language_for_buffer(buffer, cx);
 3938                if let Some(local) = self.as_local_mut() {
 3939                    local.initialize_buffer(buffer, cx);
 3940                    if local.registered_buffers.contains_key(&buffer_id) {
 3941                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3942                    }
 3943                }
 3944            }
 3945            _ => {}
 3946        }
 3947    }
 3948
 3949    fn on_worktree_store_event(
 3950        &mut self,
 3951        _: Entity<WorktreeStore>,
 3952        event: &WorktreeStoreEvent,
 3953        cx: &mut Context<Self>,
 3954    ) {
 3955        match event {
 3956            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3957                if !worktree.read(cx).is_local() {
 3958                    return;
 3959                }
 3960                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3961                    worktree::Event::UpdatedEntries(changes) => {
 3962                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 3963                    }
 3964                    worktree::Event::UpdatedGitRepositories(_)
 3965                    | worktree::Event::DeletedEntry(_) => {}
 3966                })
 3967                .detach()
 3968            }
 3969            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 3970            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 3971                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 3972            }
 3973            WorktreeStoreEvent::WorktreeReleased(..)
 3974            | WorktreeStoreEvent::WorktreeOrderChanged
 3975            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 3976            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 3977            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 3978        }
 3979    }
 3980
 3981    fn on_prettier_store_event(
 3982        &mut self,
 3983        _: Entity<PrettierStore>,
 3984        event: &PrettierStoreEvent,
 3985        cx: &mut Context<Self>,
 3986    ) {
 3987        match event {
 3988            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 3989                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 3990            }
 3991            PrettierStoreEvent::LanguageServerAdded {
 3992                new_server_id,
 3993                name,
 3994                prettier_server,
 3995            } => {
 3996                self.register_supplementary_language_server(
 3997                    *new_server_id,
 3998                    name.clone(),
 3999                    prettier_server.clone(),
 4000                    cx,
 4001                );
 4002            }
 4003        }
 4004    }
 4005
 4006    fn on_toolchain_store_event(
 4007        &mut self,
 4008        _: Entity<LocalToolchainStore>,
 4009        event: &ToolchainStoreEvent,
 4010        _: &mut Context<Self>,
 4011    ) {
 4012        if let ToolchainStoreEvent::ToolchainActivated = event {
 4013            self.request_workspace_config_refresh()
 4014        }
 4015    }
 4016
 4017    fn request_workspace_config_refresh(&mut self) {
 4018        *self._maintain_workspace_config.1.borrow_mut() = ();
 4019    }
 4020
 4021    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4022        self.as_local().map(|local| local.prettier_store.clone())
 4023    }
 4024
 4025    fn on_buffer_event(
 4026        &mut self,
 4027        buffer: Entity<Buffer>,
 4028        event: &language::BufferEvent,
 4029        cx: &mut Context<Self>,
 4030    ) {
 4031        match event {
 4032            language::BufferEvent::Edited => {
 4033                self.on_buffer_edited(buffer, cx);
 4034            }
 4035
 4036            language::BufferEvent::Saved => {
 4037                self.on_buffer_saved(buffer, cx);
 4038            }
 4039
 4040            _ => {}
 4041        }
 4042    }
 4043
 4044    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4045        buffer
 4046            .read(cx)
 4047            .set_language_registry(self.languages.clone());
 4048
 4049        cx.subscribe(buffer, |this, buffer, event, cx| {
 4050            this.on_buffer_event(buffer, event, cx);
 4051        })
 4052        .detach();
 4053
 4054        self.detect_language_for_buffer(buffer, cx);
 4055        if let Some(local) = self.as_local_mut() {
 4056            local.initialize_buffer(buffer, cx);
 4057        }
 4058
 4059        Ok(())
 4060    }
 4061
 4062    pub(crate) fn register_buffer_with_language_servers(
 4063        &mut self,
 4064        buffer: &Entity<Buffer>,
 4065        only_register_servers: HashSet<LanguageServerSelector>,
 4066        ignore_refcounts: bool,
 4067        cx: &mut Context<Self>,
 4068    ) -> OpenLspBufferHandle {
 4069        let buffer_id = buffer.read(cx).remote_id();
 4070        let handle = cx.new(|_| buffer.clone());
 4071        if let Some(local) = self.as_local_mut() {
 4072            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4073            if !ignore_refcounts {
 4074                *refcount += 1;
 4075            }
 4076
 4077            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4078            // 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
 4079            // 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
 4080            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4081            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4082                return handle;
 4083            };
 4084            if !file.is_local() {
 4085                return handle;
 4086            }
 4087
 4088            if ignore_refcounts || *refcount == 1 {
 4089                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4090            }
 4091            if !ignore_refcounts {
 4092                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4093                    let refcount = {
 4094                        let local = lsp_store.as_local_mut().unwrap();
 4095                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4096                            debug_panic!("bad refcounting");
 4097                            return;
 4098                        };
 4099
 4100                        *refcount -= 1;
 4101                        *refcount
 4102                    };
 4103                    if refcount == 0 {
 4104                        lsp_store.lsp_data.remove(&buffer_id);
 4105                        let local = lsp_store.as_local_mut().unwrap();
 4106                        local.registered_buffers.remove(&buffer_id);
 4107                        local.buffers_opened_in_servers.remove(&buffer_id);
 4108                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4109                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4110                        }
 4111                    }
 4112                })
 4113                .detach();
 4114            }
 4115        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4116            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4117            cx.background_spawn(async move {
 4118                upstream_client
 4119                    .request(proto::RegisterBufferWithLanguageServers {
 4120                        project_id: upstream_project_id,
 4121                        buffer_id,
 4122                        only_servers: only_register_servers
 4123                            .into_iter()
 4124                            .map(|selector| {
 4125                                let selector = match selector {
 4126                                    LanguageServerSelector::Id(language_server_id) => {
 4127                                        proto::language_server_selector::Selector::ServerId(
 4128                                            language_server_id.to_proto(),
 4129                                        )
 4130                                    }
 4131                                    LanguageServerSelector::Name(language_server_name) => {
 4132                                        proto::language_server_selector::Selector::Name(
 4133                                            language_server_name.to_string(),
 4134                                        )
 4135                                    }
 4136                                };
 4137                                proto::LanguageServerSelector {
 4138                                    selector: Some(selector),
 4139                                }
 4140                            })
 4141                            .collect(),
 4142                    })
 4143                    .await
 4144            })
 4145            .detach();
 4146        } else {
 4147            panic!("oops!");
 4148        }
 4149        handle
 4150    }
 4151
 4152    fn maintain_buffer_languages(
 4153        languages: Arc<LanguageRegistry>,
 4154        cx: &mut Context<Self>,
 4155    ) -> Task<()> {
 4156        let mut subscription = languages.subscribe();
 4157        let mut prev_reload_count = languages.reload_count();
 4158        cx.spawn(async move |this, cx| {
 4159            while let Some(()) = subscription.next().await {
 4160                if let Some(this) = this.upgrade() {
 4161                    // If the language registry has been reloaded, then remove and
 4162                    // re-assign the languages on all open buffers.
 4163                    let reload_count = languages.reload_count();
 4164                    if reload_count > prev_reload_count {
 4165                        prev_reload_count = reload_count;
 4166                        this.update(cx, |this, cx| {
 4167                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4168                                for buffer in buffer_store.buffers() {
 4169                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4170                                    {
 4171                                        buffer
 4172                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4173                                        if let Some(local) = this.as_local_mut() {
 4174                                            local.reset_buffer(&buffer, &f, cx);
 4175
 4176                                            if local
 4177                                                .registered_buffers
 4178                                                .contains_key(&buffer.read(cx).remote_id())
 4179                                                && let Some(file_url) =
 4180                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4181                                            {
 4182                                                local.unregister_buffer_from_language_servers(
 4183                                                    &buffer, &file_url, cx,
 4184                                                );
 4185                                            }
 4186                                        }
 4187                                    }
 4188                                }
 4189                            });
 4190                        })
 4191                        .ok();
 4192                    }
 4193
 4194                    this.update(cx, |this, cx| {
 4195                        let mut plain_text_buffers = Vec::new();
 4196                        let mut buffers_with_unknown_injections = Vec::new();
 4197                        for handle in this.buffer_store.read(cx).buffers() {
 4198                            let buffer = handle.read(cx);
 4199                            if buffer.language().is_none()
 4200                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4201                            {
 4202                                plain_text_buffers.push(handle);
 4203                            } else if buffer.contains_unknown_injections() {
 4204                                buffers_with_unknown_injections.push(handle);
 4205                            }
 4206                        }
 4207
 4208                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4209                        // and reused later in the invisible worktrees.
 4210                        plain_text_buffers.sort_by_key(|buffer| {
 4211                            Reverse(
 4212                                File::from_dyn(buffer.read(cx).file())
 4213                                    .map(|file| file.worktree.read(cx).is_visible()),
 4214                            )
 4215                        });
 4216
 4217                        for buffer in plain_text_buffers {
 4218                            this.detect_language_for_buffer(&buffer, cx);
 4219                            if let Some(local) = this.as_local_mut() {
 4220                                local.initialize_buffer(&buffer, cx);
 4221                                if local
 4222                                    .registered_buffers
 4223                                    .contains_key(&buffer.read(cx).remote_id())
 4224                                {
 4225                                    local.register_buffer_with_language_servers(
 4226                                        &buffer,
 4227                                        HashSet::default(),
 4228                                        cx,
 4229                                    );
 4230                                }
 4231                            }
 4232                        }
 4233
 4234                        for buffer in buffers_with_unknown_injections {
 4235                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4236                        }
 4237                    })
 4238                    .ok();
 4239                }
 4240            }
 4241        })
 4242    }
 4243
 4244    fn detect_language_for_buffer(
 4245        &mut self,
 4246        buffer_handle: &Entity<Buffer>,
 4247        cx: &mut Context<Self>,
 4248    ) -> Option<language::AvailableLanguage> {
 4249        // If the buffer has a language, set it and start the language server if we haven't already.
 4250        let buffer = buffer_handle.read(cx);
 4251        let file = buffer.file()?;
 4252
 4253        let content = buffer.as_rope();
 4254        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4255        if let Some(available_language) = &available_language {
 4256            if let Some(Ok(Ok(new_language))) = self
 4257                .languages
 4258                .load_language(available_language)
 4259                .now_or_never()
 4260            {
 4261                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4262            }
 4263        } else {
 4264            cx.emit(LspStoreEvent::LanguageDetected {
 4265                buffer: buffer_handle.clone(),
 4266                new_language: None,
 4267            });
 4268        }
 4269
 4270        available_language
 4271    }
 4272
 4273    pub(crate) fn set_language_for_buffer(
 4274        &mut self,
 4275        buffer_entity: &Entity<Buffer>,
 4276        new_language: Arc<Language>,
 4277        cx: &mut Context<Self>,
 4278    ) {
 4279        let buffer = buffer_entity.read(cx);
 4280        let buffer_file = buffer.file().cloned();
 4281        let buffer_id = buffer.remote_id();
 4282        if let Some(local_store) = self.as_local_mut()
 4283            && local_store.registered_buffers.contains_key(&buffer_id)
 4284            && let Some(abs_path) =
 4285                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4286            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4287        {
 4288            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4289        }
 4290        buffer_entity.update(cx, |buffer, cx| {
 4291            if buffer
 4292                .language()
 4293                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4294            {
 4295                buffer.set_language(Some(new_language.clone()), cx);
 4296            }
 4297        });
 4298
 4299        let settings =
 4300            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4301        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4302
 4303        let worktree_id = if let Some(file) = buffer_file {
 4304            let worktree = file.worktree.clone();
 4305
 4306            if let Some(local) = self.as_local_mut()
 4307                && local.registered_buffers.contains_key(&buffer_id)
 4308            {
 4309                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4310            }
 4311            Some(worktree.read(cx).id())
 4312        } else {
 4313            None
 4314        };
 4315
 4316        if settings.prettier.allowed
 4317            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4318        {
 4319            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4320            if let Some(prettier_store) = prettier_store {
 4321                prettier_store.update(cx, |prettier_store, cx| {
 4322                    prettier_store.install_default_prettier(
 4323                        worktree_id,
 4324                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4325                        cx,
 4326                    )
 4327                })
 4328            }
 4329        }
 4330
 4331        cx.emit(LspStoreEvent::LanguageDetected {
 4332            buffer: buffer_entity.clone(),
 4333            new_language: Some(new_language),
 4334        })
 4335    }
 4336
 4337    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4338        self.buffer_store.clone()
 4339    }
 4340
 4341    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4342        self.active_entry = active_entry;
 4343    }
 4344
 4345    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4346        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4347            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4348        {
 4349            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4350                summaries
 4351                    .iter()
 4352                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4353            });
 4354            if let Some(summary) = summaries.next() {
 4355                client
 4356                    .send(proto::UpdateDiagnosticSummary {
 4357                        project_id: downstream_project_id,
 4358                        worktree_id: worktree.id().to_proto(),
 4359                        summary: Some(summary),
 4360                        more_summaries: summaries.collect(),
 4361                    })
 4362                    .log_err();
 4363            }
 4364        }
 4365    }
 4366
 4367    fn is_capable_for_proto_request<R>(
 4368        &self,
 4369        buffer: &Entity<Buffer>,
 4370        request: &R,
 4371        cx: &App,
 4372    ) -> bool
 4373    where
 4374        R: LspCommand,
 4375    {
 4376        self.check_if_capable_for_proto_request(
 4377            buffer,
 4378            |capabilities| {
 4379                request.check_capabilities(AdapterServerCapabilities {
 4380                    server_capabilities: capabilities.clone(),
 4381                    code_action_kinds: None,
 4382                })
 4383            },
 4384            cx,
 4385        )
 4386    }
 4387
 4388    fn check_if_capable_for_proto_request<F>(
 4389        &self,
 4390        buffer: &Entity<Buffer>,
 4391        check: F,
 4392        cx: &App,
 4393    ) -> bool
 4394    where
 4395        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4396    {
 4397        let Some(language) = buffer.read(cx).language().cloned() else {
 4398            return false;
 4399        };
 4400        let relevant_language_servers = self
 4401            .languages
 4402            .lsp_adapters(&language.name())
 4403            .into_iter()
 4404            .map(|lsp_adapter| lsp_adapter.name())
 4405            .collect::<HashSet<_>>();
 4406        self.language_server_statuses
 4407            .iter()
 4408            .filter_map(|(server_id, server_status)| {
 4409                relevant_language_servers
 4410                    .contains(&server_status.name)
 4411                    .then_some(server_id)
 4412            })
 4413            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4414            .any(check)
 4415    }
 4416
 4417    pub fn request_lsp<R>(
 4418        &mut self,
 4419        buffer: Entity<Buffer>,
 4420        server: LanguageServerToQuery,
 4421        request: R,
 4422        cx: &mut Context<Self>,
 4423    ) -> Task<Result<R::Response>>
 4424    where
 4425        R: LspCommand,
 4426        <R::LspRequest as lsp::request::Request>::Result: Send,
 4427        <R::LspRequest as lsp::request::Request>::Params: Send,
 4428    {
 4429        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4430            return self.send_lsp_proto_request(
 4431                buffer,
 4432                upstream_client,
 4433                upstream_project_id,
 4434                request,
 4435                cx,
 4436            );
 4437        }
 4438
 4439        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4440            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4441                local
 4442                    .language_servers_for_buffer(buffer, cx)
 4443                    .find(|(_, server)| {
 4444                        request.check_capabilities(server.adapter_server_capabilities())
 4445                    })
 4446                    .map(|(_, server)| server.clone())
 4447            }),
 4448            LanguageServerToQuery::Other(id) => self
 4449                .language_server_for_local_buffer(buffer, id, cx)
 4450                .and_then(|(_, server)| {
 4451                    request
 4452                        .check_capabilities(server.adapter_server_capabilities())
 4453                        .then(|| Arc::clone(server))
 4454                }),
 4455        }) else {
 4456            return Task::ready(Ok(Default::default()));
 4457        };
 4458
 4459        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4460
 4461        let Some(file) = file else {
 4462            return Task::ready(Ok(Default::default()));
 4463        };
 4464
 4465        let lsp_params = match request.to_lsp_params_or_response(
 4466            &file.abs_path(cx),
 4467            buffer.read(cx),
 4468            &language_server,
 4469            cx,
 4470        ) {
 4471            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4472            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4473
 4474            Err(err) => {
 4475                let message = format!(
 4476                    "{} via {} failed: {}",
 4477                    request.display_name(),
 4478                    language_server.name(),
 4479                    err
 4480                );
 4481                log::warn!("{message}");
 4482                return Task::ready(Err(anyhow!(message)));
 4483            }
 4484        };
 4485
 4486        let status = request.status();
 4487        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4488            return Task::ready(Ok(Default::default()));
 4489        }
 4490        cx.spawn(async move |this, cx| {
 4491            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4492
 4493            let id = lsp_request.id();
 4494            let _cleanup = if status.is_some() {
 4495                cx.update(|cx| {
 4496                    this.update(cx, |this, cx| {
 4497                        this.on_lsp_work_start(
 4498                            language_server.server_id(),
 4499                            id.to_string(),
 4500                            LanguageServerProgress {
 4501                                is_disk_based_diagnostics_progress: false,
 4502                                is_cancellable: false,
 4503                                title: None,
 4504                                message: status.clone(),
 4505                                percentage: None,
 4506                                last_update_at: cx.background_executor().now(),
 4507                            },
 4508                            cx,
 4509                        );
 4510                    })
 4511                })
 4512                .log_err();
 4513
 4514                Some(defer(|| {
 4515                    cx.update(|cx| {
 4516                        this.update(cx, |this, cx| {
 4517                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
 4518                        })
 4519                    })
 4520                    .log_err();
 4521                }))
 4522            } else {
 4523                None
 4524            };
 4525
 4526            let result = lsp_request.await.into_response();
 4527
 4528            let response = result.map_err(|err| {
 4529                let message = format!(
 4530                    "{} via {} failed: {}",
 4531                    request.display_name(),
 4532                    language_server.name(),
 4533                    err
 4534                );
 4535                log::warn!("{message}");
 4536                anyhow::anyhow!(message)
 4537            })?;
 4538
 4539            request
 4540                .response_from_lsp(
 4541                    response,
 4542                    this.upgrade().context("no app context")?,
 4543                    buffer,
 4544                    language_server.server_id(),
 4545                    cx.clone(),
 4546                )
 4547                .await
 4548        })
 4549    }
 4550
 4551    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4552        let mut language_formatters_to_check = Vec::new();
 4553        for buffer in self.buffer_store.read(cx).buffers() {
 4554            let buffer = buffer.read(cx);
 4555            let buffer_file = File::from_dyn(buffer.file());
 4556            let buffer_language = buffer.language();
 4557            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4558            if buffer_language.is_some() {
 4559                language_formatters_to_check.push((
 4560                    buffer_file.map(|f| f.worktree_id(cx)),
 4561                    settings.into_owned(),
 4562                ));
 4563            }
 4564        }
 4565
 4566        self.request_workspace_config_refresh();
 4567
 4568        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4569            prettier_store.update(cx, |prettier_store, cx| {
 4570                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4571            })
 4572        }
 4573
 4574        cx.notify();
 4575    }
 4576
 4577    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4578        let buffer_store = self.buffer_store.clone();
 4579        let Some(local) = self.as_local_mut() else {
 4580            return;
 4581        };
 4582        let mut adapters = BTreeMap::default();
 4583        let get_adapter = {
 4584            let languages = local.languages.clone();
 4585            let environment = local.environment.clone();
 4586            let weak = local.weak.clone();
 4587            let worktree_store = local.worktree_store.clone();
 4588            let http_client = local.http_client.clone();
 4589            let fs = local.fs.clone();
 4590            move |worktree_id, cx: &mut App| {
 4591                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4592                Some(LocalLspAdapterDelegate::new(
 4593                    languages.clone(),
 4594                    &environment,
 4595                    weak.clone(),
 4596                    &worktree,
 4597                    http_client.clone(),
 4598                    fs.clone(),
 4599                    cx,
 4600                ))
 4601            }
 4602        };
 4603
 4604        let mut messages_to_report = Vec::new();
 4605        let (new_tree, to_stop) = {
 4606            let mut rebase = local.lsp_tree.rebase();
 4607            let buffers = buffer_store
 4608                .read(cx)
 4609                .buffers()
 4610                .filter_map(|buffer| {
 4611                    let raw_buffer = buffer.read(cx);
 4612                    if !local
 4613                        .registered_buffers
 4614                        .contains_key(&raw_buffer.remote_id())
 4615                    {
 4616                        return None;
 4617                    }
 4618                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4619                    let language = raw_buffer.language().cloned()?;
 4620                    Some((file, language, raw_buffer.remote_id()))
 4621                })
 4622                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4623            for (file, language, buffer_id) in buffers {
 4624                let worktree_id = file.worktree_id(cx);
 4625                let Some(worktree) = local
 4626                    .worktree_store
 4627                    .read(cx)
 4628                    .worktree_for_id(worktree_id, cx)
 4629                else {
 4630                    continue;
 4631                };
 4632
 4633                if let Some((_, apply)) = local.reuse_existing_language_server(
 4634                    rebase.server_tree(),
 4635                    &worktree,
 4636                    &language.name(),
 4637                    cx,
 4638                ) {
 4639                    (apply)(rebase.server_tree());
 4640                } else if let Some(lsp_delegate) = adapters
 4641                    .entry(worktree_id)
 4642                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4643                    .clone()
 4644                {
 4645                    let delegate =
 4646                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4647                    let path = file
 4648                        .path()
 4649                        .parent()
 4650                        .map(Arc::from)
 4651                        .unwrap_or_else(|| file.path().clone());
 4652                    let worktree_path = ProjectPath { worktree_id, path };
 4653                    let abs_path = file.abs_path(cx);
 4654                    let nodes = rebase
 4655                        .walk(
 4656                            worktree_path,
 4657                            language.name(),
 4658                            language.manifest(),
 4659                            delegate.clone(),
 4660                            cx,
 4661                        )
 4662                        .collect::<Vec<_>>();
 4663                    for node in nodes {
 4664                        let server_id = node.server_id_or_init(|disposition| {
 4665                            let path = &disposition.path;
 4666                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4667                            let key = LanguageServerSeed {
 4668                                worktree_id,
 4669                                name: disposition.server_name.clone(),
 4670                                settings: disposition.settings.clone(),
 4671                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4672                                    path.worktree_id,
 4673                                    &path.path,
 4674                                    language.name(),
 4675                                ),
 4676                            };
 4677                            local.language_server_ids.remove(&key);
 4678
 4679                            let server_id = local.get_or_insert_language_server(
 4680                                &worktree,
 4681                                lsp_delegate.clone(),
 4682                                disposition,
 4683                                &language.name(),
 4684                                cx,
 4685                            );
 4686                            if let Some(state) = local.language_servers.get(&server_id)
 4687                                && let Ok(uri) = uri
 4688                            {
 4689                                state.add_workspace_folder(uri);
 4690                            };
 4691                            server_id
 4692                        });
 4693
 4694                        if let Some(language_server_id) = server_id {
 4695                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4696                                language_server_id,
 4697                                name: node.name(),
 4698                                message:
 4699                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4700                                        proto::RegisteredForBuffer {
 4701                                            buffer_abs_path: abs_path
 4702                                                .to_string_lossy()
 4703                                                .into_owned(),
 4704                                            buffer_id: buffer_id.to_proto(),
 4705                                        },
 4706                                    ),
 4707                            });
 4708                        }
 4709                    }
 4710                } else {
 4711                    continue;
 4712                }
 4713            }
 4714            rebase.finish()
 4715        };
 4716        for message in messages_to_report {
 4717            cx.emit(message);
 4718        }
 4719        local.lsp_tree = new_tree;
 4720        for (id, _) in to_stop {
 4721            self.stop_local_language_server(id, cx).detach();
 4722        }
 4723    }
 4724
 4725    pub fn apply_code_action(
 4726        &self,
 4727        buffer_handle: Entity<Buffer>,
 4728        mut action: CodeAction,
 4729        push_to_history: bool,
 4730        cx: &mut Context<Self>,
 4731    ) -> Task<Result<ProjectTransaction>> {
 4732        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4733            let request = proto::ApplyCodeAction {
 4734                project_id,
 4735                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4736                action: Some(Self::serialize_code_action(&action)),
 4737            };
 4738            let buffer_store = self.buffer_store();
 4739            cx.spawn(async move |_, cx| {
 4740                let response = upstream_client
 4741                    .request(request)
 4742                    .await?
 4743                    .transaction
 4744                    .context("missing transaction")?;
 4745
 4746                buffer_store
 4747                    .update(cx, |buffer_store, cx| {
 4748                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4749                    })?
 4750                    .await
 4751            })
 4752        } else if self.mode.is_local() {
 4753            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4754                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4755                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4756            }) else {
 4757                return Task::ready(Ok(ProjectTransaction::default()));
 4758            };
 4759            cx.spawn(async move |this,  cx| {
 4760                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4761                    .await
 4762                    .context("resolving a code action")?;
 4763                if let Some(edit) = action.lsp_action.edit()
 4764                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4765                        return LocalLspStore::deserialize_workspace_edit(
 4766                            this.upgrade().context("no app present")?,
 4767                            edit.clone(),
 4768                            push_to_history,
 4769
 4770                            lang_server.clone(),
 4771                            cx,
 4772                        )
 4773                        .await;
 4774                    }
 4775
 4776                if let Some(command) = action.lsp_action.command() {
 4777                    let server_capabilities = lang_server.capabilities();
 4778                    let available_commands = server_capabilities
 4779                        .execute_command_provider
 4780                        .as_ref()
 4781                        .map(|options| options.commands.as_slice())
 4782                        .unwrap_or_default();
 4783                    if available_commands.contains(&command.command) {
 4784                        this.update(cx, |this, _| {
 4785                            this.as_local_mut()
 4786                                .unwrap()
 4787                                .last_workspace_edits_by_language_server
 4788                                .remove(&lang_server.server_id());
 4789                        })?;
 4790
 4791                        let _result = lang_server
 4792                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4793                                command: command.command.clone(),
 4794                                arguments: command.arguments.clone().unwrap_or_default(),
 4795                                ..lsp::ExecuteCommandParams::default()
 4796                            })
 4797                            .await.into_response()
 4798                            .context("execute command")?;
 4799
 4800                        return this.update(cx, |this, _| {
 4801                            this.as_local_mut()
 4802                                .unwrap()
 4803                                .last_workspace_edits_by_language_server
 4804                                .remove(&lang_server.server_id())
 4805                                .unwrap_or_default()
 4806                        });
 4807                    } else {
 4808                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4809                    }
 4810                }
 4811
 4812                Ok(ProjectTransaction::default())
 4813            })
 4814        } else {
 4815            Task::ready(Err(anyhow!("no upstream client and not local")))
 4816        }
 4817    }
 4818
 4819    pub fn apply_code_action_kind(
 4820        &mut self,
 4821        buffers: HashSet<Entity<Buffer>>,
 4822        kind: CodeActionKind,
 4823        push_to_history: bool,
 4824        cx: &mut Context<Self>,
 4825    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4826        if self.as_local().is_some() {
 4827            cx.spawn(async move |lsp_store, cx| {
 4828                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4829                let result = LocalLspStore::execute_code_action_kind_locally(
 4830                    lsp_store.clone(),
 4831                    buffers,
 4832                    kind,
 4833                    push_to_history,
 4834                    cx,
 4835                )
 4836                .await;
 4837                lsp_store.update(cx, |lsp_store, _| {
 4838                    lsp_store.update_last_formatting_failure(&result);
 4839                })?;
 4840                result
 4841            })
 4842        } else if let Some((client, project_id)) = self.upstream_client() {
 4843            let buffer_store = self.buffer_store();
 4844            cx.spawn(async move |lsp_store, cx| {
 4845                let result = client
 4846                    .request(proto::ApplyCodeActionKind {
 4847                        project_id,
 4848                        kind: kind.as_str().to_owned(),
 4849                        buffer_ids: buffers
 4850                            .iter()
 4851                            .map(|buffer| {
 4852                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4853                            })
 4854                            .collect::<Result<_>>()?,
 4855                    })
 4856                    .await
 4857                    .and_then(|result| result.transaction.context("missing transaction"));
 4858                lsp_store.update(cx, |lsp_store, _| {
 4859                    lsp_store.update_last_formatting_failure(&result);
 4860                })?;
 4861
 4862                let transaction_response = result?;
 4863                buffer_store
 4864                    .update(cx, |buffer_store, cx| {
 4865                        buffer_store.deserialize_project_transaction(
 4866                            transaction_response,
 4867                            push_to_history,
 4868                            cx,
 4869                        )
 4870                    })?
 4871                    .await
 4872            })
 4873        } else {
 4874            Task::ready(Ok(ProjectTransaction::default()))
 4875        }
 4876    }
 4877
 4878    pub fn resolved_hint(
 4879        &mut self,
 4880        buffer_id: BufferId,
 4881        id: InlayId,
 4882        cx: &mut Context<Self>,
 4883    ) -> Option<ResolvedHint> {
 4884        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 4885
 4886        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 4887        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 4888        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 4889        let (server_id, resolve_data) = match &hint.resolve_state {
 4890            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 4891            ResolveState::Resolving => {
 4892                return Some(ResolvedHint::Resolving(
 4893                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 4894                ));
 4895            }
 4896            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 4897        };
 4898
 4899        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 4900        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 4901        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 4902            id,
 4903            cx.spawn(async move |lsp_store, cx| {
 4904                let resolved_hint = resolve_task.await;
 4905                lsp_store
 4906                    .update(cx, |lsp_store, _| {
 4907                        if let Some(old_inlay_hint) = lsp_store
 4908                            .lsp_data
 4909                            .get_mut(&buffer_id)
 4910                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 4911                        {
 4912                            match resolved_hint {
 4913                                Ok(resolved_hint) => {
 4914                                    *old_inlay_hint = resolved_hint;
 4915                                }
 4916                                Err(e) => {
 4917                                    old_inlay_hint.resolve_state =
 4918                                        ResolveState::CanResolve(server_id, resolve_data);
 4919                                    log::error!("Inlay hint resolve failed: {e:#}");
 4920                                }
 4921                            }
 4922                        }
 4923                    })
 4924                    .ok();
 4925            })
 4926            .shared(),
 4927        );
 4928        debug_assert!(
 4929            previous_task.is_none(),
 4930            "Did not change hint's resolve state after spawning its resolve"
 4931        );
 4932        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 4933        None
 4934    }
 4935
 4936    fn resolve_inlay_hint(
 4937        &self,
 4938        mut hint: InlayHint,
 4939        buffer: Entity<Buffer>,
 4940        server_id: LanguageServerId,
 4941        cx: &mut Context<Self>,
 4942    ) -> Task<anyhow::Result<InlayHint>> {
 4943        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4944            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4945            {
 4946                hint.resolve_state = ResolveState::Resolved;
 4947                return Task::ready(Ok(hint));
 4948            }
 4949            let request = proto::ResolveInlayHint {
 4950                project_id,
 4951                buffer_id: buffer.read(cx).remote_id().into(),
 4952                language_server_id: server_id.0 as u64,
 4953                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 4954            };
 4955            cx.background_spawn(async move {
 4956                let response = upstream_client
 4957                    .request(request)
 4958                    .await
 4959                    .context("inlay hints proto request")?;
 4960                match response.hint {
 4961                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 4962                        .context("inlay hints proto resolve response conversion"),
 4963                    None => Ok(hint),
 4964                }
 4965            })
 4966        } else {
 4967            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 4968                self.language_server_for_local_buffer(buffer, server_id, cx)
 4969                    .map(|(_, server)| server.clone())
 4970            }) else {
 4971                return Task::ready(Ok(hint));
 4972            };
 4973            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 4974                return Task::ready(Ok(hint));
 4975            }
 4976            let buffer_snapshot = buffer.read(cx).snapshot();
 4977            cx.spawn(async move |_, cx| {
 4978                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 4979                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 4980                );
 4981                let resolved_hint = resolve_task
 4982                    .await
 4983                    .into_response()
 4984                    .context("inlay hint resolve LSP request")?;
 4985                let resolved_hint = InlayHints::lsp_to_project_hint(
 4986                    resolved_hint,
 4987                    &buffer,
 4988                    server_id,
 4989                    ResolveState::Resolved,
 4990                    false,
 4991                    cx,
 4992                )
 4993                .await?;
 4994                Ok(resolved_hint)
 4995            })
 4996        }
 4997    }
 4998
 4999    pub fn resolve_color_presentation(
 5000        &mut self,
 5001        mut color: DocumentColor,
 5002        buffer: Entity<Buffer>,
 5003        server_id: LanguageServerId,
 5004        cx: &mut Context<Self>,
 5005    ) -> Task<Result<DocumentColor>> {
 5006        if color.resolved {
 5007            return Task::ready(Ok(color));
 5008        }
 5009
 5010        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5011            let start = color.lsp_range.start;
 5012            let end = color.lsp_range.end;
 5013            let request = proto::GetColorPresentation {
 5014                project_id,
 5015                server_id: server_id.to_proto(),
 5016                buffer_id: buffer.read(cx).remote_id().into(),
 5017                color: Some(proto::ColorInformation {
 5018                    red: color.color.red,
 5019                    green: color.color.green,
 5020                    blue: color.color.blue,
 5021                    alpha: color.color.alpha,
 5022                    lsp_range_start: Some(proto::PointUtf16 {
 5023                        row: start.line,
 5024                        column: start.character,
 5025                    }),
 5026                    lsp_range_end: Some(proto::PointUtf16 {
 5027                        row: end.line,
 5028                        column: end.character,
 5029                    }),
 5030                }),
 5031            };
 5032            cx.background_spawn(async move {
 5033                let response = upstream_client
 5034                    .request(request)
 5035                    .await
 5036                    .context("color presentation proto request")?;
 5037                color.resolved = true;
 5038                color.color_presentations = response
 5039                    .presentations
 5040                    .into_iter()
 5041                    .map(|presentation| ColorPresentation {
 5042                        label: SharedString::from(presentation.label),
 5043                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5044                        additional_text_edits: presentation
 5045                            .additional_text_edits
 5046                            .into_iter()
 5047                            .filter_map(deserialize_lsp_edit)
 5048                            .collect(),
 5049                    })
 5050                    .collect();
 5051                Ok(color)
 5052            })
 5053        } else {
 5054            let path = match buffer
 5055                .update(cx, |buffer, cx| {
 5056                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5057                })
 5058                .context("buffer with the missing path")
 5059            {
 5060                Ok(path) => path,
 5061                Err(e) => return Task::ready(Err(e)),
 5062            };
 5063            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5064                self.language_server_for_local_buffer(buffer, server_id, cx)
 5065                    .map(|(_, server)| server.clone())
 5066            }) else {
 5067                return Task::ready(Ok(color));
 5068            };
 5069            cx.background_spawn(async move {
 5070                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5071                    lsp::ColorPresentationParams {
 5072                        text_document: make_text_document_identifier(&path)?,
 5073                        color: color.color,
 5074                        range: color.lsp_range,
 5075                        work_done_progress_params: Default::default(),
 5076                        partial_result_params: Default::default(),
 5077                    },
 5078                );
 5079                color.color_presentations = resolve_task
 5080                    .await
 5081                    .into_response()
 5082                    .context("color presentation resolve LSP request")?
 5083                    .into_iter()
 5084                    .map(|presentation| ColorPresentation {
 5085                        label: SharedString::from(presentation.label),
 5086                        text_edit: presentation.text_edit,
 5087                        additional_text_edits: presentation
 5088                            .additional_text_edits
 5089                            .unwrap_or_default(),
 5090                    })
 5091                    .collect();
 5092                color.resolved = true;
 5093                Ok(color)
 5094            })
 5095        }
 5096    }
 5097
 5098    pub(crate) fn linked_edits(
 5099        &mut self,
 5100        buffer: &Entity<Buffer>,
 5101        position: Anchor,
 5102        cx: &mut Context<Self>,
 5103    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5104        let snapshot = buffer.read(cx).snapshot();
 5105        let scope = snapshot.language_scope_at(position);
 5106        let Some(server_id) = self
 5107            .as_local()
 5108            .and_then(|local| {
 5109                buffer.update(cx, |buffer, cx| {
 5110                    local
 5111                        .language_servers_for_buffer(buffer, cx)
 5112                        .filter(|(_, server)| {
 5113                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5114                        })
 5115                        .filter(|(adapter, _)| {
 5116                            scope
 5117                                .as_ref()
 5118                                .map(|scope| scope.language_allowed(&adapter.name))
 5119                                .unwrap_or(true)
 5120                        })
 5121                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5122                        .next()
 5123                })
 5124            })
 5125            .or_else(|| {
 5126                self.upstream_client()
 5127                    .is_some()
 5128                    .then_some(LanguageServerToQuery::FirstCapable)
 5129            })
 5130            .filter(|_| {
 5131                maybe!({
 5132                    let language = buffer.read(cx).language_at(position)?;
 5133                    Some(
 5134                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5135                            .linked_edits,
 5136                    )
 5137                }) == Some(true)
 5138            })
 5139        else {
 5140            return Task::ready(Ok(Vec::new()));
 5141        };
 5142
 5143        self.request_lsp(
 5144            buffer.clone(),
 5145            server_id,
 5146            LinkedEditingRange { position },
 5147            cx,
 5148        )
 5149    }
 5150
 5151    fn apply_on_type_formatting(
 5152        &mut self,
 5153        buffer: Entity<Buffer>,
 5154        position: Anchor,
 5155        trigger: String,
 5156        cx: &mut Context<Self>,
 5157    ) -> Task<Result<Option<Transaction>>> {
 5158        if let Some((client, project_id)) = self.upstream_client() {
 5159            if !self.check_if_capable_for_proto_request(
 5160                &buffer,
 5161                |capabilities| {
 5162                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5163                },
 5164                cx,
 5165            ) {
 5166                return Task::ready(Ok(None));
 5167            }
 5168            let request = proto::OnTypeFormatting {
 5169                project_id,
 5170                buffer_id: buffer.read(cx).remote_id().into(),
 5171                position: Some(serialize_anchor(&position)),
 5172                trigger,
 5173                version: serialize_version(&buffer.read(cx).version()),
 5174            };
 5175            cx.background_spawn(async move {
 5176                client
 5177                    .request(request)
 5178                    .await?
 5179                    .transaction
 5180                    .map(language::proto::deserialize_transaction)
 5181                    .transpose()
 5182            })
 5183        } else if let Some(local) = self.as_local_mut() {
 5184            let buffer_id = buffer.read(cx).remote_id();
 5185            local.buffers_being_formatted.insert(buffer_id);
 5186            cx.spawn(async move |this, cx| {
 5187                let _cleanup = defer({
 5188                    let this = this.clone();
 5189                    let mut cx = cx.clone();
 5190                    move || {
 5191                        this.update(&mut cx, |this, _| {
 5192                            if let Some(local) = this.as_local_mut() {
 5193                                local.buffers_being_formatted.remove(&buffer_id);
 5194                            }
 5195                        })
 5196                        .ok();
 5197                    }
 5198                });
 5199
 5200                buffer
 5201                    .update(cx, |buffer, _| {
 5202                        buffer.wait_for_edits(Some(position.timestamp))
 5203                    })?
 5204                    .await?;
 5205                this.update(cx, |this, cx| {
 5206                    let position = position.to_point_utf16(buffer.read(cx));
 5207                    this.on_type_format(buffer, position, trigger, false, cx)
 5208                })?
 5209                .await
 5210            })
 5211        } else {
 5212            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5213        }
 5214    }
 5215
 5216    pub fn on_type_format<T: ToPointUtf16>(
 5217        &mut self,
 5218        buffer: Entity<Buffer>,
 5219        position: T,
 5220        trigger: String,
 5221        push_to_history: bool,
 5222        cx: &mut Context<Self>,
 5223    ) -> Task<Result<Option<Transaction>>> {
 5224        let position = position.to_point_utf16(buffer.read(cx));
 5225        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5226    }
 5227
 5228    fn on_type_format_impl(
 5229        &mut self,
 5230        buffer: Entity<Buffer>,
 5231        position: PointUtf16,
 5232        trigger: String,
 5233        push_to_history: bool,
 5234        cx: &mut Context<Self>,
 5235    ) -> Task<Result<Option<Transaction>>> {
 5236        let options = buffer.update(cx, |buffer, cx| {
 5237            lsp_command::lsp_formatting_options(
 5238                language_settings(
 5239                    buffer.language_at(position).map(|l| l.name()),
 5240                    buffer.file(),
 5241                    cx,
 5242                )
 5243                .as_ref(),
 5244            )
 5245        });
 5246
 5247        cx.spawn(async move |this, cx| {
 5248            if let Some(waiter) =
 5249                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5250            {
 5251                waiter.await?;
 5252            }
 5253            cx.update(|cx| {
 5254                this.update(cx, |this, cx| {
 5255                    this.request_lsp(
 5256                        buffer.clone(),
 5257                        LanguageServerToQuery::FirstCapable,
 5258                        OnTypeFormatting {
 5259                            position,
 5260                            trigger,
 5261                            options,
 5262                            push_to_history,
 5263                        },
 5264                        cx,
 5265                    )
 5266                })
 5267            })??
 5268            .await
 5269        })
 5270    }
 5271
 5272    pub fn definitions(
 5273        &mut self,
 5274        buffer: &Entity<Buffer>,
 5275        position: PointUtf16,
 5276        cx: &mut Context<Self>,
 5277    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5278        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5279            let request = GetDefinitions { position };
 5280            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5281                return Task::ready(Ok(None));
 5282            }
 5283            let request_task = upstream_client.request_lsp(
 5284                project_id,
 5285                None,
 5286                LSP_REQUEST_TIMEOUT,
 5287                cx.background_executor().clone(),
 5288                request.to_proto(project_id, buffer.read(cx)),
 5289            );
 5290            let buffer = buffer.clone();
 5291            cx.spawn(async move |weak_project, cx| {
 5292                let Some(project) = weak_project.upgrade() else {
 5293                    return Ok(None);
 5294                };
 5295                let Some(responses) = request_task.await? else {
 5296                    return Ok(None);
 5297                };
 5298                let actions = join_all(responses.payload.into_iter().map(|response| {
 5299                    GetDefinitions { position }.response_from_proto(
 5300                        response.response,
 5301                        project.clone(),
 5302                        buffer.clone(),
 5303                        cx.clone(),
 5304                    )
 5305                }))
 5306                .await;
 5307
 5308                Ok(Some(
 5309                    actions
 5310                        .into_iter()
 5311                        .collect::<Result<Vec<Vec<_>>>>()?
 5312                        .into_iter()
 5313                        .flatten()
 5314                        .dedup()
 5315                        .collect(),
 5316                ))
 5317            })
 5318        } else {
 5319            let definitions_task = self.request_multiple_lsp_locally(
 5320                buffer,
 5321                Some(position),
 5322                GetDefinitions { position },
 5323                cx,
 5324            );
 5325            cx.background_spawn(async move {
 5326                Ok(Some(
 5327                    definitions_task
 5328                        .await
 5329                        .into_iter()
 5330                        .flat_map(|(_, definitions)| definitions)
 5331                        .dedup()
 5332                        .collect(),
 5333                ))
 5334            })
 5335        }
 5336    }
 5337
 5338    pub fn declarations(
 5339        &mut self,
 5340        buffer: &Entity<Buffer>,
 5341        position: PointUtf16,
 5342        cx: &mut Context<Self>,
 5343    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5344        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5345            let request = GetDeclarations { position };
 5346            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5347                return Task::ready(Ok(None));
 5348            }
 5349            let request_task = upstream_client.request_lsp(
 5350                project_id,
 5351                None,
 5352                LSP_REQUEST_TIMEOUT,
 5353                cx.background_executor().clone(),
 5354                request.to_proto(project_id, buffer.read(cx)),
 5355            );
 5356            let buffer = buffer.clone();
 5357            cx.spawn(async move |weak_project, cx| {
 5358                let Some(project) = weak_project.upgrade() else {
 5359                    return Ok(None);
 5360                };
 5361                let Some(responses) = request_task.await? else {
 5362                    return Ok(None);
 5363                };
 5364                let actions = join_all(responses.payload.into_iter().map(|response| {
 5365                    GetDeclarations { position }.response_from_proto(
 5366                        response.response,
 5367                        project.clone(),
 5368                        buffer.clone(),
 5369                        cx.clone(),
 5370                    )
 5371                }))
 5372                .await;
 5373
 5374                Ok(Some(
 5375                    actions
 5376                        .into_iter()
 5377                        .collect::<Result<Vec<Vec<_>>>>()?
 5378                        .into_iter()
 5379                        .flatten()
 5380                        .dedup()
 5381                        .collect(),
 5382                ))
 5383            })
 5384        } else {
 5385            let declarations_task = self.request_multiple_lsp_locally(
 5386                buffer,
 5387                Some(position),
 5388                GetDeclarations { position },
 5389                cx,
 5390            );
 5391            cx.background_spawn(async move {
 5392                Ok(Some(
 5393                    declarations_task
 5394                        .await
 5395                        .into_iter()
 5396                        .flat_map(|(_, declarations)| declarations)
 5397                        .dedup()
 5398                        .collect(),
 5399                ))
 5400            })
 5401        }
 5402    }
 5403
 5404    pub fn type_definitions(
 5405        &mut self,
 5406        buffer: &Entity<Buffer>,
 5407        position: PointUtf16,
 5408        cx: &mut Context<Self>,
 5409    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5410        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5411            let request = GetTypeDefinitions { position };
 5412            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5413                return Task::ready(Ok(None));
 5414            }
 5415            let request_task = upstream_client.request_lsp(
 5416                project_id,
 5417                None,
 5418                LSP_REQUEST_TIMEOUT,
 5419                cx.background_executor().clone(),
 5420                request.to_proto(project_id, buffer.read(cx)),
 5421            );
 5422            let buffer = buffer.clone();
 5423            cx.spawn(async move |weak_project, cx| {
 5424                let Some(project) = weak_project.upgrade() else {
 5425                    return Ok(None);
 5426                };
 5427                let Some(responses) = request_task.await? else {
 5428                    return Ok(None);
 5429                };
 5430                let actions = join_all(responses.payload.into_iter().map(|response| {
 5431                    GetTypeDefinitions { position }.response_from_proto(
 5432                        response.response,
 5433                        project.clone(),
 5434                        buffer.clone(),
 5435                        cx.clone(),
 5436                    )
 5437                }))
 5438                .await;
 5439
 5440                Ok(Some(
 5441                    actions
 5442                        .into_iter()
 5443                        .collect::<Result<Vec<Vec<_>>>>()?
 5444                        .into_iter()
 5445                        .flatten()
 5446                        .dedup()
 5447                        .collect(),
 5448                ))
 5449            })
 5450        } else {
 5451            let type_definitions_task = self.request_multiple_lsp_locally(
 5452                buffer,
 5453                Some(position),
 5454                GetTypeDefinitions { position },
 5455                cx,
 5456            );
 5457            cx.background_spawn(async move {
 5458                Ok(Some(
 5459                    type_definitions_task
 5460                        .await
 5461                        .into_iter()
 5462                        .flat_map(|(_, type_definitions)| type_definitions)
 5463                        .dedup()
 5464                        .collect(),
 5465                ))
 5466            })
 5467        }
 5468    }
 5469
 5470    pub fn implementations(
 5471        &mut self,
 5472        buffer: &Entity<Buffer>,
 5473        position: PointUtf16,
 5474        cx: &mut Context<Self>,
 5475    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5476        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5477            let request = GetImplementations { position };
 5478            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5479                return Task::ready(Ok(None));
 5480            }
 5481            let request_task = upstream_client.request_lsp(
 5482                project_id,
 5483                None,
 5484                LSP_REQUEST_TIMEOUT,
 5485                cx.background_executor().clone(),
 5486                request.to_proto(project_id, buffer.read(cx)),
 5487            );
 5488            let buffer = buffer.clone();
 5489            cx.spawn(async move |weak_project, cx| {
 5490                let Some(project) = weak_project.upgrade() else {
 5491                    return Ok(None);
 5492                };
 5493                let Some(responses) = request_task.await? else {
 5494                    return Ok(None);
 5495                };
 5496                let actions = join_all(responses.payload.into_iter().map(|response| {
 5497                    GetImplementations { position }.response_from_proto(
 5498                        response.response,
 5499                        project.clone(),
 5500                        buffer.clone(),
 5501                        cx.clone(),
 5502                    )
 5503                }))
 5504                .await;
 5505
 5506                Ok(Some(
 5507                    actions
 5508                        .into_iter()
 5509                        .collect::<Result<Vec<Vec<_>>>>()?
 5510                        .into_iter()
 5511                        .flatten()
 5512                        .dedup()
 5513                        .collect(),
 5514                ))
 5515            })
 5516        } else {
 5517            let implementations_task = self.request_multiple_lsp_locally(
 5518                buffer,
 5519                Some(position),
 5520                GetImplementations { position },
 5521                cx,
 5522            );
 5523            cx.background_spawn(async move {
 5524                Ok(Some(
 5525                    implementations_task
 5526                        .await
 5527                        .into_iter()
 5528                        .flat_map(|(_, implementations)| implementations)
 5529                        .dedup()
 5530                        .collect(),
 5531                ))
 5532            })
 5533        }
 5534    }
 5535
 5536    pub fn references(
 5537        &mut self,
 5538        buffer: &Entity<Buffer>,
 5539        position: PointUtf16,
 5540        cx: &mut Context<Self>,
 5541    ) -> Task<Result<Option<Vec<Location>>>> {
 5542        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5543            let request = GetReferences { position };
 5544            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5545                return Task::ready(Ok(None));
 5546            }
 5547
 5548            let request_task = upstream_client.request_lsp(
 5549                project_id,
 5550                None,
 5551                LSP_REQUEST_TIMEOUT,
 5552                cx.background_executor().clone(),
 5553                request.to_proto(project_id, buffer.read(cx)),
 5554            );
 5555            let buffer = buffer.clone();
 5556            cx.spawn(async move |weak_project, cx| {
 5557                let Some(project) = weak_project.upgrade() else {
 5558                    return Ok(None);
 5559                };
 5560                let Some(responses) = request_task.await? else {
 5561                    return Ok(None);
 5562                };
 5563
 5564                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5565                    GetReferences { position }.response_from_proto(
 5566                        lsp_response.response,
 5567                        project.clone(),
 5568                        buffer.clone(),
 5569                        cx.clone(),
 5570                    )
 5571                }))
 5572                .await
 5573                .into_iter()
 5574                .collect::<Result<Vec<Vec<_>>>>()?
 5575                .into_iter()
 5576                .flatten()
 5577                .dedup()
 5578                .collect();
 5579                Ok(Some(locations))
 5580            })
 5581        } else {
 5582            let references_task = self.request_multiple_lsp_locally(
 5583                buffer,
 5584                Some(position),
 5585                GetReferences { position },
 5586                cx,
 5587            );
 5588            cx.background_spawn(async move {
 5589                Ok(Some(
 5590                    references_task
 5591                        .await
 5592                        .into_iter()
 5593                        .flat_map(|(_, references)| references)
 5594                        .dedup()
 5595                        .collect(),
 5596                ))
 5597            })
 5598        }
 5599    }
 5600
 5601    pub fn code_actions(
 5602        &mut self,
 5603        buffer: &Entity<Buffer>,
 5604        range: Range<Anchor>,
 5605        kinds: Option<Vec<CodeActionKind>>,
 5606        cx: &mut Context<Self>,
 5607    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5608        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5609            let request = GetCodeActions {
 5610                range: range.clone(),
 5611                kinds: kinds.clone(),
 5612            };
 5613            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5614                return Task::ready(Ok(None));
 5615            }
 5616            let request_task = upstream_client.request_lsp(
 5617                project_id,
 5618                None,
 5619                LSP_REQUEST_TIMEOUT,
 5620                cx.background_executor().clone(),
 5621                request.to_proto(project_id, buffer.read(cx)),
 5622            );
 5623            let buffer = buffer.clone();
 5624            cx.spawn(async move |weak_project, cx| {
 5625                let Some(project) = weak_project.upgrade() else {
 5626                    return Ok(None);
 5627                };
 5628                let Some(responses) = request_task.await? else {
 5629                    return Ok(None);
 5630                };
 5631                let actions = join_all(responses.payload.into_iter().map(|response| {
 5632                    GetCodeActions {
 5633                        range: range.clone(),
 5634                        kinds: kinds.clone(),
 5635                    }
 5636                    .response_from_proto(
 5637                        response.response,
 5638                        project.clone(),
 5639                        buffer.clone(),
 5640                        cx.clone(),
 5641                    )
 5642                }))
 5643                .await;
 5644
 5645                Ok(Some(
 5646                    actions
 5647                        .into_iter()
 5648                        .collect::<Result<Vec<Vec<_>>>>()?
 5649                        .into_iter()
 5650                        .flatten()
 5651                        .collect(),
 5652                ))
 5653            })
 5654        } else {
 5655            let all_actions_task = self.request_multiple_lsp_locally(
 5656                buffer,
 5657                Some(range.start),
 5658                GetCodeActions { range, kinds },
 5659                cx,
 5660            );
 5661            cx.background_spawn(async move {
 5662                Ok(Some(
 5663                    all_actions_task
 5664                        .await
 5665                        .into_iter()
 5666                        .flat_map(|(_, actions)| actions)
 5667                        .collect(),
 5668                ))
 5669            })
 5670        }
 5671    }
 5672
 5673    pub fn code_lens_actions(
 5674        &mut self,
 5675        buffer: &Entity<Buffer>,
 5676        cx: &mut Context<Self>,
 5677    ) -> CodeLensTask {
 5678        let version_queried_for = buffer.read(cx).version();
 5679        let buffer_id = buffer.read(cx).remote_id();
 5680        let existing_servers = self.as_local().map(|local| {
 5681            local
 5682                .buffers_opened_in_servers
 5683                .get(&buffer_id)
 5684                .cloned()
 5685                .unwrap_or_default()
 5686        });
 5687
 5688        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5689            if let Some(cached_lens) = &lsp_data.code_lens {
 5690                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5691                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5692                        existing_servers != cached_lens.lens.keys().copied().collect()
 5693                    });
 5694                    if !has_different_servers {
 5695                        return Task::ready(Ok(Some(
 5696                            cached_lens.lens.values().flatten().cloned().collect(),
 5697                        )))
 5698                        .shared();
 5699                    }
 5700                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5701                    if !version_queried_for.changed_since(updating_for) {
 5702                        return running_update.clone();
 5703                    }
 5704                }
 5705            }
 5706        }
 5707
 5708        let lens_lsp_data = self
 5709            .latest_lsp_data(buffer, cx)
 5710            .code_lens
 5711            .get_or_insert_default();
 5712        let buffer = buffer.clone();
 5713        let query_version_queried_for = version_queried_for.clone();
 5714        let new_task = cx
 5715            .spawn(async move |lsp_store, cx| {
 5716                cx.background_executor()
 5717                    .timer(Duration::from_millis(30))
 5718                    .await;
 5719                let fetched_lens = lsp_store
 5720                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5721                    .map_err(Arc::new)?
 5722                    .await
 5723                    .context("fetching code lens")
 5724                    .map_err(Arc::new);
 5725                let fetched_lens = match fetched_lens {
 5726                    Ok(fetched_lens) => fetched_lens,
 5727                    Err(e) => {
 5728                        lsp_store
 5729                            .update(cx, |lsp_store, _| {
 5730                                if let Some(lens_lsp_data) = lsp_store
 5731                                    .lsp_data
 5732                                    .get_mut(&buffer_id)
 5733                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5734                                {
 5735                                    lens_lsp_data.update = None;
 5736                                }
 5737                            })
 5738                            .ok();
 5739                        return Err(e);
 5740                    }
 5741                };
 5742
 5743                lsp_store
 5744                    .update(cx, |lsp_store, _| {
 5745                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5746                        let code_lens = lsp_data.code_lens.as_mut()?;
 5747                        if let Some(fetched_lens) = fetched_lens {
 5748                            if lsp_data.buffer_version == query_version_queried_for {
 5749                                code_lens.lens.extend(fetched_lens);
 5750                            } else if !lsp_data
 5751                                .buffer_version
 5752                                .changed_since(&query_version_queried_for)
 5753                            {
 5754                                lsp_data.buffer_version = query_version_queried_for;
 5755                                code_lens.lens = fetched_lens;
 5756                            }
 5757                        }
 5758                        code_lens.update = None;
 5759                        Some(code_lens.lens.values().flatten().cloned().collect())
 5760                    })
 5761                    .map_err(Arc::new)
 5762            })
 5763            .shared();
 5764        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5765        new_task
 5766    }
 5767
 5768    fn fetch_code_lens(
 5769        &mut self,
 5770        buffer: &Entity<Buffer>,
 5771        cx: &mut Context<Self>,
 5772    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5773        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5774            let request = GetCodeLens;
 5775            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5776                return Task::ready(Ok(None));
 5777            }
 5778            let request_task = upstream_client.request_lsp(
 5779                project_id,
 5780                None,
 5781                LSP_REQUEST_TIMEOUT,
 5782                cx.background_executor().clone(),
 5783                request.to_proto(project_id, buffer.read(cx)),
 5784            );
 5785            let buffer = buffer.clone();
 5786            cx.spawn(async move |weak_lsp_store, cx| {
 5787                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5788                    return Ok(None);
 5789                };
 5790                let Some(responses) = request_task.await? else {
 5791                    return Ok(None);
 5792                };
 5793
 5794                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5795                    let lsp_store = lsp_store.clone();
 5796                    let buffer = buffer.clone();
 5797                    let cx = cx.clone();
 5798                    async move {
 5799                        (
 5800                            LanguageServerId::from_proto(response.server_id),
 5801                            GetCodeLens
 5802                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5803                                .await,
 5804                        )
 5805                    }
 5806                }))
 5807                .await;
 5808
 5809                let mut has_errors = false;
 5810                let code_lens_actions = code_lens_actions
 5811                    .into_iter()
 5812                    .filter_map(|(server_id, code_lens)| match code_lens {
 5813                        Ok(code_lens) => Some((server_id, code_lens)),
 5814                        Err(e) => {
 5815                            has_errors = true;
 5816                            log::error!("{e:#}");
 5817                            None
 5818                        }
 5819                    })
 5820                    .collect::<HashMap<_, _>>();
 5821                anyhow::ensure!(
 5822                    !has_errors || !code_lens_actions.is_empty(),
 5823                    "Failed to fetch code lens"
 5824                );
 5825                Ok(Some(code_lens_actions))
 5826            })
 5827        } else {
 5828            let code_lens_actions_task =
 5829                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5830            cx.background_spawn(async move {
 5831                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5832            })
 5833        }
 5834    }
 5835
 5836    #[inline(never)]
 5837    pub fn completions(
 5838        &self,
 5839        buffer: &Entity<Buffer>,
 5840        position: PointUtf16,
 5841        context: CompletionContext,
 5842        cx: &mut Context<Self>,
 5843    ) -> Task<Result<Vec<CompletionResponse>>> {
 5844        let language_registry = self.languages.clone();
 5845
 5846        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5847            let request = GetCompletions { position, context };
 5848            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5849                return Task::ready(Ok(Vec::new()));
 5850            }
 5851            let task = self.send_lsp_proto_request(
 5852                buffer.clone(),
 5853                upstream_client,
 5854                project_id,
 5855                request,
 5856                cx,
 5857            );
 5858            let language = buffer.read(cx).language().cloned();
 5859
 5860            // In the future, we should provide project guests with the names of LSP adapters,
 5861            // so that they can use the correct LSP adapter when computing labels. For now,
 5862            // guests just use the first LSP adapter associated with the buffer's language.
 5863            let lsp_adapter = language.as_ref().and_then(|language| {
 5864                language_registry
 5865                    .lsp_adapters(&language.name())
 5866                    .first()
 5867                    .cloned()
 5868            });
 5869
 5870            cx.foreground_executor().spawn(async move {
 5871                let completion_response = task.await?;
 5872                let completions = populate_labels_for_completions(
 5873                    completion_response.completions,
 5874                    language,
 5875                    lsp_adapter,
 5876                )
 5877                .await;
 5878                Ok(vec![CompletionResponse {
 5879                    completions,
 5880                    display_options: CompletionDisplayOptions::default(),
 5881                    is_incomplete: completion_response.is_incomplete,
 5882                }])
 5883            })
 5884        } else if let Some(local) = self.as_local() {
 5885            let snapshot = buffer.read(cx).snapshot();
 5886            let offset = position.to_offset(&snapshot);
 5887            let scope = snapshot.language_scope_at(offset);
 5888            let language = snapshot.language().cloned();
 5889            let completion_settings = language_settings(
 5890                language.as_ref().map(|language| language.name()),
 5891                buffer.read(cx).file(),
 5892                cx,
 5893            )
 5894            .completions
 5895            .clone();
 5896            if !completion_settings.lsp {
 5897                return Task::ready(Ok(Vec::new()));
 5898            }
 5899
 5900            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5901                local
 5902                    .language_servers_for_buffer(buffer, cx)
 5903                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5904                    .filter(|(adapter, _)| {
 5905                        scope
 5906                            .as_ref()
 5907                            .map(|scope| scope.language_allowed(&adapter.name))
 5908                            .unwrap_or(true)
 5909                    })
 5910                    .map(|(_, server)| server.server_id())
 5911                    .collect()
 5912            });
 5913
 5914            let buffer = buffer.clone();
 5915            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5916            let lsp_timeout = if lsp_timeout > 0 {
 5917                Some(Duration::from_millis(lsp_timeout))
 5918            } else {
 5919                None
 5920            };
 5921            cx.spawn(async move |this,  cx| {
 5922                let mut tasks = Vec::with_capacity(server_ids.len());
 5923                this.update(cx, |lsp_store, cx| {
 5924                    for server_id in server_ids {
 5925                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5926                        let lsp_timeout = lsp_timeout
 5927                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5928                        let mut timeout = cx.background_spawn(async move {
 5929                            match lsp_timeout {
 5930                                Some(lsp_timeout) => {
 5931                                    lsp_timeout.await;
 5932                                    true
 5933                                },
 5934                                None => false,
 5935                            }
 5936                        }).fuse();
 5937                        let mut lsp_request = lsp_store.request_lsp(
 5938                            buffer.clone(),
 5939                            LanguageServerToQuery::Other(server_id),
 5940                            GetCompletions {
 5941                                position,
 5942                                context: context.clone(),
 5943                            },
 5944                            cx,
 5945                        ).fuse();
 5946                        let new_task = cx.background_spawn(async move {
 5947                            select_biased! {
 5948                                response = lsp_request => anyhow::Ok(Some(response?)),
 5949                                timeout_happened = timeout => {
 5950                                    if timeout_happened {
 5951                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5952                                        Ok(None)
 5953                                    } else {
 5954                                        let completions = lsp_request.await?;
 5955                                        Ok(Some(completions))
 5956                                    }
 5957                                },
 5958                            }
 5959                        });
 5960                        tasks.push((lsp_adapter, new_task));
 5961                    }
 5962                })?;
 5963
 5964                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5965                    let completion_response = task.await.ok()??;
 5966                    let completions = populate_labels_for_completions(
 5967                            completion_response.completions,
 5968                            language.clone(),
 5969                            lsp_adapter,
 5970                        )
 5971                        .await;
 5972                    Some(CompletionResponse {
 5973                        completions,
 5974                        display_options: CompletionDisplayOptions::default(),
 5975                        is_incomplete: completion_response.is_incomplete,
 5976                    })
 5977                });
 5978
 5979                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 5980
 5981                Ok(responses.into_iter().flatten().collect())
 5982            })
 5983        } else {
 5984            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5985        }
 5986    }
 5987
 5988    pub fn resolve_completions(
 5989        &self,
 5990        buffer: Entity<Buffer>,
 5991        completion_indices: Vec<usize>,
 5992        completions: Rc<RefCell<Box<[Completion]>>>,
 5993        cx: &mut Context<Self>,
 5994    ) -> Task<Result<bool>> {
 5995        let client = self.upstream_client();
 5996        let buffer_id = buffer.read(cx).remote_id();
 5997        let buffer_snapshot = buffer.read(cx).snapshot();
 5998
 5999        if !self.check_if_capable_for_proto_request(
 6000            &buffer,
 6001            GetCompletions::can_resolve_completions,
 6002            cx,
 6003        ) {
 6004            return Task::ready(Ok(false));
 6005        }
 6006        cx.spawn(async move |lsp_store, cx| {
 6007            let mut did_resolve = false;
 6008            if let Some((client, project_id)) = client {
 6009                for completion_index in completion_indices {
 6010                    let server_id = {
 6011                        let completion = &completions.borrow()[completion_index];
 6012                        completion.source.server_id()
 6013                    };
 6014                    if let Some(server_id) = server_id {
 6015                        if Self::resolve_completion_remote(
 6016                            project_id,
 6017                            server_id,
 6018                            buffer_id,
 6019                            completions.clone(),
 6020                            completion_index,
 6021                            client.clone(),
 6022                        )
 6023                        .await
 6024                        .log_err()
 6025                        .is_some()
 6026                        {
 6027                            did_resolve = true;
 6028                        }
 6029                    } else {
 6030                        resolve_word_completion(
 6031                            &buffer_snapshot,
 6032                            &mut completions.borrow_mut()[completion_index],
 6033                        );
 6034                    }
 6035                }
 6036            } else {
 6037                for completion_index in completion_indices {
 6038                    let server_id = {
 6039                        let completion = &completions.borrow()[completion_index];
 6040                        completion.source.server_id()
 6041                    };
 6042                    if let Some(server_id) = server_id {
 6043                        let server_and_adapter = lsp_store
 6044                            .read_with(cx, |lsp_store, _| {
 6045                                let server = lsp_store.language_server_for_id(server_id)?;
 6046                                let adapter =
 6047                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6048                                Some((server, adapter))
 6049                            })
 6050                            .ok()
 6051                            .flatten();
 6052                        let Some((server, adapter)) = server_and_adapter else {
 6053                            continue;
 6054                        };
 6055
 6056                        let resolved = Self::resolve_completion_local(
 6057                            server,
 6058                            completions.clone(),
 6059                            completion_index,
 6060                        )
 6061                        .await
 6062                        .log_err()
 6063                        .is_some();
 6064                        if resolved {
 6065                            Self::regenerate_completion_labels(
 6066                                adapter,
 6067                                &buffer_snapshot,
 6068                                completions.clone(),
 6069                                completion_index,
 6070                            )
 6071                            .await
 6072                            .log_err();
 6073                            did_resolve = true;
 6074                        }
 6075                    } else {
 6076                        resolve_word_completion(
 6077                            &buffer_snapshot,
 6078                            &mut completions.borrow_mut()[completion_index],
 6079                        );
 6080                    }
 6081                }
 6082            }
 6083
 6084            Ok(did_resolve)
 6085        })
 6086    }
 6087
 6088    async fn resolve_completion_local(
 6089        server: Arc<lsp::LanguageServer>,
 6090        completions: Rc<RefCell<Box<[Completion]>>>,
 6091        completion_index: usize,
 6092    ) -> Result<()> {
 6093        let server_id = server.server_id();
 6094        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6095            return Ok(());
 6096        }
 6097
 6098        let request = {
 6099            let completion = &completions.borrow()[completion_index];
 6100            match &completion.source {
 6101                CompletionSource::Lsp {
 6102                    lsp_completion,
 6103                    resolved,
 6104                    server_id: completion_server_id,
 6105                    ..
 6106                } => {
 6107                    if *resolved {
 6108                        return Ok(());
 6109                    }
 6110                    anyhow::ensure!(
 6111                        server_id == *completion_server_id,
 6112                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6113                    );
 6114                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6115                }
 6116                CompletionSource::BufferWord { .. }
 6117                | CompletionSource::Dap { .. }
 6118                | CompletionSource::Custom => {
 6119                    return Ok(());
 6120                }
 6121            }
 6122        };
 6123        let resolved_completion = request
 6124            .await
 6125            .into_response()
 6126            .context("resolve completion")?;
 6127
 6128        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6129        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6130
 6131        let mut completions = completions.borrow_mut();
 6132        let completion = &mut completions[completion_index];
 6133        if let CompletionSource::Lsp {
 6134            lsp_completion,
 6135            resolved,
 6136            server_id: completion_server_id,
 6137            ..
 6138        } = &mut completion.source
 6139        {
 6140            if *resolved {
 6141                return Ok(());
 6142            }
 6143            anyhow::ensure!(
 6144                server_id == *completion_server_id,
 6145                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6146            );
 6147            *lsp_completion = Box::new(resolved_completion);
 6148            *resolved = true;
 6149        }
 6150        Ok(())
 6151    }
 6152
 6153    async fn regenerate_completion_labels(
 6154        adapter: Arc<CachedLspAdapter>,
 6155        snapshot: &BufferSnapshot,
 6156        completions: Rc<RefCell<Box<[Completion]>>>,
 6157        completion_index: usize,
 6158    ) -> Result<()> {
 6159        let completion_item = completions.borrow()[completion_index]
 6160            .source
 6161            .lsp_completion(true)
 6162            .map(Cow::into_owned);
 6163        if let Some(lsp_documentation) = completion_item
 6164            .as_ref()
 6165            .and_then(|completion_item| completion_item.documentation.clone())
 6166        {
 6167            let mut completions = completions.borrow_mut();
 6168            let completion = &mut completions[completion_index];
 6169            completion.documentation = Some(lsp_documentation.into());
 6170        } else {
 6171            let mut completions = completions.borrow_mut();
 6172            let completion = &mut completions[completion_index];
 6173            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6174        }
 6175
 6176        let mut new_label = match completion_item {
 6177            Some(completion_item) => {
 6178                // 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
 6179                // So we have to update the label here anyway...
 6180                let language = snapshot.language();
 6181                match language {
 6182                    Some(language) => {
 6183                        adapter
 6184                            .labels_for_completions(
 6185                                std::slice::from_ref(&completion_item),
 6186                                language,
 6187                            )
 6188                            .await?
 6189                    }
 6190                    None => Vec::new(),
 6191                }
 6192                .pop()
 6193                .flatten()
 6194                .unwrap_or_else(|| {
 6195                    CodeLabel::fallback_for_completion(
 6196                        &completion_item,
 6197                        language.map(|language| language.as_ref()),
 6198                    )
 6199                })
 6200            }
 6201            None => CodeLabel::plain(
 6202                completions.borrow()[completion_index].new_text.clone(),
 6203                None,
 6204            ),
 6205        };
 6206        ensure_uniform_list_compatible_label(&mut new_label);
 6207
 6208        let mut completions = completions.borrow_mut();
 6209        let completion = &mut completions[completion_index];
 6210        if completion.label.filter_text() == new_label.filter_text() {
 6211            completion.label = new_label;
 6212        } else {
 6213            log::error!(
 6214                "Resolved completion changed display label from {} to {}. \
 6215                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6216                completion.label.text(),
 6217                new_label.text(),
 6218                completion.label.filter_text(),
 6219                new_label.filter_text()
 6220            );
 6221        }
 6222
 6223        Ok(())
 6224    }
 6225
 6226    async fn resolve_completion_remote(
 6227        project_id: u64,
 6228        server_id: LanguageServerId,
 6229        buffer_id: BufferId,
 6230        completions: Rc<RefCell<Box<[Completion]>>>,
 6231        completion_index: usize,
 6232        client: AnyProtoClient,
 6233    ) -> Result<()> {
 6234        let lsp_completion = {
 6235            let completion = &completions.borrow()[completion_index];
 6236            match &completion.source {
 6237                CompletionSource::Lsp {
 6238                    lsp_completion,
 6239                    resolved,
 6240                    server_id: completion_server_id,
 6241                    ..
 6242                } => {
 6243                    anyhow::ensure!(
 6244                        server_id == *completion_server_id,
 6245                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6246                    );
 6247                    if *resolved {
 6248                        return Ok(());
 6249                    }
 6250                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6251                }
 6252                CompletionSource::Custom
 6253                | CompletionSource::Dap { .. }
 6254                | CompletionSource::BufferWord { .. } => {
 6255                    return Ok(());
 6256                }
 6257            }
 6258        };
 6259        let request = proto::ResolveCompletionDocumentation {
 6260            project_id,
 6261            language_server_id: server_id.0 as u64,
 6262            lsp_completion,
 6263            buffer_id: buffer_id.into(),
 6264        };
 6265
 6266        let response = client
 6267            .request(request)
 6268            .await
 6269            .context("completion documentation resolve proto request")?;
 6270        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6271
 6272        let documentation = if response.documentation.is_empty() {
 6273            CompletionDocumentation::Undocumented
 6274        } else if response.documentation_is_markdown {
 6275            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6276        } else if response.documentation.lines().count() <= 1 {
 6277            CompletionDocumentation::SingleLine(response.documentation.into())
 6278        } else {
 6279            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6280        };
 6281
 6282        let mut completions = completions.borrow_mut();
 6283        let completion = &mut completions[completion_index];
 6284        completion.documentation = Some(documentation);
 6285        if let CompletionSource::Lsp {
 6286            insert_range,
 6287            lsp_completion,
 6288            resolved,
 6289            server_id: completion_server_id,
 6290            lsp_defaults: _,
 6291        } = &mut completion.source
 6292        {
 6293            let completion_insert_range = response
 6294                .old_insert_start
 6295                .and_then(deserialize_anchor)
 6296                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6297            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6298
 6299            if *resolved {
 6300                return Ok(());
 6301            }
 6302            anyhow::ensure!(
 6303                server_id == *completion_server_id,
 6304                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6305            );
 6306            *lsp_completion = Box::new(resolved_lsp_completion);
 6307            *resolved = true;
 6308        }
 6309
 6310        let replace_range = response
 6311            .old_replace_start
 6312            .and_then(deserialize_anchor)
 6313            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6314        if let Some((old_replace_start, old_replace_end)) = replace_range
 6315            && !response.new_text.is_empty()
 6316        {
 6317            completion.new_text = response.new_text;
 6318            completion.replace_range = old_replace_start..old_replace_end;
 6319        }
 6320
 6321        Ok(())
 6322    }
 6323
 6324    pub fn apply_additional_edits_for_completion(
 6325        &self,
 6326        buffer_handle: Entity<Buffer>,
 6327        completions: Rc<RefCell<Box<[Completion]>>>,
 6328        completion_index: usize,
 6329        push_to_history: bool,
 6330        cx: &mut Context<Self>,
 6331    ) -> Task<Result<Option<Transaction>>> {
 6332        if let Some((client, project_id)) = self.upstream_client() {
 6333            let buffer = buffer_handle.read(cx);
 6334            let buffer_id = buffer.remote_id();
 6335            cx.spawn(async move |_, cx| {
 6336                let request = {
 6337                    let completion = completions.borrow()[completion_index].clone();
 6338                    proto::ApplyCompletionAdditionalEdits {
 6339                        project_id,
 6340                        buffer_id: buffer_id.into(),
 6341                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6342                            replace_range: completion.replace_range,
 6343                            new_text: completion.new_text,
 6344                            source: completion.source,
 6345                        })),
 6346                    }
 6347                };
 6348
 6349                if let Some(transaction) = client.request(request).await?.transaction {
 6350                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6351                    buffer_handle
 6352                        .update(cx, |buffer, _| {
 6353                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6354                        })?
 6355                        .await?;
 6356                    if push_to_history {
 6357                        buffer_handle.update(cx, |buffer, _| {
 6358                            buffer.push_transaction(transaction.clone(), Instant::now());
 6359                            buffer.finalize_last_transaction();
 6360                        })?;
 6361                    }
 6362                    Ok(Some(transaction))
 6363                } else {
 6364                    Ok(None)
 6365                }
 6366            })
 6367        } else {
 6368            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6369                let completion = &completions.borrow()[completion_index];
 6370                let server_id = completion.source.server_id()?;
 6371                Some(
 6372                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6373                        .1
 6374                        .clone(),
 6375                )
 6376            }) else {
 6377                return Task::ready(Ok(None));
 6378            };
 6379
 6380            cx.spawn(async move |this, cx| {
 6381                Self::resolve_completion_local(
 6382                    server.clone(),
 6383                    completions.clone(),
 6384                    completion_index,
 6385                )
 6386                .await
 6387                .context("resolving completion")?;
 6388                let completion = completions.borrow()[completion_index].clone();
 6389                let additional_text_edits = completion
 6390                    .source
 6391                    .lsp_completion(true)
 6392                    .as_ref()
 6393                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6394                if let Some(edits) = additional_text_edits {
 6395                    let edits = this
 6396                        .update(cx, |this, cx| {
 6397                            this.as_local_mut().unwrap().edits_from_lsp(
 6398                                &buffer_handle,
 6399                                edits,
 6400                                server.server_id(),
 6401                                None,
 6402                                cx,
 6403                            )
 6404                        })?
 6405                        .await?;
 6406
 6407                    buffer_handle.update(cx, |buffer, cx| {
 6408                        buffer.finalize_last_transaction();
 6409                        buffer.start_transaction();
 6410
 6411                        for (range, text) in edits {
 6412                            let primary = &completion.replace_range;
 6413
 6414                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6415                            // and the primary completion is just an insertion (empty range), then this is likely
 6416                            // an auto-import scenario and should not be considered overlapping
 6417                            // https://github.com/zed-industries/zed/issues/26136
 6418                            let is_file_start_auto_import = {
 6419                                let snapshot = buffer.snapshot();
 6420                                let primary_start_point = primary.start.to_point(&snapshot);
 6421                                let range_start_point = range.start.to_point(&snapshot);
 6422
 6423                                let result = primary_start_point.row == 0
 6424                                    && primary_start_point.column == 0
 6425                                    && range_start_point.row == 0
 6426                                    && range_start_point.column == 0;
 6427
 6428                                result
 6429                            };
 6430
 6431                            let has_overlap = if is_file_start_auto_import {
 6432                                false
 6433                            } else {
 6434                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6435                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6436                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6437                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6438                                let result = start_within || end_within;
 6439                                result
 6440                            };
 6441
 6442                            //Skip additional edits which overlap with the primary completion edit
 6443                            //https://github.com/zed-industries/zed/pull/1871
 6444                            if !has_overlap {
 6445                                buffer.edit([(range, text)], None, cx);
 6446                            }
 6447                        }
 6448
 6449                        let transaction = if buffer.end_transaction(cx).is_some() {
 6450                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6451                            if !push_to_history {
 6452                                buffer.forget_transaction(transaction.id);
 6453                            }
 6454                            Some(transaction)
 6455                        } else {
 6456                            None
 6457                        };
 6458                        Ok(transaction)
 6459                    })?
 6460                } else {
 6461                    Ok(None)
 6462                }
 6463            })
 6464        }
 6465    }
 6466
 6467    pub fn pull_diagnostics(
 6468        &mut self,
 6469        buffer: Entity<Buffer>,
 6470        cx: &mut Context<Self>,
 6471    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6472        let buffer_id = buffer.read(cx).remote_id();
 6473
 6474        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6475            let mut suitable_capabilities = None;
 6476            // Are we capable for proto request?
 6477            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6478                &buffer,
 6479                |capabilities| {
 6480                    if let Some(caps) = &capabilities.diagnostic_provider {
 6481                        suitable_capabilities = Some(caps.clone());
 6482                        true
 6483                    } else {
 6484                        false
 6485                    }
 6486                },
 6487                cx,
 6488            );
 6489            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6490            let Some(dynamic_caps) = suitable_capabilities else {
 6491                return Task::ready(Ok(None));
 6492            };
 6493            assert!(any_server_has_diagnostics_provider);
 6494
 6495            let request = GetDocumentDiagnostics {
 6496                previous_result_id: None,
 6497                dynamic_caps,
 6498            };
 6499            let request_task = client.request_lsp(
 6500                upstream_project_id,
 6501                None,
 6502                LSP_REQUEST_TIMEOUT,
 6503                cx.background_executor().clone(),
 6504                request.to_proto(upstream_project_id, buffer.read(cx)),
 6505            );
 6506            cx.background_spawn(async move {
 6507                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6508                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6509                // Do not attempt to further process the dummy responses here.
 6510                let _response = request_task.await?;
 6511                Ok(None)
 6512            })
 6513        } else {
 6514            let servers = buffer.update(cx, |buffer, cx| {
 6515                self.language_servers_for_local_buffer(buffer, cx)
 6516                    .map(|(_, server)| server.clone())
 6517                    .collect::<Vec<_>>()
 6518            });
 6519
 6520            let pull_diagnostics = servers
 6521                .into_iter()
 6522                .flat_map(|server| {
 6523                    let result = maybe!({
 6524                        let local = self.as_local()?;
 6525                        let server_id = server.server_id();
 6526                        let providers_with_identifiers = local
 6527                            .language_server_dynamic_registrations
 6528                            .get(&server_id)
 6529                            .into_iter()
 6530                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6531                            .collect::<Vec<_>>();
 6532                        Some(
 6533                            providers_with_identifiers
 6534                                .into_iter()
 6535                                .map(|dynamic_caps| {
 6536                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6537                                    self.request_lsp(
 6538                                        buffer.clone(),
 6539                                        LanguageServerToQuery::Other(server_id),
 6540                                        GetDocumentDiagnostics {
 6541                                            previous_result_id: result_id,
 6542                                            dynamic_caps,
 6543                                        },
 6544                                        cx,
 6545                                    )
 6546                                })
 6547                                .collect::<Vec<_>>(),
 6548                        )
 6549                    });
 6550
 6551                    result.unwrap_or_default()
 6552                })
 6553                .collect::<Vec<_>>();
 6554
 6555            cx.background_spawn(async move {
 6556                let mut responses = Vec::new();
 6557                for diagnostics in join_all(pull_diagnostics).await {
 6558                    responses.extend(diagnostics?);
 6559                }
 6560                Ok(Some(responses))
 6561            })
 6562        }
 6563    }
 6564
 6565    pub fn applicable_inlay_chunks(
 6566        &mut self,
 6567        buffer: &Entity<Buffer>,
 6568        ranges: &[Range<text::Anchor>],
 6569        cx: &mut Context<Self>,
 6570    ) -> Vec<Range<BufferRow>> {
 6571        self.latest_lsp_data(buffer, cx)
 6572            .inlay_hints
 6573            .applicable_chunks(ranges)
 6574            .map(|chunk| chunk.start..chunk.end)
 6575            .collect()
 6576    }
 6577
 6578    pub fn invalidate_inlay_hints<'a>(
 6579        &'a mut self,
 6580        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6581    ) {
 6582        for buffer_id in for_buffers {
 6583            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6584                lsp_data.inlay_hints.clear();
 6585            }
 6586        }
 6587    }
 6588
 6589    pub fn inlay_hints(
 6590        &mut self,
 6591        invalidate: InvalidationStrategy,
 6592        buffer: Entity<Buffer>,
 6593        ranges: Vec<Range<text::Anchor>>,
 6594        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6595        cx: &mut Context<Self>,
 6596    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6597        let buffer_snapshot = buffer.read(cx).snapshot();
 6598        let next_hint_id = self.next_hint_id.clone();
 6599        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6600        let mut lsp_refresh_requested = false;
 6601        let for_server = if let InvalidationStrategy::RefreshRequested {
 6602            server_id,
 6603            request_id,
 6604        } = invalidate
 6605        {
 6606            let invalidated = lsp_data
 6607                .inlay_hints
 6608                .invalidate_for_server_refresh(server_id, request_id);
 6609            lsp_refresh_requested = invalidated;
 6610            Some(server_id)
 6611        } else {
 6612            None
 6613        };
 6614        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6615        let known_chunks = known_chunks
 6616            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6617            .map(|(_, known_chunks)| known_chunks)
 6618            .unwrap_or_default();
 6619
 6620        let mut hint_fetch_tasks = Vec::new();
 6621        let mut cached_inlay_hints = None;
 6622        let mut ranges_to_query = None;
 6623        let applicable_chunks = existing_inlay_hints
 6624            .applicable_chunks(ranges.as_slice())
 6625            .filter(|chunk| !known_chunks.contains(&(chunk.start..chunk.end)))
 6626            .collect::<Vec<_>>();
 6627        if applicable_chunks.is_empty() {
 6628            return HashMap::default();
 6629        }
 6630
 6631        let last_chunk_number = existing_inlay_hints.buffer_chunks_len() - 1;
 6632
 6633        for row_chunk in applicable_chunks {
 6634            match (
 6635                existing_inlay_hints
 6636                    .cached_hints(&row_chunk)
 6637                    .filter(|_| !lsp_refresh_requested)
 6638                    .cloned(),
 6639                existing_inlay_hints
 6640                    .fetched_hints(&row_chunk)
 6641                    .as_ref()
 6642                    .filter(|_| !lsp_refresh_requested)
 6643                    .cloned(),
 6644            ) {
 6645                (None, None) => {
 6646                    let end = if last_chunk_number == row_chunk.id {
 6647                        Point::new(row_chunk.end, buffer_snapshot.line_len(row_chunk.end))
 6648                    } else {
 6649                        Point::new(row_chunk.end, 0)
 6650                    };
 6651                    ranges_to_query.get_or_insert_with(Vec::new).push((
 6652                        row_chunk,
 6653                        buffer_snapshot.anchor_before(Point::new(row_chunk.start, 0))
 6654                            ..buffer_snapshot.anchor_after(end),
 6655                    ));
 6656                }
 6657                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6658                (Some(cached_hints), None) => {
 6659                    for (server_id, cached_hints) in cached_hints {
 6660                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6661                            cached_inlay_hints
 6662                                .get_or_insert_with(HashMap::default)
 6663                                .entry(row_chunk.start..row_chunk.end)
 6664                                .or_insert_with(HashMap::default)
 6665                                .entry(server_id)
 6666                                .or_insert_with(Vec::new)
 6667                                .extend(cached_hints);
 6668                        }
 6669                    }
 6670                }
 6671                (Some(cached_hints), Some(fetched_hints)) => {
 6672                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6673                    for (server_id, cached_hints) in cached_hints {
 6674                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6675                            cached_inlay_hints
 6676                                .get_or_insert_with(HashMap::default)
 6677                                .entry(row_chunk.start..row_chunk.end)
 6678                                .or_insert_with(HashMap::default)
 6679                                .entry(server_id)
 6680                                .or_insert_with(Vec::new)
 6681                                .extend(cached_hints);
 6682                        }
 6683                    }
 6684                }
 6685            }
 6686        }
 6687
 6688        if hint_fetch_tasks.is_empty()
 6689            && ranges_to_query
 6690                .as_ref()
 6691                .is_none_or(|ranges| ranges.is_empty())
 6692            && let Some(cached_inlay_hints) = cached_inlay_hints
 6693        {
 6694            cached_inlay_hints
 6695                .into_iter()
 6696                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6697                .collect()
 6698        } else {
 6699            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6700                let next_hint_id = next_hint_id.clone();
 6701                let buffer = buffer.clone();
 6702                let new_inlay_hints = cx
 6703                    .spawn(async move |lsp_store, cx| {
 6704                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6705                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6706                        })?;
 6707                        new_fetch_task
 6708                            .await
 6709                            .and_then(|new_hints_by_server| {
 6710                                lsp_store.update(cx, |lsp_store, cx| {
 6711                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6712                                    let update_cache = !lsp_data
 6713                                        .buffer_version
 6714                                        .changed_since(&buffer.read(cx).version());
 6715                                    if new_hints_by_server.is_empty() {
 6716                                        if update_cache {
 6717                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6718                                        }
 6719                                        HashMap::default()
 6720                                    } else {
 6721                                        new_hints_by_server
 6722                                            .into_iter()
 6723                                            .map(|(server_id, new_hints)| {
 6724                                                let new_hints = new_hints
 6725                                                    .into_iter()
 6726                                                    .map(|new_hint| {
 6727                                                        (
 6728                                                            InlayId::Hint(next_hint_id.fetch_add(
 6729                                                                1,
 6730                                                                atomic::Ordering::AcqRel,
 6731                                                            )),
 6732                                                            new_hint,
 6733                                                        )
 6734                                                    })
 6735                                                    .collect::<Vec<_>>();
 6736                                                if update_cache {
 6737                                                    lsp_data.inlay_hints.insert_new_hints(
 6738                                                        chunk,
 6739                                                        server_id,
 6740                                                        new_hints.clone(),
 6741                                                    );
 6742                                                }
 6743                                                (server_id, new_hints)
 6744                                            })
 6745                                            .collect()
 6746                                    }
 6747                                })
 6748                            })
 6749                            .map_err(Arc::new)
 6750                    })
 6751                    .shared();
 6752
 6753                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6754                *fetch_task = Some(new_inlay_hints.clone());
 6755                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6756            }
 6757
 6758            cached_inlay_hints
 6759                .unwrap_or_default()
 6760                .into_iter()
 6761                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6762                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6763                    (
 6764                        chunk.start..chunk.end,
 6765                        cx.spawn(async move |_, _| {
 6766                            hints_fetch.await.map_err(|e| {
 6767                                if e.error_code() != ErrorCode::Internal {
 6768                                    anyhow!(e.error_code())
 6769                                } else {
 6770                                    anyhow!("{e:#}")
 6771                                }
 6772                            })
 6773                        }),
 6774                    )
 6775                }))
 6776                .collect()
 6777        }
 6778    }
 6779
 6780    fn fetch_inlay_hints(
 6781        &mut self,
 6782        for_server: Option<LanguageServerId>,
 6783        buffer: &Entity<Buffer>,
 6784        range: Range<Anchor>,
 6785        cx: &mut Context<Self>,
 6786    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6787        let request = InlayHints {
 6788            range: range.clone(),
 6789        };
 6790        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6791            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6792                return Task::ready(Ok(HashMap::default()));
 6793            }
 6794            let request_task = upstream_client.request_lsp(
 6795                project_id,
 6796                for_server.map(|id| id.to_proto()),
 6797                LSP_REQUEST_TIMEOUT,
 6798                cx.background_executor().clone(),
 6799                request.to_proto(project_id, buffer.read(cx)),
 6800            );
 6801            let buffer = buffer.clone();
 6802            cx.spawn(async move |weak_lsp_store, cx| {
 6803                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6804                    return Ok(HashMap::default());
 6805                };
 6806                let Some(responses) = request_task.await? else {
 6807                    return Ok(HashMap::default());
 6808                };
 6809
 6810                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 6811                    let lsp_store = lsp_store.clone();
 6812                    let buffer = buffer.clone();
 6813                    let cx = cx.clone();
 6814                    let request = request.clone();
 6815                    async move {
 6816                        (
 6817                            LanguageServerId::from_proto(response.server_id),
 6818                            request
 6819                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6820                                .await,
 6821                        )
 6822                    }
 6823                }))
 6824                .await;
 6825
 6826                let mut has_errors = false;
 6827                let inlay_hints = inlay_hints
 6828                    .into_iter()
 6829                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 6830                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 6831                        Err(e) => {
 6832                            has_errors = true;
 6833                            log::error!("{e:#}");
 6834                            None
 6835                        }
 6836                    })
 6837                    .collect::<HashMap<_, _>>();
 6838                anyhow::ensure!(
 6839                    !has_errors || !inlay_hints.is_empty(),
 6840                    "Failed to fetch inlay hints"
 6841                );
 6842                Ok(inlay_hints)
 6843            })
 6844        } else {
 6845            let inlay_hints_task = match for_server {
 6846                Some(server_id) => {
 6847                    let server_task = self.request_lsp(
 6848                        buffer.clone(),
 6849                        LanguageServerToQuery::Other(server_id),
 6850                        request,
 6851                        cx,
 6852                    );
 6853                    cx.background_spawn(async move {
 6854                        let mut responses = Vec::new();
 6855                        match server_task.await {
 6856                            Ok(response) => responses.push((server_id, response)),
 6857                            Err(e) => log::error!(
 6858                                "Error handling response for inlay hints request: {e:#}"
 6859                            ),
 6860                        }
 6861                        responses
 6862                    })
 6863                }
 6864                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 6865            };
 6866            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 6867            cx.background_spawn(async move {
 6868                Ok(inlay_hints_task
 6869                    .await
 6870                    .into_iter()
 6871                    .map(|(server_id, mut new_hints)| {
 6872                        new_hints.retain(|hint| {
 6873                            hint.position.is_valid(&buffer_snapshot)
 6874                                && range.start.is_valid(&buffer_snapshot)
 6875                                && range.end.is_valid(&buffer_snapshot)
 6876                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 6877                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 6878                        });
 6879                        (server_id, new_hints)
 6880                    })
 6881                    .collect())
 6882            })
 6883        }
 6884    }
 6885
 6886    pub fn pull_diagnostics_for_buffer(
 6887        &mut self,
 6888        buffer: Entity<Buffer>,
 6889        cx: &mut Context<Self>,
 6890    ) -> Task<anyhow::Result<()>> {
 6891        let diagnostics = self.pull_diagnostics(buffer, cx);
 6892        cx.spawn(async move |lsp_store, cx| {
 6893            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6894                return Ok(());
 6895            };
 6896            lsp_store.update(cx, |lsp_store, cx| {
 6897                if lsp_store.as_local().is_none() {
 6898                    return;
 6899                }
 6900
 6901                let mut unchanged_buffers = HashSet::default();
 6902                let mut changed_buffers = HashSet::default();
 6903                let server_diagnostics_updates = diagnostics
 6904                    .into_iter()
 6905                    .filter_map(|diagnostics_set| match diagnostics_set {
 6906                        LspPullDiagnostics::Response {
 6907                            server_id,
 6908                            uri,
 6909                            diagnostics,
 6910                        } => Some((server_id, uri, diagnostics)),
 6911                        LspPullDiagnostics::Default => None,
 6912                    })
 6913                    .fold(
 6914                        HashMap::default(),
 6915                        |mut acc, (server_id, uri, diagnostics)| {
 6916                            let (result_id, diagnostics) = match diagnostics {
 6917                                PulledDiagnostics::Unchanged { result_id } => {
 6918                                    unchanged_buffers.insert(uri.clone());
 6919                                    (Some(result_id), Vec::new())
 6920                                }
 6921                                PulledDiagnostics::Changed {
 6922                                    result_id,
 6923                                    diagnostics,
 6924                                } => {
 6925                                    changed_buffers.insert(uri.clone());
 6926                                    (result_id, diagnostics)
 6927                                }
 6928                            };
 6929                            let disk_based_sources = Cow::Owned(
 6930                                lsp_store
 6931                                    .language_server_adapter_for_id(server_id)
 6932                                    .as_ref()
 6933                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6934                                    .unwrap_or(&[])
 6935                                    .to_vec(),
 6936                            );
 6937                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6938                                DocumentDiagnosticsUpdate {
 6939                                    server_id,
 6940                                    diagnostics: lsp::PublishDiagnosticsParams {
 6941                                        uri,
 6942                                        diagnostics,
 6943                                        version: None,
 6944                                    },
 6945                                    result_id,
 6946                                    disk_based_sources,
 6947                                },
 6948                            );
 6949                            acc
 6950                        },
 6951                    );
 6952
 6953                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6954                    lsp_store
 6955                        .merge_lsp_diagnostics(
 6956                            DiagnosticSourceKind::Pulled,
 6957                            diagnostic_updates,
 6958                            |buffer, old_diagnostic, cx| {
 6959                                File::from_dyn(buffer.file())
 6960                                    .and_then(|file| {
 6961                                        let abs_path = file.as_local()?.abs_path(cx);
 6962                                        lsp::Uri::from_file_path(abs_path).ok()
 6963                                    })
 6964                                    .is_none_or(|buffer_uri| {
 6965                                        unchanged_buffers.contains(&buffer_uri)
 6966                                            || match old_diagnostic.source_kind {
 6967                                                DiagnosticSourceKind::Pulled => {
 6968                                                    !changed_buffers.contains(&buffer_uri)
 6969                                                }
 6970                                                DiagnosticSourceKind::Other
 6971                                                | DiagnosticSourceKind::Pushed => true,
 6972                                            }
 6973                                    })
 6974                            },
 6975                            cx,
 6976                        )
 6977                        .log_err();
 6978                }
 6979            })
 6980        })
 6981    }
 6982
 6983    pub fn document_colors(
 6984        &mut self,
 6985        known_cache_version: Option<usize>,
 6986        buffer: Entity<Buffer>,
 6987        cx: &mut Context<Self>,
 6988    ) -> Option<DocumentColorTask> {
 6989        let version_queried_for = buffer.read(cx).version();
 6990        let buffer_id = buffer.read(cx).remote_id();
 6991
 6992        let current_language_servers = self.as_local().map(|local| {
 6993            local
 6994                .buffers_opened_in_servers
 6995                .get(&buffer_id)
 6996                .cloned()
 6997                .unwrap_or_default()
 6998        });
 6999
 7000        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7001            if let Some(cached_colors) = &lsp_data.document_colors {
 7002                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7003                    let has_different_servers =
 7004                        current_language_servers.is_some_and(|current_language_servers| {
 7005                            current_language_servers
 7006                                != cached_colors.colors.keys().copied().collect()
 7007                        });
 7008                    if !has_different_servers {
 7009                        let cache_version = cached_colors.cache_version;
 7010                        if Some(cache_version) == known_cache_version {
 7011                            return None;
 7012                        } else {
 7013                            return Some(
 7014                                Task::ready(Ok(DocumentColors {
 7015                                    colors: cached_colors
 7016                                        .colors
 7017                                        .values()
 7018                                        .flatten()
 7019                                        .cloned()
 7020                                        .collect(),
 7021                                    cache_version: Some(cache_version),
 7022                                }))
 7023                                .shared(),
 7024                            );
 7025                        }
 7026                    }
 7027                }
 7028            }
 7029        }
 7030
 7031        let color_lsp_data = self
 7032            .latest_lsp_data(&buffer, cx)
 7033            .document_colors
 7034            .get_or_insert_default();
 7035        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7036            && !version_queried_for.changed_since(updating_for)
 7037        {
 7038            return Some(running_update.clone());
 7039        }
 7040        let buffer_version_queried_for = version_queried_for.clone();
 7041        let new_task = cx
 7042            .spawn(async move |lsp_store, cx| {
 7043                cx.background_executor()
 7044                    .timer(Duration::from_millis(30))
 7045                    .await;
 7046                let fetched_colors = lsp_store
 7047                    .update(cx, |lsp_store, cx| {
 7048                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7049                    })?
 7050                    .await
 7051                    .context("fetching document colors")
 7052                    .map_err(Arc::new);
 7053                let fetched_colors = match fetched_colors {
 7054                    Ok(fetched_colors) => {
 7055                        if Some(true)
 7056                            == buffer
 7057                                .update(cx, |buffer, _| {
 7058                                    buffer.version() != buffer_version_queried_for
 7059                                })
 7060                                .ok()
 7061                        {
 7062                            return Ok(DocumentColors::default());
 7063                        }
 7064                        fetched_colors
 7065                    }
 7066                    Err(e) => {
 7067                        lsp_store
 7068                            .update(cx, |lsp_store, _| {
 7069                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7070                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7071                                        document_colors.colors_update = None;
 7072                                    }
 7073                                }
 7074                            })
 7075                            .ok();
 7076                        return Err(e);
 7077                    }
 7078                };
 7079
 7080                lsp_store
 7081                    .update(cx, |lsp_store, cx| {
 7082                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7083                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7084
 7085                        if let Some(fetched_colors) = fetched_colors {
 7086                            if lsp_data.buffer_version == buffer_version_queried_for {
 7087                                lsp_colors.colors.extend(fetched_colors);
 7088                                lsp_colors.cache_version += 1;
 7089                            } else if !lsp_data
 7090                                .buffer_version
 7091                                .changed_since(&buffer_version_queried_for)
 7092                            {
 7093                                lsp_data.buffer_version = buffer_version_queried_for;
 7094                                lsp_colors.colors = fetched_colors;
 7095                                lsp_colors.cache_version += 1;
 7096                            }
 7097                        }
 7098                        lsp_colors.colors_update = None;
 7099                        let colors = lsp_colors
 7100                            .colors
 7101                            .values()
 7102                            .flatten()
 7103                            .cloned()
 7104                            .collect::<HashSet<_>>();
 7105                        DocumentColors {
 7106                            colors,
 7107                            cache_version: Some(lsp_colors.cache_version),
 7108                        }
 7109                    })
 7110                    .map_err(Arc::new)
 7111            })
 7112            .shared();
 7113        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7114        Some(new_task)
 7115    }
 7116
 7117    fn fetch_document_colors_for_buffer(
 7118        &mut self,
 7119        buffer: &Entity<Buffer>,
 7120        cx: &mut Context<Self>,
 7121    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7122        if let Some((client, project_id)) = self.upstream_client() {
 7123            let request = GetDocumentColor {};
 7124            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7125                return Task::ready(Ok(None));
 7126            }
 7127
 7128            let request_task = client.request_lsp(
 7129                project_id,
 7130                None,
 7131                LSP_REQUEST_TIMEOUT,
 7132                cx.background_executor().clone(),
 7133                request.to_proto(project_id, buffer.read(cx)),
 7134            );
 7135            let buffer = buffer.clone();
 7136            cx.spawn(async move |lsp_store, cx| {
 7137                let Some(project) = lsp_store.upgrade() else {
 7138                    return Ok(None);
 7139                };
 7140                let colors = join_all(
 7141                    request_task
 7142                        .await
 7143                        .log_err()
 7144                        .flatten()
 7145                        .map(|response| response.payload)
 7146                        .unwrap_or_default()
 7147                        .into_iter()
 7148                        .map(|color_response| {
 7149                            let response = request.response_from_proto(
 7150                                color_response.response,
 7151                                project.clone(),
 7152                                buffer.clone(),
 7153                                cx.clone(),
 7154                            );
 7155                            async move {
 7156                                (
 7157                                    LanguageServerId::from_proto(color_response.server_id),
 7158                                    response.await.log_err().unwrap_or_default(),
 7159                                )
 7160                            }
 7161                        }),
 7162                )
 7163                .await
 7164                .into_iter()
 7165                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7166                    acc.entry(server_id)
 7167                        .or_insert_with(HashSet::default)
 7168                        .extend(colors);
 7169                    acc
 7170                });
 7171                Ok(Some(colors))
 7172            })
 7173        } else {
 7174            let document_colors_task =
 7175                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7176            cx.background_spawn(async move {
 7177                Ok(Some(
 7178                    document_colors_task
 7179                        .await
 7180                        .into_iter()
 7181                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7182                            acc.entry(server_id)
 7183                                .or_insert_with(HashSet::default)
 7184                                .extend(colors);
 7185                            acc
 7186                        })
 7187                        .into_iter()
 7188                        .collect(),
 7189                ))
 7190            })
 7191        }
 7192    }
 7193
 7194    pub fn signature_help<T: ToPointUtf16>(
 7195        &mut self,
 7196        buffer: &Entity<Buffer>,
 7197        position: T,
 7198        cx: &mut Context<Self>,
 7199    ) -> Task<Option<Vec<SignatureHelp>>> {
 7200        let position = position.to_point_utf16(buffer.read(cx));
 7201
 7202        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7203            let request = GetSignatureHelp { position };
 7204            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7205                return Task::ready(None);
 7206            }
 7207            let request_task = client.request_lsp(
 7208                upstream_project_id,
 7209                None,
 7210                LSP_REQUEST_TIMEOUT,
 7211                cx.background_executor().clone(),
 7212                request.to_proto(upstream_project_id, buffer.read(cx)),
 7213            );
 7214            let buffer = buffer.clone();
 7215            cx.spawn(async move |weak_project, cx| {
 7216                let project = weak_project.upgrade()?;
 7217                let signatures = join_all(
 7218                    request_task
 7219                        .await
 7220                        .log_err()
 7221                        .flatten()
 7222                        .map(|response| response.payload)
 7223                        .unwrap_or_default()
 7224                        .into_iter()
 7225                        .map(|response| {
 7226                            let response = GetSignatureHelp { position }.response_from_proto(
 7227                                response.response,
 7228                                project.clone(),
 7229                                buffer.clone(),
 7230                                cx.clone(),
 7231                            );
 7232                            async move { response.await.log_err().flatten() }
 7233                        }),
 7234                )
 7235                .await
 7236                .into_iter()
 7237                .flatten()
 7238                .collect();
 7239                Some(signatures)
 7240            })
 7241        } else {
 7242            let all_actions_task = self.request_multiple_lsp_locally(
 7243                buffer,
 7244                Some(position),
 7245                GetSignatureHelp { position },
 7246                cx,
 7247            );
 7248            cx.background_spawn(async move {
 7249                Some(
 7250                    all_actions_task
 7251                        .await
 7252                        .into_iter()
 7253                        .flat_map(|(_, actions)| actions)
 7254                        .collect::<Vec<_>>(),
 7255                )
 7256            })
 7257        }
 7258    }
 7259
 7260    pub fn hover(
 7261        &mut self,
 7262        buffer: &Entity<Buffer>,
 7263        position: PointUtf16,
 7264        cx: &mut Context<Self>,
 7265    ) -> Task<Option<Vec<Hover>>> {
 7266        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7267            let request = GetHover { position };
 7268            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7269                return Task::ready(None);
 7270            }
 7271            let request_task = client.request_lsp(
 7272                upstream_project_id,
 7273                None,
 7274                LSP_REQUEST_TIMEOUT,
 7275                cx.background_executor().clone(),
 7276                request.to_proto(upstream_project_id, buffer.read(cx)),
 7277            );
 7278            let buffer = buffer.clone();
 7279            cx.spawn(async move |weak_project, cx| {
 7280                let project = weak_project.upgrade()?;
 7281                let hovers = join_all(
 7282                    request_task
 7283                        .await
 7284                        .log_err()
 7285                        .flatten()
 7286                        .map(|response| response.payload)
 7287                        .unwrap_or_default()
 7288                        .into_iter()
 7289                        .map(|response| {
 7290                            let response = GetHover { position }.response_from_proto(
 7291                                response.response,
 7292                                project.clone(),
 7293                                buffer.clone(),
 7294                                cx.clone(),
 7295                            );
 7296                            async move {
 7297                                response
 7298                                    .await
 7299                                    .log_err()
 7300                                    .flatten()
 7301                                    .and_then(remove_empty_hover_blocks)
 7302                            }
 7303                        }),
 7304                )
 7305                .await
 7306                .into_iter()
 7307                .flatten()
 7308                .collect();
 7309                Some(hovers)
 7310            })
 7311        } else {
 7312            let all_actions_task = self.request_multiple_lsp_locally(
 7313                buffer,
 7314                Some(position),
 7315                GetHover { position },
 7316                cx,
 7317            );
 7318            cx.background_spawn(async move {
 7319                Some(
 7320                    all_actions_task
 7321                        .await
 7322                        .into_iter()
 7323                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7324                        .collect::<Vec<Hover>>(),
 7325                )
 7326            })
 7327        }
 7328    }
 7329
 7330    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7331        let language_registry = self.languages.clone();
 7332
 7333        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7334            let request = upstream_client.request(proto::GetProjectSymbols {
 7335                project_id: *project_id,
 7336                query: query.to_string(),
 7337            });
 7338            cx.foreground_executor().spawn(async move {
 7339                let response = request.await?;
 7340                let mut symbols = Vec::new();
 7341                let core_symbols = response
 7342                    .symbols
 7343                    .into_iter()
 7344                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7345                    .collect::<Vec<_>>();
 7346                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7347                    .await;
 7348                Ok(symbols)
 7349            })
 7350        } else if let Some(local) = self.as_local() {
 7351            struct WorkspaceSymbolsResult {
 7352                server_id: LanguageServerId,
 7353                lsp_adapter: Arc<CachedLspAdapter>,
 7354                worktree: WeakEntity<Worktree>,
 7355                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7356            }
 7357
 7358            let mut requests = Vec::new();
 7359            let mut requested_servers = BTreeSet::new();
 7360            for (seed, state) in local.language_server_ids.iter() {
 7361                let Some(worktree_handle) = self
 7362                    .worktree_store
 7363                    .read(cx)
 7364                    .worktree_for_id(seed.worktree_id, cx)
 7365                else {
 7366                    continue;
 7367                };
 7368                let worktree = worktree_handle.read(cx);
 7369                if !worktree.is_visible() {
 7370                    continue;
 7371                }
 7372
 7373                if !requested_servers.insert(state.id) {
 7374                    continue;
 7375                }
 7376
 7377                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7378                    Some(LanguageServerState::Running {
 7379                        adapter, server, ..
 7380                    }) => (adapter.clone(), server),
 7381
 7382                    _ => continue,
 7383                };
 7384                let supports_workspace_symbol_request =
 7385                    match server.capabilities().workspace_symbol_provider {
 7386                        Some(OneOf::Left(supported)) => supported,
 7387                        Some(OneOf::Right(_)) => true,
 7388                        None => false,
 7389                    };
 7390                if !supports_workspace_symbol_request {
 7391                    continue;
 7392                }
 7393                let worktree_handle = worktree_handle.clone();
 7394                let server_id = server.server_id();
 7395                requests.push(
 7396                        server
 7397                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7398                                lsp::WorkspaceSymbolParams {
 7399                                    query: query.to_string(),
 7400                                    ..Default::default()
 7401                                },
 7402                            )
 7403                            .map(move |response| {
 7404                                let lsp_symbols = response.into_response()
 7405                                    .context("workspace symbols request")
 7406                                    .log_err()
 7407                                    .flatten()
 7408                                    .map(|symbol_response| match symbol_response {
 7409                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7410                                            flat_responses.into_iter().map(|lsp_symbol| {
 7411                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7412                                            }).collect::<Vec<_>>()
 7413                                        }
 7414                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7415                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7416                                                let location = match lsp_symbol.location {
 7417                                                    OneOf::Left(location) => location,
 7418                                                    OneOf::Right(_) => {
 7419                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7420                                                        return None
 7421                                                    }
 7422                                                };
 7423                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7424                                            }).collect::<Vec<_>>()
 7425                                        }
 7426                                    }).unwrap_or_default();
 7427
 7428                                WorkspaceSymbolsResult {
 7429                                    server_id,
 7430                                    lsp_adapter,
 7431                                    worktree: worktree_handle.downgrade(),
 7432                                    lsp_symbols,
 7433                                }
 7434                            }),
 7435                    );
 7436            }
 7437
 7438            cx.spawn(async move |this, cx| {
 7439                let responses = futures::future::join_all(requests).await;
 7440                let this = match this.upgrade() {
 7441                    Some(this) => this,
 7442                    None => return Ok(Vec::new()),
 7443                };
 7444
 7445                let mut symbols = Vec::new();
 7446                for result in responses {
 7447                    let core_symbols = this.update(cx, |this, cx| {
 7448                        result
 7449                            .lsp_symbols
 7450                            .into_iter()
 7451                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7452                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7453                                let source_worktree = result.worktree.upgrade()?;
 7454                                let source_worktree_id = source_worktree.read(cx).id();
 7455
 7456                                let path = if let Some((tree, rel_path)) =
 7457                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7458                                {
 7459                                    let worktree_id = tree.read(cx).id();
 7460                                    SymbolLocation::InProject(ProjectPath {
 7461                                        worktree_id,
 7462                                        path: rel_path,
 7463                                    })
 7464                                } else {
 7465                                    SymbolLocation::OutsideProject {
 7466                                        signature: this.symbol_signature(&abs_path),
 7467                                        abs_path: abs_path.into(),
 7468                                    }
 7469                                };
 7470
 7471                                Some(CoreSymbol {
 7472                                    source_language_server_id: result.server_id,
 7473                                    language_server_name: result.lsp_adapter.name.clone(),
 7474                                    source_worktree_id,
 7475                                    path,
 7476                                    kind: symbol_kind,
 7477                                    name: symbol_name,
 7478                                    range: range_from_lsp(symbol_location.range),
 7479                                })
 7480                            })
 7481                            .collect()
 7482                    })?;
 7483
 7484                    populate_labels_for_symbols(
 7485                        core_symbols,
 7486                        &language_registry,
 7487                        Some(result.lsp_adapter),
 7488                        &mut symbols,
 7489                    )
 7490                    .await;
 7491                }
 7492
 7493                Ok(symbols)
 7494            })
 7495        } else {
 7496            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7497        }
 7498    }
 7499
 7500    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7501        let mut summary = DiagnosticSummary::default();
 7502        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7503            summary.error_count += path_summary.error_count;
 7504            summary.warning_count += path_summary.warning_count;
 7505        }
 7506        summary
 7507    }
 7508
 7509    /// Returns the diagnostic summary for a specific project path.
 7510    pub fn diagnostic_summary_for_path(
 7511        &self,
 7512        project_path: &ProjectPath,
 7513        _: &App,
 7514    ) -> DiagnosticSummary {
 7515        if let Some(summaries) = self
 7516            .diagnostic_summaries
 7517            .get(&project_path.worktree_id)
 7518            .and_then(|map| map.get(&project_path.path))
 7519        {
 7520            let (error_count, warning_count) = summaries.iter().fold(
 7521                (0, 0),
 7522                |(error_count, warning_count), (_language_server_id, summary)| {
 7523                    (
 7524                        error_count + summary.error_count,
 7525                        warning_count + summary.warning_count,
 7526                    )
 7527                },
 7528            );
 7529
 7530            DiagnosticSummary {
 7531                error_count,
 7532                warning_count,
 7533            }
 7534        } else {
 7535            DiagnosticSummary::default()
 7536        }
 7537    }
 7538
 7539    pub fn diagnostic_summaries<'a>(
 7540        &'a self,
 7541        include_ignored: bool,
 7542        cx: &'a App,
 7543    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7544        self.worktree_store
 7545            .read(cx)
 7546            .visible_worktrees(cx)
 7547            .filter_map(|worktree| {
 7548                let worktree = worktree.read(cx);
 7549                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7550            })
 7551            .flat_map(move |(worktree, summaries)| {
 7552                let worktree_id = worktree.id();
 7553                summaries
 7554                    .iter()
 7555                    .filter(move |(path, _)| {
 7556                        include_ignored
 7557                            || worktree
 7558                                .entry_for_path(path.as_ref())
 7559                                .is_some_and(|entry| !entry.is_ignored)
 7560                    })
 7561                    .flat_map(move |(path, summaries)| {
 7562                        summaries.iter().map(move |(server_id, summary)| {
 7563                            (
 7564                                ProjectPath {
 7565                                    worktree_id,
 7566                                    path: path.clone(),
 7567                                },
 7568                                *server_id,
 7569                                *summary,
 7570                            )
 7571                        })
 7572                    })
 7573            })
 7574    }
 7575
 7576    pub fn on_buffer_edited(
 7577        &mut self,
 7578        buffer: Entity<Buffer>,
 7579        cx: &mut Context<Self>,
 7580    ) -> Option<()> {
 7581        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7582            Some(
 7583                self.as_local()?
 7584                    .language_servers_for_buffer(buffer, cx)
 7585                    .map(|i| i.1.clone())
 7586                    .collect(),
 7587            )
 7588        })?;
 7589
 7590        let buffer = buffer.read(cx);
 7591        let file = File::from_dyn(buffer.file())?;
 7592        let abs_path = file.as_local()?.abs_path(cx);
 7593        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7594        let next_snapshot = buffer.text_snapshot();
 7595        for language_server in language_servers {
 7596            let language_server = language_server.clone();
 7597
 7598            let buffer_snapshots = self
 7599                .as_local_mut()
 7600                .unwrap()
 7601                .buffer_snapshots
 7602                .get_mut(&buffer.remote_id())
 7603                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7604            let previous_snapshot = buffer_snapshots.last()?;
 7605
 7606            let build_incremental_change = || {
 7607                buffer
 7608                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7609                        previous_snapshot.snapshot.version(),
 7610                    )
 7611                    .map(|edit| {
 7612                        let edit_start = edit.new.start.0;
 7613                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7614                        let new_text = next_snapshot
 7615                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7616                            .collect();
 7617                        lsp::TextDocumentContentChangeEvent {
 7618                            range: Some(lsp::Range::new(
 7619                                point_to_lsp(edit_start),
 7620                                point_to_lsp(edit_end),
 7621                            )),
 7622                            range_length: None,
 7623                            text: new_text,
 7624                        }
 7625                    })
 7626                    .collect()
 7627            };
 7628
 7629            let document_sync_kind = language_server
 7630                .capabilities()
 7631                .text_document_sync
 7632                .as_ref()
 7633                .and_then(|sync| match sync {
 7634                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7635                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7636                });
 7637
 7638            let content_changes: Vec<_> = match document_sync_kind {
 7639                Some(lsp::TextDocumentSyncKind::FULL) => {
 7640                    vec![lsp::TextDocumentContentChangeEvent {
 7641                        range: None,
 7642                        range_length: None,
 7643                        text: next_snapshot.text(),
 7644                    }]
 7645                }
 7646                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7647                _ => {
 7648                    #[cfg(any(test, feature = "test-support"))]
 7649                    {
 7650                        build_incremental_change()
 7651                    }
 7652
 7653                    #[cfg(not(any(test, feature = "test-support")))]
 7654                    {
 7655                        continue;
 7656                    }
 7657                }
 7658            };
 7659
 7660            let next_version = previous_snapshot.version + 1;
 7661            buffer_snapshots.push(LspBufferSnapshot {
 7662                version: next_version,
 7663                snapshot: next_snapshot.clone(),
 7664            });
 7665
 7666            language_server
 7667                .notify::<lsp::notification::DidChangeTextDocument>(
 7668                    lsp::DidChangeTextDocumentParams {
 7669                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7670                            uri.clone(),
 7671                            next_version,
 7672                        ),
 7673                        content_changes,
 7674                    },
 7675                )
 7676                .ok();
 7677            self.pull_workspace_diagnostics(language_server.server_id());
 7678        }
 7679
 7680        None
 7681    }
 7682
 7683    pub fn on_buffer_saved(
 7684        &mut self,
 7685        buffer: Entity<Buffer>,
 7686        cx: &mut Context<Self>,
 7687    ) -> Option<()> {
 7688        let file = File::from_dyn(buffer.read(cx).file())?;
 7689        let worktree_id = file.worktree_id(cx);
 7690        let abs_path = file.as_local()?.abs_path(cx);
 7691        let text_document = lsp::TextDocumentIdentifier {
 7692            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7693        };
 7694        let local = self.as_local()?;
 7695
 7696        for server in local.language_servers_for_worktree(worktree_id) {
 7697            if let Some(include_text) = include_text(server.as_ref()) {
 7698                let text = if include_text {
 7699                    Some(buffer.read(cx).text())
 7700                } else {
 7701                    None
 7702                };
 7703                server
 7704                    .notify::<lsp::notification::DidSaveTextDocument>(
 7705                        lsp::DidSaveTextDocumentParams {
 7706                            text_document: text_document.clone(),
 7707                            text,
 7708                        },
 7709                    )
 7710                    .ok();
 7711            }
 7712        }
 7713
 7714        let language_servers = buffer.update(cx, |buffer, cx| {
 7715            local.language_server_ids_for_buffer(buffer, cx)
 7716        });
 7717        for language_server_id in language_servers {
 7718            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7719        }
 7720
 7721        None
 7722    }
 7723
 7724    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7725        maybe!(async move {
 7726            let mut refreshed_servers = HashSet::default();
 7727            let servers = lsp_store
 7728                .update(cx, |lsp_store, cx| {
 7729                    let local = lsp_store.as_local()?;
 7730
 7731                    let servers = local
 7732                        .language_server_ids
 7733                        .iter()
 7734                        .filter_map(|(seed, state)| {
 7735                            let worktree = lsp_store
 7736                                .worktree_store
 7737                                .read(cx)
 7738                                .worktree_for_id(seed.worktree_id, cx);
 7739                            let delegate: Arc<dyn LspAdapterDelegate> =
 7740                                worktree.map(|worktree| {
 7741                                    LocalLspAdapterDelegate::new(
 7742                                        local.languages.clone(),
 7743                                        &local.environment,
 7744                                        cx.weak_entity(),
 7745                                        &worktree,
 7746                                        local.http_client.clone(),
 7747                                        local.fs.clone(),
 7748                                        cx,
 7749                                    )
 7750                                })?;
 7751                            let server_id = state.id;
 7752
 7753                            let states = local.language_servers.get(&server_id)?;
 7754
 7755                            match states {
 7756                                LanguageServerState::Starting { .. } => None,
 7757                                LanguageServerState::Running {
 7758                                    adapter, server, ..
 7759                                } => {
 7760                                    let adapter = adapter.clone();
 7761                                    let server = server.clone();
 7762                                    refreshed_servers.insert(server.name());
 7763                                    let toolchain = seed.toolchain.clone();
 7764                                    Some(cx.spawn(async move |_, cx| {
 7765                                        let settings =
 7766                                            LocalLspStore::workspace_configuration_for_adapter(
 7767                                                adapter.adapter.clone(),
 7768                                                &delegate,
 7769                                                toolchain,
 7770                                                cx,
 7771                                            )
 7772                                            .await
 7773                                            .ok()?;
 7774                                        server
 7775                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7776                                                lsp::DidChangeConfigurationParams { settings },
 7777                                            )
 7778                                            .ok()?;
 7779                                        Some(())
 7780                                    }))
 7781                                }
 7782                            }
 7783                        })
 7784                        .collect::<Vec<_>>();
 7785
 7786                    Some(servers)
 7787                })
 7788                .ok()
 7789                .flatten()?;
 7790
 7791            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7792            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7793            // to stop and unregister its language server wrapper.
 7794            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7795            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7796            let _: Vec<Option<()>> = join_all(servers).await;
 7797
 7798            Some(())
 7799        })
 7800        .await;
 7801    }
 7802
 7803    fn maintain_workspace_config(
 7804        external_refresh_requests: watch::Receiver<()>,
 7805        cx: &mut Context<Self>,
 7806    ) -> Task<Result<()>> {
 7807        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7808        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7809
 7810        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7811            *settings_changed_tx.borrow_mut() = ();
 7812        });
 7813
 7814        let mut joint_future =
 7815            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7816        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7817        // - 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).
 7818        // - 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.
 7819        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7820        // - 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,
 7821        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7822        cx.spawn(async move |this, cx| {
 7823            while let Some(()) = joint_future.next().await {
 7824                this.update(cx, |this, cx| {
 7825                    this.refresh_server_tree(cx);
 7826                })
 7827                .ok();
 7828
 7829                Self::refresh_workspace_configurations(&this, cx).await;
 7830            }
 7831
 7832            drop(settings_observation);
 7833            anyhow::Ok(())
 7834        })
 7835    }
 7836
 7837    pub fn language_servers_for_local_buffer<'a>(
 7838        &'a self,
 7839        buffer: &Buffer,
 7840        cx: &mut App,
 7841    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7842        let local = self.as_local();
 7843        let language_server_ids = local
 7844            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7845            .unwrap_or_default();
 7846
 7847        language_server_ids
 7848            .into_iter()
 7849            .filter_map(
 7850                move |server_id| match local?.language_servers.get(&server_id)? {
 7851                    LanguageServerState::Running {
 7852                        adapter, server, ..
 7853                    } => Some((adapter, server)),
 7854                    _ => None,
 7855                },
 7856            )
 7857    }
 7858
 7859    pub fn language_server_for_local_buffer<'a>(
 7860        &'a self,
 7861        buffer: &'a Buffer,
 7862        server_id: LanguageServerId,
 7863        cx: &'a mut App,
 7864    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7865        self.as_local()?
 7866            .language_servers_for_buffer(buffer, cx)
 7867            .find(|(_, s)| s.server_id() == server_id)
 7868    }
 7869
 7870    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7871        self.diagnostic_summaries.remove(&id_to_remove);
 7872        if let Some(local) = self.as_local_mut() {
 7873            let to_remove = local.remove_worktree(id_to_remove, cx);
 7874            for server in to_remove {
 7875                self.language_server_statuses.remove(&server);
 7876            }
 7877        }
 7878    }
 7879
 7880    pub fn shared(
 7881        &mut self,
 7882        project_id: u64,
 7883        downstream_client: AnyProtoClient,
 7884        _: &mut Context<Self>,
 7885    ) {
 7886        self.downstream_client = Some((downstream_client.clone(), project_id));
 7887
 7888        for (server_id, status) in &self.language_server_statuses {
 7889            if let Some(server) = self.language_server_for_id(*server_id) {
 7890                downstream_client
 7891                    .send(proto::StartLanguageServer {
 7892                        project_id,
 7893                        server: Some(proto::LanguageServer {
 7894                            id: server_id.to_proto(),
 7895                            name: status.name.to_string(),
 7896                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7897                        }),
 7898                        capabilities: serde_json::to_string(&server.capabilities())
 7899                            .expect("serializing server LSP capabilities"),
 7900                    })
 7901                    .log_err();
 7902            }
 7903        }
 7904    }
 7905
 7906    pub fn disconnected_from_host(&mut self) {
 7907        self.downstream_client.take();
 7908    }
 7909
 7910    pub fn disconnected_from_ssh_remote(&mut self) {
 7911        if let LspStoreMode::Remote(RemoteLspStore {
 7912            upstream_client, ..
 7913        }) = &mut self.mode
 7914        {
 7915            upstream_client.take();
 7916        }
 7917    }
 7918
 7919    pub(crate) fn set_language_server_statuses_from_proto(
 7920        &mut self,
 7921        project: WeakEntity<Project>,
 7922        language_servers: Vec<proto::LanguageServer>,
 7923        server_capabilities: Vec<String>,
 7924        cx: &mut Context<Self>,
 7925    ) {
 7926        let lsp_logs = cx
 7927            .try_global::<GlobalLogStore>()
 7928            .map(|lsp_store| lsp_store.0.clone());
 7929
 7930        self.language_server_statuses = language_servers
 7931            .into_iter()
 7932            .zip(server_capabilities)
 7933            .map(|(server, server_capabilities)| {
 7934                let server_id = LanguageServerId(server.id as usize);
 7935                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7936                    self.lsp_server_capabilities
 7937                        .insert(server_id, server_capabilities);
 7938                }
 7939
 7940                let name = LanguageServerName::from_proto(server.name);
 7941                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7942
 7943                if let Some(lsp_logs) = &lsp_logs {
 7944                    lsp_logs.update(cx, |lsp_logs, cx| {
 7945                        lsp_logs.add_language_server(
 7946                            // Only remote clients get their language servers set from proto
 7947                            LanguageServerKind::Remote {
 7948                                project: project.clone(),
 7949                            },
 7950                            server_id,
 7951                            Some(name.clone()),
 7952                            worktree,
 7953                            None,
 7954                            cx,
 7955                        );
 7956                    });
 7957                }
 7958
 7959                (
 7960                    server_id,
 7961                    LanguageServerStatus {
 7962                        name,
 7963                        pending_work: Default::default(),
 7964                        has_pending_diagnostic_updates: false,
 7965                        progress_tokens: Default::default(),
 7966                        worktree,
 7967                    },
 7968                )
 7969            })
 7970            .collect();
 7971    }
 7972
 7973    #[cfg(test)]
 7974    pub fn update_diagnostic_entries(
 7975        &mut self,
 7976        server_id: LanguageServerId,
 7977        abs_path: PathBuf,
 7978        result_id: Option<String>,
 7979        version: Option<i32>,
 7980        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7981        cx: &mut Context<Self>,
 7982    ) -> anyhow::Result<()> {
 7983        self.merge_diagnostic_entries(
 7984            vec![DocumentDiagnosticsUpdate {
 7985                diagnostics: DocumentDiagnostics {
 7986                    diagnostics,
 7987                    document_abs_path: abs_path,
 7988                    version,
 7989                },
 7990                result_id,
 7991                server_id,
 7992                disk_based_sources: Cow::Borrowed(&[]),
 7993            }],
 7994            |_, _, _| false,
 7995            cx,
 7996        )?;
 7997        Ok(())
 7998    }
 7999
 8000    pub fn merge_diagnostic_entries<'a>(
 8001        &mut self,
 8002        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8003        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 8004        cx: &mut Context<Self>,
 8005    ) -> anyhow::Result<()> {
 8006        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8007        let mut updated_diagnostics_paths = HashMap::default();
 8008        for mut update in diagnostic_updates {
 8009            let abs_path = &update.diagnostics.document_abs_path;
 8010            let server_id = update.server_id;
 8011            let Some((worktree, relative_path)) =
 8012                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8013            else {
 8014                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8015                return Ok(());
 8016            };
 8017
 8018            let worktree_id = worktree.read(cx).id();
 8019            let project_path = ProjectPath {
 8020                worktree_id,
 8021                path: relative_path,
 8022            };
 8023
 8024            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8025                let snapshot = buffer_handle.read(cx).snapshot();
 8026                let buffer = buffer_handle.read(cx);
 8027                let reused_diagnostics = buffer
 8028                    .buffer_diagnostics(Some(server_id))
 8029                    .iter()
 8030                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8031                    .map(|v| {
 8032                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8033                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8034                        DiagnosticEntry {
 8035                            range: start..end,
 8036                            diagnostic: v.diagnostic.clone(),
 8037                        }
 8038                    })
 8039                    .collect::<Vec<_>>();
 8040
 8041                self.as_local_mut()
 8042                    .context("cannot merge diagnostics on a remote LspStore")?
 8043                    .update_buffer_diagnostics(
 8044                        &buffer_handle,
 8045                        server_id,
 8046                        update.result_id,
 8047                        update.diagnostics.version,
 8048                        update.diagnostics.diagnostics.clone(),
 8049                        reused_diagnostics.clone(),
 8050                        cx,
 8051                    )?;
 8052
 8053                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8054            }
 8055
 8056            let updated = worktree.update(cx, |worktree, cx| {
 8057                self.update_worktree_diagnostics(
 8058                    worktree.id(),
 8059                    server_id,
 8060                    project_path.path.clone(),
 8061                    update.diagnostics.diagnostics,
 8062                    cx,
 8063                )
 8064            })?;
 8065            match updated {
 8066                ControlFlow::Continue(new_summary) => {
 8067                    if let Some((project_id, new_summary)) = new_summary {
 8068                        match &mut diagnostics_summary {
 8069                            Some(diagnostics_summary) => {
 8070                                diagnostics_summary
 8071                                    .more_summaries
 8072                                    .push(proto::DiagnosticSummary {
 8073                                        path: project_path.path.as_ref().to_proto(),
 8074                                        language_server_id: server_id.0 as u64,
 8075                                        error_count: new_summary.error_count,
 8076                                        warning_count: new_summary.warning_count,
 8077                                    })
 8078                            }
 8079                            None => {
 8080                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8081                                    project_id,
 8082                                    worktree_id: worktree_id.to_proto(),
 8083                                    summary: Some(proto::DiagnosticSummary {
 8084                                        path: project_path.path.as_ref().to_proto(),
 8085                                        language_server_id: server_id.0 as u64,
 8086                                        error_count: new_summary.error_count,
 8087                                        warning_count: new_summary.warning_count,
 8088                                    }),
 8089                                    more_summaries: Vec::new(),
 8090                                })
 8091                            }
 8092                        }
 8093                    }
 8094                    updated_diagnostics_paths
 8095                        .entry(server_id)
 8096                        .or_insert_with(Vec::new)
 8097                        .push(project_path);
 8098                }
 8099                ControlFlow::Break(()) => {}
 8100            }
 8101        }
 8102
 8103        if let Some((diagnostics_summary, (downstream_client, _))) =
 8104            diagnostics_summary.zip(self.downstream_client.as_ref())
 8105        {
 8106            downstream_client.send(diagnostics_summary).log_err();
 8107        }
 8108        for (server_id, paths) in updated_diagnostics_paths {
 8109            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8110        }
 8111        Ok(())
 8112    }
 8113
 8114    fn update_worktree_diagnostics(
 8115        &mut self,
 8116        worktree_id: WorktreeId,
 8117        server_id: LanguageServerId,
 8118        path_in_worktree: Arc<RelPath>,
 8119        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8120        _: &mut Context<Worktree>,
 8121    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8122        let local = match &mut self.mode {
 8123            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8124            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8125        };
 8126
 8127        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8128        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8129        let summaries_by_server_id = summaries_for_tree
 8130            .entry(path_in_worktree.clone())
 8131            .or_default();
 8132
 8133        let old_summary = summaries_by_server_id
 8134            .remove(&server_id)
 8135            .unwrap_or_default();
 8136
 8137        let new_summary = DiagnosticSummary::new(&diagnostics);
 8138        if new_summary.is_empty() {
 8139            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8140            {
 8141                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8142                    diagnostics_by_server_id.remove(ix);
 8143                }
 8144                if diagnostics_by_server_id.is_empty() {
 8145                    diagnostics_for_tree.remove(&path_in_worktree);
 8146                }
 8147            }
 8148        } else {
 8149            summaries_by_server_id.insert(server_id, new_summary);
 8150            let diagnostics_by_server_id = diagnostics_for_tree
 8151                .entry(path_in_worktree.clone())
 8152                .or_default();
 8153            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8154                Ok(ix) => {
 8155                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8156                }
 8157                Err(ix) => {
 8158                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8159                }
 8160            }
 8161        }
 8162
 8163        if !old_summary.is_empty() || !new_summary.is_empty() {
 8164            if let Some((_, project_id)) = &self.downstream_client {
 8165                Ok(ControlFlow::Continue(Some((
 8166                    *project_id,
 8167                    proto::DiagnosticSummary {
 8168                        path: path_in_worktree.to_proto(),
 8169                        language_server_id: server_id.0 as u64,
 8170                        error_count: new_summary.error_count as u32,
 8171                        warning_count: new_summary.warning_count as u32,
 8172                    },
 8173                ))))
 8174            } else {
 8175                Ok(ControlFlow::Continue(None))
 8176            }
 8177        } else {
 8178            Ok(ControlFlow::Break(()))
 8179        }
 8180    }
 8181
 8182    pub fn open_buffer_for_symbol(
 8183        &mut self,
 8184        symbol: &Symbol,
 8185        cx: &mut Context<Self>,
 8186    ) -> Task<Result<Entity<Buffer>>> {
 8187        if let Some((client, project_id)) = self.upstream_client() {
 8188            let request = client.request(proto::OpenBufferForSymbol {
 8189                project_id,
 8190                symbol: Some(Self::serialize_symbol(symbol)),
 8191            });
 8192            cx.spawn(async move |this, cx| {
 8193                let response = request.await?;
 8194                let buffer_id = BufferId::new(response.buffer_id)?;
 8195                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8196                    .await
 8197            })
 8198        } else if let Some(local) = self.as_local() {
 8199            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8200                seed.worktree_id == symbol.source_worktree_id
 8201                    && state.id == symbol.source_language_server_id
 8202                    && symbol.language_server_name == seed.name
 8203            });
 8204            if !is_valid {
 8205                return Task::ready(Err(anyhow!(
 8206                    "language server for worktree and language not found"
 8207                )));
 8208            };
 8209
 8210            let symbol_abs_path = match &symbol.path {
 8211                SymbolLocation::InProject(project_path) => self
 8212                    .worktree_store
 8213                    .read(cx)
 8214                    .absolutize(&project_path, cx)
 8215                    .context("no such worktree"),
 8216                SymbolLocation::OutsideProject {
 8217                    abs_path,
 8218                    signature: _,
 8219                } => Ok(abs_path.to_path_buf()),
 8220            };
 8221            let symbol_abs_path = match symbol_abs_path {
 8222                Ok(abs_path) => abs_path,
 8223                Err(err) => return Task::ready(Err(err)),
 8224            };
 8225            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8226                uri
 8227            } else {
 8228                return Task::ready(Err(anyhow!("invalid symbol path")));
 8229            };
 8230
 8231            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8232        } else {
 8233            Task::ready(Err(anyhow!("no upstream client or local store")))
 8234        }
 8235    }
 8236
 8237    pub(crate) fn open_local_buffer_via_lsp(
 8238        &mut self,
 8239        abs_path: lsp::Uri,
 8240        language_server_id: LanguageServerId,
 8241        cx: &mut Context<Self>,
 8242    ) -> Task<Result<Entity<Buffer>>> {
 8243        cx.spawn(async move |lsp_store, cx| {
 8244            // Escape percent-encoded string.
 8245            let current_scheme = abs_path.scheme().to_owned();
 8246            // Uri is immutable, so we can't modify the scheme
 8247
 8248            let abs_path = abs_path
 8249                .to_file_path()
 8250                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8251            let p = abs_path.clone();
 8252            let yarn_worktree = lsp_store
 8253                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8254                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8255                        cx.spawn(async move |this, cx| {
 8256                            let t = this
 8257                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8258                                .ok()?;
 8259                            t.await
 8260                        })
 8261                    }),
 8262                    None => Task::ready(None),
 8263                })?
 8264                .await;
 8265            let (worktree_root_target, known_relative_path) =
 8266                if let Some((zip_root, relative_path)) = yarn_worktree {
 8267                    (zip_root, Some(relative_path))
 8268                } else {
 8269                    (Arc::<Path>::from(abs_path.as_path()), None)
 8270                };
 8271            let (worktree, relative_path) = if let Some(result) =
 8272                lsp_store.update(cx, |lsp_store, cx| {
 8273                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8274                        worktree_store.find_worktree(&worktree_root_target, cx)
 8275                    })
 8276                })? {
 8277                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8278                (result.0, relative_path)
 8279            } else {
 8280                let worktree = lsp_store
 8281                    .update(cx, |lsp_store, cx| {
 8282                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8283                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8284                        })
 8285                    })?
 8286                    .await?;
 8287                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8288                    lsp_store
 8289                        .update(cx, |lsp_store, cx| {
 8290                            if let Some(local) = lsp_store.as_local_mut() {
 8291                                local.register_language_server_for_invisible_worktree(
 8292                                    &worktree,
 8293                                    language_server_id,
 8294                                    cx,
 8295                                )
 8296                            }
 8297                        })
 8298                        .ok();
 8299                }
 8300                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8301                let relative_path = if let Some(known_path) = known_relative_path {
 8302                    known_path
 8303                } else {
 8304                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8305                        .into_arc()
 8306                };
 8307                (worktree, relative_path)
 8308            };
 8309            let project_path = ProjectPath {
 8310                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8311                path: relative_path,
 8312            };
 8313            lsp_store
 8314                .update(cx, |lsp_store, cx| {
 8315                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8316                        buffer_store.open_buffer(project_path, cx)
 8317                    })
 8318                })?
 8319                .await
 8320        })
 8321    }
 8322
 8323    fn request_multiple_lsp_locally<P, R>(
 8324        &mut self,
 8325        buffer: &Entity<Buffer>,
 8326        position: Option<P>,
 8327        request: R,
 8328        cx: &mut Context<Self>,
 8329    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8330    where
 8331        P: ToOffset,
 8332        R: LspCommand + Clone,
 8333        <R::LspRequest as lsp::request::Request>::Result: Send,
 8334        <R::LspRequest as lsp::request::Request>::Params: Send,
 8335    {
 8336        let Some(local) = self.as_local() else {
 8337            return Task::ready(Vec::new());
 8338        };
 8339
 8340        let snapshot = buffer.read(cx).snapshot();
 8341        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8342
 8343        let server_ids = buffer.update(cx, |buffer, cx| {
 8344            local
 8345                .language_servers_for_buffer(buffer, cx)
 8346                .filter(|(adapter, _)| {
 8347                    scope
 8348                        .as_ref()
 8349                        .map(|scope| scope.language_allowed(&adapter.name))
 8350                        .unwrap_or(true)
 8351                })
 8352                .map(|(_, server)| server.server_id())
 8353                .filter(|server_id| {
 8354                    self.as_local().is_none_or(|local| {
 8355                        local
 8356                            .buffers_opened_in_servers
 8357                            .get(&snapshot.remote_id())
 8358                            .is_some_and(|servers| servers.contains(server_id))
 8359                    })
 8360                })
 8361                .collect::<Vec<_>>()
 8362        });
 8363
 8364        let mut response_results = server_ids
 8365            .into_iter()
 8366            .map(|server_id| {
 8367                let task = self.request_lsp(
 8368                    buffer.clone(),
 8369                    LanguageServerToQuery::Other(server_id),
 8370                    request.clone(),
 8371                    cx,
 8372                );
 8373                async move { (server_id, task.await) }
 8374            })
 8375            .collect::<FuturesUnordered<_>>();
 8376
 8377        cx.background_spawn(async move {
 8378            let mut responses = Vec::with_capacity(response_results.len());
 8379            while let Some((server_id, response_result)) = response_results.next().await {
 8380                match response_result {
 8381                    Ok(response) => responses.push((server_id, response)),
 8382                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8383                }
 8384            }
 8385            responses
 8386        })
 8387    }
 8388
 8389    async fn handle_lsp_command<T: LspCommand>(
 8390        this: Entity<Self>,
 8391        envelope: TypedEnvelope<T::ProtoRequest>,
 8392        mut cx: AsyncApp,
 8393    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8394    where
 8395        <T::LspRequest as lsp::request::Request>::Params: Send,
 8396        <T::LspRequest as lsp::request::Request>::Result: Send,
 8397    {
 8398        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8399        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8400        let buffer_handle = this.update(&mut cx, |this, cx| {
 8401            this.buffer_store.read(cx).get_existing(buffer_id)
 8402        })??;
 8403        let request = T::from_proto(
 8404            envelope.payload,
 8405            this.clone(),
 8406            buffer_handle.clone(),
 8407            cx.clone(),
 8408        )
 8409        .await?;
 8410        let response = this
 8411            .update(&mut cx, |this, cx| {
 8412                this.request_lsp(
 8413                    buffer_handle.clone(),
 8414                    LanguageServerToQuery::FirstCapable,
 8415                    request,
 8416                    cx,
 8417                )
 8418            })?
 8419            .await?;
 8420        this.update(&mut cx, |this, cx| {
 8421            Ok(T::response_to_proto(
 8422                response,
 8423                this,
 8424                sender_id,
 8425                &buffer_handle.read(cx).version(),
 8426                cx,
 8427            ))
 8428        })?
 8429    }
 8430
 8431    async fn handle_lsp_query(
 8432        lsp_store: Entity<Self>,
 8433        envelope: TypedEnvelope<proto::LspQuery>,
 8434        mut cx: AsyncApp,
 8435    ) -> Result<proto::Ack> {
 8436        use proto::lsp_query::Request;
 8437        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8438        let lsp_query = envelope.payload;
 8439        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8440        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8441        match lsp_query.request.context("invalid LSP query request")? {
 8442            Request::GetReferences(get_references) => {
 8443                let position = get_references.position.clone().and_then(deserialize_anchor);
 8444                Self::query_lsp_locally::<GetReferences>(
 8445                    lsp_store,
 8446                    server_id,
 8447                    sender_id,
 8448                    lsp_request_id,
 8449                    get_references,
 8450                    position,
 8451                    &mut cx,
 8452                )
 8453                .await?;
 8454            }
 8455            Request::GetDocumentColor(get_document_color) => {
 8456                Self::query_lsp_locally::<GetDocumentColor>(
 8457                    lsp_store,
 8458                    server_id,
 8459                    sender_id,
 8460                    lsp_request_id,
 8461                    get_document_color,
 8462                    None,
 8463                    &mut cx,
 8464                )
 8465                .await?;
 8466            }
 8467            Request::GetHover(get_hover) => {
 8468                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8469                Self::query_lsp_locally::<GetHover>(
 8470                    lsp_store,
 8471                    server_id,
 8472                    sender_id,
 8473                    lsp_request_id,
 8474                    get_hover,
 8475                    position,
 8476                    &mut cx,
 8477                )
 8478                .await?;
 8479            }
 8480            Request::GetCodeActions(get_code_actions) => {
 8481                Self::query_lsp_locally::<GetCodeActions>(
 8482                    lsp_store,
 8483                    server_id,
 8484                    sender_id,
 8485                    lsp_request_id,
 8486                    get_code_actions,
 8487                    None,
 8488                    &mut cx,
 8489                )
 8490                .await?;
 8491            }
 8492            Request::GetSignatureHelp(get_signature_help) => {
 8493                let position = get_signature_help
 8494                    .position
 8495                    .clone()
 8496                    .and_then(deserialize_anchor);
 8497                Self::query_lsp_locally::<GetSignatureHelp>(
 8498                    lsp_store,
 8499                    server_id,
 8500                    sender_id,
 8501                    lsp_request_id,
 8502                    get_signature_help,
 8503                    position,
 8504                    &mut cx,
 8505                )
 8506                .await?;
 8507            }
 8508            Request::GetCodeLens(get_code_lens) => {
 8509                Self::query_lsp_locally::<GetCodeLens>(
 8510                    lsp_store,
 8511                    server_id,
 8512                    sender_id,
 8513                    lsp_request_id,
 8514                    get_code_lens,
 8515                    None,
 8516                    &mut cx,
 8517                )
 8518                .await?;
 8519            }
 8520            Request::GetDefinition(get_definition) => {
 8521                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8522                Self::query_lsp_locally::<GetDefinitions>(
 8523                    lsp_store,
 8524                    server_id,
 8525                    sender_id,
 8526                    lsp_request_id,
 8527                    get_definition,
 8528                    position,
 8529                    &mut cx,
 8530                )
 8531                .await?;
 8532            }
 8533            Request::GetDeclaration(get_declaration) => {
 8534                let position = get_declaration
 8535                    .position
 8536                    .clone()
 8537                    .and_then(deserialize_anchor);
 8538                Self::query_lsp_locally::<GetDeclarations>(
 8539                    lsp_store,
 8540                    server_id,
 8541                    sender_id,
 8542                    lsp_request_id,
 8543                    get_declaration,
 8544                    position,
 8545                    &mut cx,
 8546                )
 8547                .await?;
 8548            }
 8549            Request::GetTypeDefinition(get_type_definition) => {
 8550                let position = get_type_definition
 8551                    .position
 8552                    .clone()
 8553                    .and_then(deserialize_anchor);
 8554                Self::query_lsp_locally::<GetTypeDefinitions>(
 8555                    lsp_store,
 8556                    server_id,
 8557                    sender_id,
 8558                    lsp_request_id,
 8559                    get_type_definition,
 8560                    position,
 8561                    &mut cx,
 8562                )
 8563                .await?;
 8564            }
 8565            Request::GetImplementation(get_implementation) => {
 8566                let position = get_implementation
 8567                    .position
 8568                    .clone()
 8569                    .and_then(deserialize_anchor);
 8570                Self::query_lsp_locally::<GetImplementations>(
 8571                    lsp_store,
 8572                    server_id,
 8573                    sender_id,
 8574                    lsp_request_id,
 8575                    get_implementation,
 8576                    position,
 8577                    &mut cx,
 8578                )
 8579                .await?;
 8580            }
 8581            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8582                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8583                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8584                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8585                    this.buffer_store.read(cx).get_existing(buffer_id)
 8586                })??;
 8587                buffer
 8588                    .update(&mut cx, |buffer, _| {
 8589                        buffer.wait_for_version(version.clone())
 8590                    })?
 8591                    .await?;
 8592                lsp_store.update(&mut cx, |lsp_store, cx| {
 8593                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8594                    let key = LspKey {
 8595                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8596                        server_queried: server_id,
 8597                    };
 8598                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8599                    ) {
 8600                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8601                            lsp_requests.clear();
 8602                        };
 8603                    }
 8604
 8605                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8606                    existing_queries.insert(
 8607                        lsp_request_id,
 8608                        cx.spawn(async move |lsp_store, cx| {
 8609                            let diagnostics_pull = lsp_store
 8610                                .update(cx, |lsp_store, cx| {
 8611                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8612                                })
 8613                                .ok();
 8614                            if let Some(diagnostics_pull) = diagnostics_pull {
 8615                                match diagnostics_pull.await {
 8616                                    Ok(()) => {}
 8617                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8618                                };
 8619                            }
 8620                        }),
 8621                    );
 8622                })?;
 8623            }
 8624            Request::InlayHints(inlay_hints) => {
 8625                let query_start = inlay_hints
 8626                    .start
 8627                    .clone()
 8628                    .and_then(deserialize_anchor)
 8629                    .context("invalid inlay hints range start")?;
 8630                let query_end = inlay_hints
 8631                    .end
 8632                    .clone()
 8633                    .and_then(deserialize_anchor)
 8634                    .context("invalid inlay hints range end")?;
 8635                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8636                    &lsp_store,
 8637                    server_id,
 8638                    lsp_request_id,
 8639                    &inlay_hints,
 8640                    query_start..query_end,
 8641                    &mut cx,
 8642                )
 8643                .await
 8644                .context("preparing inlay hints request")?;
 8645                Self::query_lsp_locally::<InlayHints>(
 8646                    lsp_store,
 8647                    server_id,
 8648                    sender_id,
 8649                    lsp_request_id,
 8650                    inlay_hints,
 8651                    None,
 8652                    &mut cx,
 8653                )
 8654                .await
 8655                .context("querying for inlay hints")?
 8656            }
 8657        }
 8658        Ok(proto::Ack {})
 8659    }
 8660
 8661    async fn handle_lsp_query_response(
 8662        lsp_store: Entity<Self>,
 8663        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8664        cx: AsyncApp,
 8665    ) -> Result<()> {
 8666        lsp_store.read_with(&cx, |lsp_store, _| {
 8667            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8668                upstream_client.handle_lsp_response(envelope.clone());
 8669            }
 8670        })?;
 8671        Ok(())
 8672    }
 8673
 8674    async fn handle_apply_code_action(
 8675        this: Entity<Self>,
 8676        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8677        mut cx: AsyncApp,
 8678    ) -> Result<proto::ApplyCodeActionResponse> {
 8679        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8680        let action =
 8681            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8682        let apply_code_action = this.update(&mut cx, |this, cx| {
 8683            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8684            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8685            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8686        })??;
 8687
 8688        let project_transaction = apply_code_action.await?;
 8689        let project_transaction = this.update(&mut cx, |this, cx| {
 8690            this.buffer_store.update(cx, |buffer_store, cx| {
 8691                buffer_store.serialize_project_transaction_for_peer(
 8692                    project_transaction,
 8693                    sender_id,
 8694                    cx,
 8695                )
 8696            })
 8697        })?;
 8698        Ok(proto::ApplyCodeActionResponse {
 8699            transaction: Some(project_transaction),
 8700        })
 8701    }
 8702
 8703    async fn handle_register_buffer_with_language_servers(
 8704        this: Entity<Self>,
 8705        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8706        mut cx: AsyncApp,
 8707    ) -> Result<proto::Ack> {
 8708        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8709        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8710        this.update(&mut cx, |this, cx| {
 8711            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8712                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8713                    project_id: upstream_project_id,
 8714                    buffer_id: buffer_id.to_proto(),
 8715                    only_servers: envelope.payload.only_servers,
 8716                });
 8717            }
 8718
 8719            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8720                anyhow::bail!("buffer is not open");
 8721            };
 8722
 8723            let handle = this.register_buffer_with_language_servers(
 8724                &buffer,
 8725                envelope
 8726                    .payload
 8727                    .only_servers
 8728                    .into_iter()
 8729                    .filter_map(|selector| {
 8730                        Some(match selector.selector? {
 8731                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8732                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8733                            }
 8734                            proto::language_server_selector::Selector::Name(name) => {
 8735                                LanguageServerSelector::Name(LanguageServerName(
 8736                                    SharedString::from(name),
 8737                                ))
 8738                            }
 8739                        })
 8740                    })
 8741                    .collect(),
 8742                false,
 8743                cx,
 8744            );
 8745            this.buffer_store().update(cx, |buffer_store, _| {
 8746                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8747            });
 8748
 8749            Ok(())
 8750        })??;
 8751        Ok(proto::Ack {})
 8752    }
 8753
 8754    async fn handle_rename_project_entry(
 8755        this: Entity<Self>,
 8756        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8757        mut cx: AsyncApp,
 8758    ) -> Result<proto::ProjectEntryResponse> {
 8759        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8760        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8761        let new_path =
 8762            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8763
 8764        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8765            .update(&mut cx, |this, cx| {
 8766                let (worktree, entry) = this
 8767                    .worktree_store
 8768                    .read(cx)
 8769                    .worktree_and_entry_for_id(entry_id, cx)?;
 8770                let new_worktree = this
 8771                    .worktree_store
 8772                    .read(cx)
 8773                    .worktree_for_id(new_worktree_id, cx)?;
 8774                Some((
 8775                    this.worktree_store.clone(),
 8776                    worktree,
 8777                    new_worktree,
 8778                    entry.clone(),
 8779                ))
 8780            })?
 8781            .context("worktree not found")?;
 8782        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8783            (worktree.absolutize(&old_entry.path), worktree.id())
 8784        })?;
 8785        let new_abs_path =
 8786            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8787
 8788        let _transaction = Self::will_rename_entry(
 8789            this.downgrade(),
 8790            old_worktree_id,
 8791            &old_abs_path,
 8792            &new_abs_path,
 8793            old_entry.is_dir(),
 8794            cx.clone(),
 8795        )
 8796        .await;
 8797        let response = WorktreeStore::handle_rename_project_entry(
 8798            worktree_store,
 8799            envelope.payload,
 8800            cx.clone(),
 8801        )
 8802        .await;
 8803        this.read_with(&cx, |this, _| {
 8804            this.did_rename_entry(
 8805                old_worktree_id,
 8806                &old_abs_path,
 8807                &new_abs_path,
 8808                old_entry.is_dir(),
 8809            );
 8810        })
 8811        .ok();
 8812        response
 8813    }
 8814
 8815    async fn handle_update_diagnostic_summary(
 8816        this: Entity<Self>,
 8817        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8818        mut cx: AsyncApp,
 8819    ) -> Result<()> {
 8820        this.update(&mut cx, |lsp_store, cx| {
 8821            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8822            let mut updated_diagnostics_paths = HashMap::default();
 8823            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8824            for message_summary in envelope
 8825                .payload
 8826                .summary
 8827                .into_iter()
 8828                .chain(envelope.payload.more_summaries)
 8829            {
 8830                let project_path = ProjectPath {
 8831                    worktree_id,
 8832                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8833                };
 8834                let path = project_path.path.clone();
 8835                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8836                let summary = DiagnosticSummary {
 8837                    error_count: message_summary.error_count as usize,
 8838                    warning_count: message_summary.warning_count as usize,
 8839                };
 8840
 8841                if summary.is_empty() {
 8842                    if let Some(worktree_summaries) =
 8843                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8844                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8845                    {
 8846                        summaries.remove(&server_id);
 8847                        if summaries.is_empty() {
 8848                            worktree_summaries.remove(&path);
 8849                        }
 8850                    }
 8851                } else {
 8852                    lsp_store
 8853                        .diagnostic_summaries
 8854                        .entry(worktree_id)
 8855                        .or_default()
 8856                        .entry(path)
 8857                        .or_default()
 8858                        .insert(server_id, summary);
 8859                }
 8860
 8861                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8862                    match &mut diagnostics_summary {
 8863                        Some(diagnostics_summary) => {
 8864                            diagnostics_summary
 8865                                .more_summaries
 8866                                .push(proto::DiagnosticSummary {
 8867                                    path: project_path.path.as_ref().to_proto(),
 8868                                    language_server_id: server_id.0 as u64,
 8869                                    error_count: summary.error_count as u32,
 8870                                    warning_count: summary.warning_count as u32,
 8871                                })
 8872                        }
 8873                        None => {
 8874                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8875                                project_id: *project_id,
 8876                                worktree_id: worktree_id.to_proto(),
 8877                                summary: Some(proto::DiagnosticSummary {
 8878                                    path: project_path.path.as_ref().to_proto(),
 8879                                    language_server_id: server_id.0 as u64,
 8880                                    error_count: summary.error_count as u32,
 8881                                    warning_count: summary.warning_count as u32,
 8882                                }),
 8883                                more_summaries: Vec::new(),
 8884                            })
 8885                        }
 8886                    }
 8887                }
 8888                updated_diagnostics_paths
 8889                    .entry(server_id)
 8890                    .or_insert_with(Vec::new)
 8891                    .push(project_path);
 8892            }
 8893
 8894            if let Some((diagnostics_summary, (downstream_client, _))) =
 8895                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8896            {
 8897                downstream_client.send(diagnostics_summary).log_err();
 8898            }
 8899            for (server_id, paths) in updated_diagnostics_paths {
 8900                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8901            }
 8902            Ok(())
 8903        })?
 8904    }
 8905
 8906    async fn handle_start_language_server(
 8907        lsp_store: Entity<Self>,
 8908        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8909        mut cx: AsyncApp,
 8910    ) -> Result<()> {
 8911        let server = envelope.payload.server.context("invalid server")?;
 8912        let server_capabilities =
 8913            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8914                .with_context(|| {
 8915                    format!(
 8916                        "incorrect server capabilities {}",
 8917                        envelope.payload.capabilities
 8918                    )
 8919                })?;
 8920        lsp_store.update(&mut cx, |lsp_store, cx| {
 8921            let server_id = LanguageServerId(server.id as usize);
 8922            let server_name = LanguageServerName::from_proto(server.name.clone());
 8923            lsp_store
 8924                .lsp_server_capabilities
 8925                .insert(server_id, server_capabilities);
 8926            lsp_store.language_server_statuses.insert(
 8927                server_id,
 8928                LanguageServerStatus {
 8929                    name: server_name.clone(),
 8930                    pending_work: Default::default(),
 8931                    has_pending_diagnostic_updates: false,
 8932                    progress_tokens: Default::default(),
 8933                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8934                },
 8935            );
 8936            cx.emit(LspStoreEvent::LanguageServerAdded(
 8937                server_id,
 8938                server_name,
 8939                server.worktree_id.map(WorktreeId::from_proto),
 8940            ));
 8941            cx.notify();
 8942        })?;
 8943        Ok(())
 8944    }
 8945
 8946    async fn handle_update_language_server(
 8947        lsp_store: Entity<Self>,
 8948        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8949        mut cx: AsyncApp,
 8950    ) -> Result<()> {
 8951        lsp_store.update(&mut cx, |lsp_store, cx| {
 8952            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8953
 8954            match envelope.payload.variant.context("invalid variant")? {
 8955                proto::update_language_server::Variant::WorkStart(payload) => {
 8956                    lsp_store.on_lsp_work_start(
 8957                        language_server_id,
 8958                        payload.token,
 8959                        LanguageServerProgress {
 8960                            title: payload.title,
 8961                            is_disk_based_diagnostics_progress: false,
 8962                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8963                            message: payload.message,
 8964                            percentage: payload.percentage.map(|p| p as usize),
 8965                            last_update_at: cx.background_executor().now(),
 8966                        },
 8967                        cx,
 8968                    );
 8969                }
 8970                proto::update_language_server::Variant::WorkProgress(payload) => {
 8971                    lsp_store.on_lsp_work_progress(
 8972                        language_server_id,
 8973                        payload.token,
 8974                        LanguageServerProgress {
 8975                            title: None,
 8976                            is_disk_based_diagnostics_progress: false,
 8977                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8978                            message: payload.message,
 8979                            percentage: payload.percentage.map(|p| p as usize),
 8980                            last_update_at: cx.background_executor().now(),
 8981                        },
 8982                        cx,
 8983                    );
 8984                }
 8985
 8986                proto::update_language_server::Variant::WorkEnd(payload) => {
 8987                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8988                }
 8989
 8990                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8991                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8992                }
 8993
 8994                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8995                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8996                }
 8997
 8998                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8999                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9000                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9001                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9002                        language_server_id,
 9003                        name: envelope
 9004                            .payload
 9005                            .server_name
 9006                            .map(SharedString::new)
 9007                            .map(LanguageServerName),
 9008                        message: non_lsp,
 9009                    });
 9010                }
 9011            }
 9012
 9013            Ok(())
 9014        })?
 9015    }
 9016
 9017    async fn handle_language_server_log(
 9018        this: Entity<Self>,
 9019        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9020        mut cx: AsyncApp,
 9021    ) -> Result<()> {
 9022        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9023        let log_type = envelope
 9024            .payload
 9025            .log_type
 9026            .map(LanguageServerLogType::from_proto)
 9027            .context("invalid language server log type")?;
 9028
 9029        let message = envelope.payload.message;
 9030
 9031        this.update(&mut cx, |_, cx| {
 9032            cx.emit(LspStoreEvent::LanguageServerLog(
 9033                language_server_id,
 9034                log_type,
 9035                message,
 9036            ));
 9037        })
 9038    }
 9039
 9040    async fn handle_lsp_ext_cancel_flycheck(
 9041        lsp_store: Entity<Self>,
 9042        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9043        cx: AsyncApp,
 9044    ) -> Result<proto::Ack> {
 9045        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9046        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9047            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9048                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9049            } else {
 9050                None
 9051            }
 9052        })?;
 9053        if let Some(task) = task {
 9054            task.context("handling lsp ext cancel flycheck")?;
 9055        }
 9056
 9057        Ok(proto::Ack {})
 9058    }
 9059
 9060    async fn handle_lsp_ext_run_flycheck(
 9061        lsp_store: Entity<Self>,
 9062        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9063        mut cx: AsyncApp,
 9064    ) -> Result<proto::Ack> {
 9065        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9066        lsp_store.update(&mut cx, |lsp_store, cx| {
 9067            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9068                let text_document = if envelope.payload.current_file_only {
 9069                    let buffer_id = envelope
 9070                        .payload
 9071                        .buffer_id
 9072                        .map(|id| BufferId::new(id))
 9073                        .transpose()?;
 9074                    buffer_id
 9075                        .and_then(|buffer_id| {
 9076                            lsp_store
 9077                                .buffer_store()
 9078                                .read(cx)
 9079                                .get(buffer_id)
 9080                                .and_then(|buffer| {
 9081                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9082                                })
 9083                                .map(|path| make_text_document_identifier(&path))
 9084                        })
 9085                        .transpose()?
 9086                } else {
 9087                    None
 9088                };
 9089                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9090                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9091                )?;
 9092            }
 9093            anyhow::Ok(())
 9094        })??;
 9095
 9096        Ok(proto::Ack {})
 9097    }
 9098
 9099    async fn handle_lsp_ext_clear_flycheck(
 9100        lsp_store: Entity<Self>,
 9101        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9102        cx: AsyncApp,
 9103    ) -> Result<proto::Ack> {
 9104        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9105        lsp_store
 9106            .read_with(&cx, |lsp_store, _| {
 9107                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9108                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9109                } else {
 9110                    None
 9111                }
 9112            })
 9113            .context("handling lsp ext clear flycheck")?;
 9114
 9115        Ok(proto::Ack {})
 9116    }
 9117
 9118    pub fn disk_based_diagnostics_started(
 9119        &mut self,
 9120        language_server_id: LanguageServerId,
 9121        cx: &mut Context<Self>,
 9122    ) {
 9123        if let Some(language_server_status) =
 9124            self.language_server_statuses.get_mut(&language_server_id)
 9125        {
 9126            language_server_status.has_pending_diagnostic_updates = true;
 9127        }
 9128
 9129        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9130        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9131            language_server_id,
 9132            name: self
 9133                .language_server_adapter_for_id(language_server_id)
 9134                .map(|adapter| adapter.name()),
 9135            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9136                Default::default(),
 9137            ),
 9138        })
 9139    }
 9140
 9141    pub fn disk_based_diagnostics_finished(
 9142        &mut self,
 9143        language_server_id: LanguageServerId,
 9144        cx: &mut Context<Self>,
 9145    ) {
 9146        if let Some(language_server_status) =
 9147            self.language_server_statuses.get_mut(&language_server_id)
 9148        {
 9149            language_server_status.has_pending_diagnostic_updates = false;
 9150        }
 9151
 9152        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9153        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9154            language_server_id,
 9155            name: self
 9156                .language_server_adapter_for_id(language_server_id)
 9157                .map(|adapter| adapter.name()),
 9158            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9159                Default::default(),
 9160            ),
 9161        })
 9162    }
 9163
 9164    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9165    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9166    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9167    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9168    // the language server might take some time to publish diagnostics.
 9169    fn simulate_disk_based_diagnostics_events_if_needed(
 9170        &mut self,
 9171        language_server_id: LanguageServerId,
 9172        cx: &mut Context<Self>,
 9173    ) {
 9174        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9175
 9176        let Some(LanguageServerState::Running {
 9177            simulate_disk_based_diagnostics_completion,
 9178            adapter,
 9179            ..
 9180        }) = self
 9181            .as_local_mut()
 9182            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9183        else {
 9184            return;
 9185        };
 9186
 9187        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9188            return;
 9189        }
 9190
 9191        let prev_task =
 9192            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9193                cx.background_executor()
 9194                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9195                    .await;
 9196
 9197                this.update(cx, |this, cx| {
 9198                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9199
 9200                    if let Some(LanguageServerState::Running {
 9201                        simulate_disk_based_diagnostics_completion,
 9202                        ..
 9203                    }) = this.as_local_mut().and_then(|local_store| {
 9204                        local_store.language_servers.get_mut(&language_server_id)
 9205                    }) {
 9206                        *simulate_disk_based_diagnostics_completion = None;
 9207                    }
 9208                })
 9209                .ok();
 9210            }));
 9211
 9212        if prev_task.is_none() {
 9213            self.disk_based_diagnostics_started(language_server_id, cx);
 9214        }
 9215    }
 9216
 9217    pub fn language_server_statuses(
 9218        &self,
 9219    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9220        self.language_server_statuses
 9221            .iter()
 9222            .map(|(key, value)| (*key, value))
 9223    }
 9224
 9225    pub(super) fn did_rename_entry(
 9226        &self,
 9227        worktree_id: WorktreeId,
 9228        old_path: &Path,
 9229        new_path: &Path,
 9230        is_dir: bool,
 9231    ) {
 9232        maybe!({
 9233            let local_store = self.as_local()?;
 9234
 9235            let old_uri = lsp::Uri::from_file_path(old_path)
 9236                .ok()
 9237                .map(|uri| uri.to_string())?;
 9238            let new_uri = lsp::Uri::from_file_path(new_path)
 9239                .ok()
 9240                .map(|uri| uri.to_string())?;
 9241
 9242            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9243                let Some(filter) = local_store
 9244                    .language_server_paths_watched_for_rename
 9245                    .get(&language_server.server_id())
 9246                else {
 9247                    continue;
 9248                };
 9249
 9250                if filter.should_send_did_rename(&old_uri, is_dir) {
 9251                    language_server
 9252                        .notify::<DidRenameFiles>(RenameFilesParams {
 9253                            files: vec![FileRename {
 9254                                old_uri: old_uri.clone(),
 9255                                new_uri: new_uri.clone(),
 9256                            }],
 9257                        })
 9258                        .ok();
 9259                }
 9260            }
 9261            Some(())
 9262        });
 9263    }
 9264
 9265    pub(super) fn will_rename_entry(
 9266        this: WeakEntity<Self>,
 9267        worktree_id: WorktreeId,
 9268        old_path: &Path,
 9269        new_path: &Path,
 9270        is_dir: bool,
 9271        cx: AsyncApp,
 9272    ) -> Task<ProjectTransaction> {
 9273        let old_uri = lsp::Uri::from_file_path(old_path)
 9274            .ok()
 9275            .map(|uri| uri.to_string());
 9276        let new_uri = lsp::Uri::from_file_path(new_path)
 9277            .ok()
 9278            .map(|uri| uri.to_string());
 9279        cx.spawn(async move |cx| {
 9280            let mut tasks = vec![];
 9281            this.update(cx, |this, cx| {
 9282                let local_store = this.as_local()?;
 9283                let old_uri = old_uri?;
 9284                let new_uri = new_uri?;
 9285                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9286                    let Some(filter) = local_store
 9287                        .language_server_paths_watched_for_rename
 9288                        .get(&language_server.server_id())
 9289                    else {
 9290                        continue;
 9291                    };
 9292
 9293                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9294                        let apply_edit = cx.spawn({
 9295                            let old_uri = old_uri.clone();
 9296                            let new_uri = new_uri.clone();
 9297                            let language_server = language_server.clone();
 9298                            async move |this, cx| {
 9299                                let edit = language_server
 9300                                    .request::<WillRenameFiles>(RenameFilesParams {
 9301                                        files: vec![FileRename { old_uri, new_uri }],
 9302                                    })
 9303                                    .await
 9304                                    .into_response()
 9305                                    .context("will rename files")
 9306                                    .log_err()
 9307                                    .flatten()?;
 9308
 9309                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9310                                    this.upgrade()?,
 9311                                    edit,
 9312                                    false,
 9313                                    language_server.clone(),
 9314                                    cx,
 9315                                )
 9316                                .await
 9317                                .ok()?;
 9318                                Some(transaction)
 9319                            }
 9320                        });
 9321                        tasks.push(apply_edit);
 9322                    }
 9323                }
 9324                Some(())
 9325            })
 9326            .ok()
 9327            .flatten();
 9328            let mut merged_transaction = ProjectTransaction::default();
 9329            for task in tasks {
 9330                // Await on tasks sequentially so that the order of application of edits is deterministic
 9331                // (at least with regards to the order of registration of language servers)
 9332                if let Some(transaction) = task.await {
 9333                    for (buffer, buffer_transaction) in transaction.0 {
 9334                        merged_transaction.0.insert(buffer, buffer_transaction);
 9335                    }
 9336                }
 9337            }
 9338            merged_transaction
 9339        })
 9340    }
 9341
 9342    fn lsp_notify_abs_paths_changed(
 9343        &mut self,
 9344        server_id: LanguageServerId,
 9345        changes: Vec<PathEvent>,
 9346    ) {
 9347        maybe!({
 9348            let server = self.language_server_for_id(server_id)?;
 9349            let changes = changes
 9350                .into_iter()
 9351                .filter_map(|event| {
 9352                    let typ = match event.kind? {
 9353                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9354                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9355                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9356                    };
 9357                    Some(lsp::FileEvent {
 9358                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9359                        typ,
 9360                    })
 9361                })
 9362                .collect::<Vec<_>>();
 9363            if !changes.is_empty() {
 9364                server
 9365                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9366                        lsp::DidChangeWatchedFilesParams { changes },
 9367                    )
 9368                    .ok();
 9369            }
 9370            Some(())
 9371        });
 9372    }
 9373
 9374    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9375        self.as_local()?.language_server_for_id(id)
 9376    }
 9377
 9378    fn on_lsp_progress(
 9379        &mut self,
 9380        progress: lsp::ProgressParams,
 9381        language_server_id: LanguageServerId,
 9382        disk_based_diagnostics_progress_token: Option<String>,
 9383        cx: &mut Context<Self>,
 9384    ) {
 9385        let token = match progress.token {
 9386            lsp::NumberOrString::String(token) => token,
 9387            lsp::NumberOrString::Number(token) => {
 9388                log::info!("skipping numeric progress token {}", token);
 9389                return;
 9390            }
 9391        };
 9392
 9393        match progress.value {
 9394            lsp::ProgressParamsValue::WorkDone(progress) => {
 9395                self.handle_work_done_progress(
 9396                    progress,
 9397                    language_server_id,
 9398                    disk_based_diagnostics_progress_token,
 9399                    token,
 9400                    cx,
 9401                );
 9402            }
 9403            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9404                let identifier = token.split_once("id:").map(|(_, id)| id.to_owned());
 9405                if let Some(LanguageServerState::Running {
 9406                    workspace_diagnostics_refresh_tasks,
 9407                    ..
 9408                }) = self
 9409                    .as_local_mut()
 9410                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9411                    && let Some(workspace_diagnostics) =
 9412                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9413                {
 9414                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9415                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9416                }
 9417            }
 9418        }
 9419    }
 9420
 9421    fn handle_work_done_progress(
 9422        &mut self,
 9423        progress: lsp::WorkDoneProgress,
 9424        language_server_id: LanguageServerId,
 9425        disk_based_diagnostics_progress_token: Option<String>,
 9426        token: String,
 9427        cx: &mut Context<Self>,
 9428    ) {
 9429        let language_server_status =
 9430            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9431                status
 9432            } else {
 9433                return;
 9434            };
 9435
 9436        if !language_server_status.progress_tokens.contains(&token) {
 9437            return;
 9438        }
 9439
 9440        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9441            .as_ref()
 9442            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9443
 9444        match progress {
 9445            lsp::WorkDoneProgress::Begin(report) => {
 9446                if is_disk_based_diagnostics_progress {
 9447                    self.disk_based_diagnostics_started(language_server_id, cx);
 9448                }
 9449                self.on_lsp_work_start(
 9450                    language_server_id,
 9451                    token.clone(),
 9452                    LanguageServerProgress {
 9453                        title: Some(report.title),
 9454                        is_disk_based_diagnostics_progress,
 9455                        is_cancellable: report.cancellable.unwrap_or(false),
 9456                        message: report.message.clone(),
 9457                        percentage: report.percentage.map(|p| p as usize),
 9458                        last_update_at: cx.background_executor().now(),
 9459                    },
 9460                    cx,
 9461                );
 9462            }
 9463            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9464                language_server_id,
 9465                token,
 9466                LanguageServerProgress {
 9467                    title: None,
 9468                    is_disk_based_diagnostics_progress,
 9469                    is_cancellable: report.cancellable.unwrap_or(false),
 9470                    message: report.message,
 9471                    percentage: report.percentage.map(|p| p as usize),
 9472                    last_update_at: cx.background_executor().now(),
 9473                },
 9474                cx,
 9475            ),
 9476            lsp::WorkDoneProgress::End(_) => {
 9477                language_server_status.progress_tokens.remove(&token);
 9478                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9479                if is_disk_based_diagnostics_progress {
 9480                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9481                }
 9482            }
 9483        }
 9484    }
 9485
 9486    fn on_lsp_work_start(
 9487        &mut self,
 9488        language_server_id: LanguageServerId,
 9489        token: String,
 9490        progress: LanguageServerProgress,
 9491        cx: &mut Context<Self>,
 9492    ) {
 9493        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9494            status.pending_work.insert(token.clone(), progress.clone());
 9495            cx.notify();
 9496        }
 9497        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9498            language_server_id,
 9499            name: self
 9500                .language_server_adapter_for_id(language_server_id)
 9501                .map(|adapter| adapter.name()),
 9502            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9503                token,
 9504                title: progress.title,
 9505                message: progress.message,
 9506                percentage: progress.percentage.map(|p| p as u32),
 9507                is_cancellable: Some(progress.is_cancellable),
 9508            }),
 9509        })
 9510    }
 9511
 9512    fn on_lsp_work_progress(
 9513        &mut self,
 9514        language_server_id: LanguageServerId,
 9515        token: String,
 9516        progress: LanguageServerProgress,
 9517        cx: &mut Context<Self>,
 9518    ) {
 9519        let mut did_update = false;
 9520        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9521            match status.pending_work.entry(token.clone()) {
 9522                btree_map::Entry::Vacant(entry) => {
 9523                    entry.insert(progress.clone());
 9524                    did_update = true;
 9525                }
 9526                btree_map::Entry::Occupied(mut entry) => {
 9527                    let entry = entry.get_mut();
 9528                    if (progress.last_update_at - entry.last_update_at)
 9529                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9530                    {
 9531                        entry.last_update_at = progress.last_update_at;
 9532                        if progress.message.is_some() {
 9533                            entry.message = progress.message.clone();
 9534                        }
 9535                        if progress.percentage.is_some() {
 9536                            entry.percentage = progress.percentage;
 9537                        }
 9538                        if progress.is_cancellable != entry.is_cancellable {
 9539                            entry.is_cancellable = progress.is_cancellable;
 9540                        }
 9541                        did_update = true;
 9542                    }
 9543                }
 9544            }
 9545        }
 9546
 9547        if did_update {
 9548            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9549                language_server_id,
 9550                name: self
 9551                    .language_server_adapter_for_id(language_server_id)
 9552                    .map(|adapter| adapter.name()),
 9553                message: proto::update_language_server::Variant::WorkProgress(
 9554                    proto::LspWorkProgress {
 9555                        token,
 9556                        message: progress.message,
 9557                        percentage: progress.percentage.map(|p| p as u32),
 9558                        is_cancellable: Some(progress.is_cancellable),
 9559                    },
 9560                ),
 9561            })
 9562        }
 9563    }
 9564
 9565    fn on_lsp_work_end(
 9566        &mut self,
 9567        language_server_id: LanguageServerId,
 9568        token: String,
 9569        cx: &mut Context<Self>,
 9570    ) {
 9571        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9572            if let Some(work) = status.pending_work.remove(&token)
 9573                && !work.is_disk_based_diagnostics_progress
 9574            {
 9575                cx.emit(LspStoreEvent::RefreshInlayHints {
 9576                    server_id: language_server_id,
 9577                    request_id: None,
 9578                });
 9579            }
 9580            cx.notify();
 9581        }
 9582
 9583        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9584            language_server_id,
 9585            name: self
 9586                .language_server_adapter_for_id(language_server_id)
 9587                .map(|adapter| adapter.name()),
 9588            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9589        })
 9590    }
 9591
 9592    pub async fn handle_resolve_completion_documentation(
 9593        this: Entity<Self>,
 9594        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9595        mut cx: AsyncApp,
 9596    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9597        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9598
 9599        let completion = this
 9600            .read_with(&cx, |this, cx| {
 9601                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9602                let server = this
 9603                    .language_server_for_id(id)
 9604                    .with_context(|| format!("No language server {id}"))?;
 9605
 9606                anyhow::Ok(cx.background_spawn(async move {
 9607                    let can_resolve = server
 9608                        .capabilities()
 9609                        .completion_provider
 9610                        .as_ref()
 9611                        .and_then(|options| options.resolve_provider)
 9612                        .unwrap_or(false);
 9613                    if can_resolve {
 9614                        server
 9615                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9616                            .await
 9617                            .into_response()
 9618                            .context("resolve completion item")
 9619                    } else {
 9620                        anyhow::Ok(lsp_completion)
 9621                    }
 9622                }))
 9623            })??
 9624            .await?;
 9625
 9626        let mut documentation_is_markdown = false;
 9627        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9628        let documentation = match completion.documentation {
 9629            Some(lsp::Documentation::String(text)) => text,
 9630
 9631            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9632                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9633                value
 9634            }
 9635
 9636            _ => String::new(),
 9637        };
 9638
 9639        // If we have a new buffer_id, that means we're talking to a new client
 9640        // and want to check for new text_edits in the completion too.
 9641        let mut old_replace_start = None;
 9642        let mut old_replace_end = None;
 9643        let mut old_insert_start = None;
 9644        let mut old_insert_end = None;
 9645        let mut new_text = String::default();
 9646        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9647            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9648                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9649                anyhow::Ok(buffer.read(cx).snapshot())
 9650            })??;
 9651
 9652            if let Some(text_edit) = completion.text_edit.as_ref() {
 9653                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9654
 9655                if let Some(mut edit) = edit {
 9656                    LineEnding::normalize(&mut edit.new_text);
 9657
 9658                    new_text = edit.new_text;
 9659                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9660                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9661                    if let Some(insert_range) = edit.insert_range {
 9662                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9663                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9664                    }
 9665                }
 9666            }
 9667        }
 9668
 9669        Ok(proto::ResolveCompletionDocumentationResponse {
 9670            documentation,
 9671            documentation_is_markdown,
 9672            old_replace_start,
 9673            old_replace_end,
 9674            new_text,
 9675            lsp_completion,
 9676            old_insert_start,
 9677            old_insert_end,
 9678        })
 9679    }
 9680
 9681    async fn handle_on_type_formatting(
 9682        this: Entity<Self>,
 9683        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9684        mut cx: AsyncApp,
 9685    ) -> Result<proto::OnTypeFormattingResponse> {
 9686        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9687            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9688            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9689            let position = envelope
 9690                .payload
 9691                .position
 9692                .and_then(deserialize_anchor)
 9693                .context("invalid position")?;
 9694            anyhow::Ok(this.apply_on_type_formatting(
 9695                buffer,
 9696                position,
 9697                envelope.payload.trigger.clone(),
 9698                cx,
 9699            ))
 9700        })??;
 9701
 9702        let transaction = on_type_formatting
 9703            .await?
 9704            .as_ref()
 9705            .map(language::proto::serialize_transaction);
 9706        Ok(proto::OnTypeFormattingResponse { transaction })
 9707    }
 9708
 9709    async fn handle_refresh_inlay_hints(
 9710        lsp_store: Entity<Self>,
 9711        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9712        mut cx: AsyncApp,
 9713    ) -> Result<proto::Ack> {
 9714        lsp_store.update(&mut cx, |_, cx| {
 9715            cx.emit(LspStoreEvent::RefreshInlayHints {
 9716                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
 9717                request_id: envelope.payload.request_id.map(|id| id as usize),
 9718            });
 9719        })?;
 9720        Ok(proto::Ack {})
 9721    }
 9722
 9723    async fn handle_pull_workspace_diagnostics(
 9724        lsp_store: Entity<Self>,
 9725        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9726        mut cx: AsyncApp,
 9727    ) -> Result<proto::Ack> {
 9728        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9729        lsp_store.update(&mut cx, |lsp_store, _| {
 9730            lsp_store.pull_workspace_diagnostics(server_id);
 9731        })?;
 9732        Ok(proto::Ack {})
 9733    }
 9734
 9735    async fn handle_get_color_presentation(
 9736        lsp_store: Entity<Self>,
 9737        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9738        mut cx: AsyncApp,
 9739    ) -> Result<proto::GetColorPresentationResponse> {
 9740        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9741        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9742            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9743        })??;
 9744
 9745        let color = envelope
 9746            .payload
 9747            .color
 9748            .context("invalid color resolve request")?;
 9749        let start = color
 9750            .lsp_range_start
 9751            .context("invalid color resolve request")?;
 9752        let end = color
 9753            .lsp_range_end
 9754            .context("invalid color resolve request")?;
 9755
 9756        let color = DocumentColor {
 9757            lsp_range: lsp::Range {
 9758                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9759                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9760            },
 9761            color: lsp::Color {
 9762                red: color.red,
 9763                green: color.green,
 9764                blue: color.blue,
 9765                alpha: color.alpha,
 9766            },
 9767            resolved: false,
 9768            color_presentations: Vec::new(),
 9769        };
 9770        let resolved_color = lsp_store
 9771            .update(&mut cx, |lsp_store, cx| {
 9772                lsp_store.resolve_color_presentation(
 9773                    color,
 9774                    buffer.clone(),
 9775                    LanguageServerId(envelope.payload.server_id as usize),
 9776                    cx,
 9777                )
 9778            })?
 9779            .await
 9780            .context("resolving color presentation")?;
 9781
 9782        Ok(proto::GetColorPresentationResponse {
 9783            presentations: resolved_color
 9784                .color_presentations
 9785                .into_iter()
 9786                .map(|presentation| proto::ColorPresentation {
 9787                    label: presentation.label.to_string(),
 9788                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9789                    additional_text_edits: presentation
 9790                        .additional_text_edits
 9791                        .into_iter()
 9792                        .map(serialize_lsp_edit)
 9793                        .collect(),
 9794                })
 9795                .collect(),
 9796        })
 9797    }
 9798
 9799    async fn handle_resolve_inlay_hint(
 9800        lsp_store: Entity<Self>,
 9801        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9802        mut cx: AsyncApp,
 9803    ) -> Result<proto::ResolveInlayHintResponse> {
 9804        let proto_hint = envelope
 9805            .payload
 9806            .hint
 9807            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9808        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9809            .context("resolved proto inlay hint conversion")?;
 9810        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9811            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9812            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9813        })??;
 9814        let response_hint = lsp_store
 9815            .update(&mut cx, |lsp_store, cx| {
 9816                lsp_store.resolve_inlay_hint(
 9817                    hint,
 9818                    buffer,
 9819                    LanguageServerId(envelope.payload.language_server_id as usize),
 9820                    cx,
 9821                )
 9822            })?
 9823            .await
 9824            .context("inlay hints fetch")?;
 9825        Ok(proto::ResolveInlayHintResponse {
 9826            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9827        })
 9828    }
 9829
 9830    async fn handle_refresh_code_lens(
 9831        this: Entity<Self>,
 9832        _: TypedEnvelope<proto::RefreshCodeLens>,
 9833        mut cx: AsyncApp,
 9834    ) -> Result<proto::Ack> {
 9835        this.update(&mut cx, |_, cx| {
 9836            cx.emit(LspStoreEvent::RefreshCodeLens);
 9837        })?;
 9838        Ok(proto::Ack {})
 9839    }
 9840
 9841    async fn handle_open_buffer_for_symbol(
 9842        this: Entity<Self>,
 9843        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9844        mut cx: AsyncApp,
 9845    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9846        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9847        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9848        let symbol = Self::deserialize_symbol(symbol)?;
 9849        this.read_with(&cx, |this, _| {
 9850            if let SymbolLocation::OutsideProject {
 9851                abs_path,
 9852                signature,
 9853            } = &symbol.path
 9854            {
 9855                let new_signature = this.symbol_signature(&abs_path);
 9856                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9857            }
 9858            Ok(())
 9859        })??;
 9860        let buffer = this
 9861            .update(&mut cx, |this, cx| {
 9862                this.open_buffer_for_symbol(
 9863                    &Symbol {
 9864                        language_server_name: symbol.language_server_name,
 9865                        source_worktree_id: symbol.source_worktree_id,
 9866                        source_language_server_id: symbol.source_language_server_id,
 9867                        path: symbol.path,
 9868                        name: symbol.name,
 9869                        kind: symbol.kind,
 9870                        range: symbol.range,
 9871                        label: CodeLabel::default(),
 9872                    },
 9873                    cx,
 9874                )
 9875            })?
 9876            .await?;
 9877
 9878        this.update(&mut cx, |this, cx| {
 9879            let is_private = buffer
 9880                .read(cx)
 9881                .file()
 9882                .map(|f| f.is_private())
 9883                .unwrap_or_default();
 9884            if is_private {
 9885                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9886            } else {
 9887                this.buffer_store
 9888                    .update(cx, |buffer_store, cx| {
 9889                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9890                    })
 9891                    .detach_and_log_err(cx);
 9892                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9893                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9894            }
 9895        })?
 9896    }
 9897
 9898    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9899        let mut hasher = Sha256::new();
 9900        hasher.update(abs_path.to_string_lossy().as_bytes());
 9901        hasher.update(self.nonce.to_be_bytes());
 9902        hasher.finalize().as_slice().try_into().unwrap()
 9903    }
 9904
 9905    pub async fn handle_get_project_symbols(
 9906        this: Entity<Self>,
 9907        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9908        mut cx: AsyncApp,
 9909    ) -> Result<proto::GetProjectSymbolsResponse> {
 9910        let symbols = this
 9911            .update(&mut cx, |this, cx| {
 9912                this.symbols(&envelope.payload.query, cx)
 9913            })?
 9914            .await?;
 9915
 9916        Ok(proto::GetProjectSymbolsResponse {
 9917            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9918        })
 9919    }
 9920
 9921    pub async fn handle_restart_language_servers(
 9922        this: Entity<Self>,
 9923        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9924        mut cx: AsyncApp,
 9925    ) -> Result<proto::Ack> {
 9926        this.update(&mut cx, |lsp_store, cx| {
 9927            let buffers =
 9928                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9929            lsp_store.restart_language_servers_for_buffers(
 9930                buffers,
 9931                envelope
 9932                    .payload
 9933                    .only_servers
 9934                    .into_iter()
 9935                    .filter_map(|selector| {
 9936                        Some(match selector.selector? {
 9937                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9938                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9939                            }
 9940                            proto::language_server_selector::Selector::Name(name) => {
 9941                                LanguageServerSelector::Name(LanguageServerName(
 9942                                    SharedString::from(name),
 9943                                ))
 9944                            }
 9945                        })
 9946                    })
 9947                    .collect(),
 9948                cx,
 9949            );
 9950        })?;
 9951
 9952        Ok(proto::Ack {})
 9953    }
 9954
 9955    pub async fn handle_stop_language_servers(
 9956        lsp_store: Entity<Self>,
 9957        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9958        mut cx: AsyncApp,
 9959    ) -> Result<proto::Ack> {
 9960        lsp_store.update(&mut cx, |lsp_store, cx| {
 9961            if envelope.payload.all
 9962                && envelope.payload.also_servers.is_empty()
 9963                && envelope.payload.buffer_ids.is_empty()
 9964            {
 9965                lsp_store.stop_all_language_servers(cx);
 9966            } else {
 9967                let buffers =
 9968                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9969                lsp_store
 9970                    .stop_language_servers_for_buffers(
 9971                        buffers,
 9972                        envelope
 9973                            .payload
 9974                            .also_servers
 9975                            .into_iter()
 9976                            .filter_map(|selector| {
 9977                                Some(match selector.selector? {
 9978                                    proto::language_server_selector::Selector::ServerId(
 9979                                        server_id,
 9980                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9981                                        server_id,
 9982                                    )),
 9983                                    proto::language_server_selector::Selector::Name(name) => {
 9984                                        LanguageServerSelector::Name(LanguageServerName(
 9985                                            SharedString::from(name),
 9986                                        ))
 9987                                    }
 9988                                })
 9989                            })
 9990                            .collect(),
 9991                        cx,
 9992                    )
 9993                    .detach_and_log_err(cx);
 9994            }
 9995        })?;
 9996
 9997        Ok(proto::Ack {})
 9998    }
 9999
10000    pub async fn handle_cancel_language_server_work(
10001        this: Entity<Self>,
10002        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10003        mut cx: AsyncApp,
10004    ) -> Result<proto::Ack> {
10005        this.update(&mut cx, |this, cx| {
10006            if let Some(work) = envelope.payload.work {
10007                match work {
10008                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10009                        let buffers =
10010                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10011                        this.cancel_language_server_work_for_buffers(buffers, cx);
10012                    }
10013                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10014                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10015                        this.cancel_language_server_work(server_id, work.token, cx);
10016                    }
10017                }
10018            }
10019        })?;
10020
10021        Ok(proto::Ack {})
10022    }
10023
10024    fn buffer_ids_to_buffers(
10025        &mut self,
10026        buffer_ids: impl Iterator<Item = u64>,
10027        cx: &mut Context<Self>,
10028    ) -> Vec<Entity<Buffer>> {
10029        buffer_ids
10030            .into_iter()
10031            .flat_map(|buffer_id| {
10032                self.buffer_store
10033                    .read(cx)
10034                    .get(BufferId::new(buffer_id).log_err()?)
10035            })
10036            .collect::<Vec<_>>()
10037    }
10038
10039    async fn handle_apply_additional_edits_for_completion(
10040        this: Entity<Self>,
10041        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10042        mut cx: AsyncApp,
10043    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10044        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10045            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10046            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10047            let completion = Self::deserialize_completion(
10048                envelope.payload.completion.context("invalid completion")?,
10049            )?;
10050            anyhow::Ok((buffer, completion))
10051        })??;
10052
10053        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10054            this.apply_additional_edits_for_completion(
10055                buffer,
10056                Rc::new(RefCell::new(Box::new([Completion {
10057                    replace_range: completion.replace_range,
10058                    new_text: completion.new_text,
10059                    source: completion.source,
10060                    documentation: None,
10061                    label: CodeLabel::default(),
10062                    insert_text_mode: None,
10063                    icon_path: None,
10064                    confirm: None,
10065                }]))),
10066                0,
10067                false,
10068                cx,
10069            )
10070        })?;
10071
10072        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10073            transaction: apply_additional_edits
10074                .await?
10075                .as_ref()
10076                .map(language::proto::serialize_transaction),
10077        })
10078    }
10079
10080    pub fn last_formatting_failure(&self) -> Option<&str> {
10081        self.last_formatting_failure.as_deref()
10082    }
10083
10084    pub fn reset_last_formatting_failure(&mut self) {
10085        self.last_formatting_failure = None;
10086    }
10087
10088    pub fn environment_for_buffer(
10089        &self,
10090        buffer: &Entity<Buffer>,
10091        cx: &mut Context<Self>,
10092    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10093        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10094            environment.update(cx, |env, cx| {
10095                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10096            })
10097        } else {
10098            Task::ready(None).shared()
10099        }
10100    }
10101
10102    pub fn format(
10103        &mut self,
10104        buffers: HashSet<Entity<Buffer>>,
10105        target: LspFormatTarget,
10106        push_to_history: bool,
10107        trigger: FormatTrigger,
10108        cx: &mut Context<Self>,
10109    ) -> Task<anyhow::Result<ProjectTransaction>> {
10110        let logger = zlog::scoped!("format");
10111        if self.as_local().is_some() {
10112            zlog::trace!(logger => "Formatting locally");
10113            let logger = zlog::scoped!(logger => "local");
10114            let buffers = buffers
10115                .into_iter()
10116                .map(|buffer_handle| {
10117                    let buffer = buffer_handle.read(cx);
10118                    let buffer_abs_path = File::from_dyn(buffer.file())
10119                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10120
10121                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10122                })
10123                .collect::<Vec<_>>();
10124
10125            cx.spawn(async move |lsp_store, cx| {
10126                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10127
10128                for (handle, abs_path, id) in buffers {
10129                    let env = lsp_store
10130                        .update(cx, |lsp_store, cx| {
10131                            lsp_store.environment_for_buffer(&handle, cx)
10132                        })?
10133                        .await;
10134
10135                    let ranges = match &target {
10136                        LspFormatTarget::Buffers => None,
10137                        LspFormatTarget::Ranges(ranges) => {
10138                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10139                        }
10140                    };
10141
10142                    formattable_buffers.push(FormattableBuffer {
10143                        handle,
10144                        abs_path,
10145                        env,
10146                        ranges,
10147                    });
10148                }
10149                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10150
10151                let format_timer = zlog::time!(logger => "Formatting buffers");
10152                let result = LocalLspStore::format_locally(
10153                    lsp_store.clone(),
10154                    formattable_buffers,
10155                    push_to_history,
10156                    trigger,
10157                    logger,
10158                    cx,
10159                )
10160                .await;
10161                format_timer.end();
10162
10163                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10164
10165                lsp_store.update(cx, |lsp_store, _| {
10166                    lsp_store.update_last_formatting_failure(&result);
10167                })?;
10168
10169                result
10170            })
10171        } else if let Some((client, project_id)) = self.upstream_client() {
10172            zlog::trace!(logger => "Formatting remotely");
10173            let logger = zlog::scoped!(logger => "remote");
10174            // Don't support formatting ranges via remote
10175            match target {
10176                LspFormatTarget::Buffers => {}
10177                LspFormatTarget::Ranges(_) => {
10178                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10179                    return Task::ready(Ok(ProjectTransaction::default()));
10180                }
10181            }
10182
10183            let buffer_store = self.buffer_store();
10184            cx.spawn(async move |lsp_store, cx| {
10185                zlog::trace!(logger => "Sending remote format request");
10186                let request_timer = zlog::time!(logger => "remote format request");
10187                let result = client
10188                    .request(proto::FormatBuffers {
10189                        project_id,
10190                        trigger: trigger as i32,
10191                        buffer_ids: buffers
10192                            .iter()
10193                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10194                            .collect::<Result<_>>()?,
10195                    })
10196                    .await
10197                    .and_then(|result| result.transaction.context("missing transaction"));
10198                request_timer.end();
10199
10200                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10201
10202                lsp_store.update(cx, |lsp_store, _| {
10203                    lsp_store.update_last_formatting_failure(&result);
10204                })?;
10205
10206                let transaction_response = result?;
10207                let _timer = zlog::time!(logger => "deserializing project transaction");
10208                buffer_store
10209                    .update(cx, |buffer_store, cx| {
10210                        buffer_store.deserialize_project_transaction(
10211                            transaction_response,
10212                            push_to_history,
10213                            cx,
10214                        )
10215                    })?
10216                    .await
10217            })
10218        } else {
10219            zlog::trace!(logger => "Not formatting");
10220            Task::ready(Ok(ProjectTransaction::default()))
10221        }
10222    }
10223
10224    async fn handle_format_buffers(
10225        this: Entity<Self>,
10226        envelope: TypedEnvelope<proto::FormatBuffers>,
10227        mut cx: AsyncApp,
10228    ) -> Result<proto::FormatBuffersResponse> {
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 trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10237            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10238        })??;
10239
10240        let project_transaction = format.await?;
10241        let project_transaction = this.update(&mut cx, |this, cx| {
10242            this.buffer_store.update(cx, |buffer_store, cx| {
10243                buffer_store.serialize_project_transaction_for_peer(
10244                    project_transaction,
10245                    sender_id,
10246                    cx,
10247                )
10248            })
10249        })?;
10250        Ok(proto::FormatBuffersResponse {
10251            transaction: Some(project_transaction),
10252        })
10253    }
10254
10255    async fn handle_apply_code_action_kind(
10256        this: Entity<Self>,
10257        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10258        mut cx: AsyncApp,
10259    ) -> Result<proto::ApplyCodeActionKindResponse> {
10260        let sender_id = envelope.original_sender_id().unwrap_or_default();
10261        let format = this.update(&mut cx, |this, cx| {
10262            let mut buffers = HashSet::default();
10263            for buffer_id in &envelope.payload.buffer_ids {
10264                let buffer_id = BufferId::new(*buffer_id)?;
10265                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10266            }
10267            let kind = match envelope.payload.kind.as_str() {
10268                "" => CodeActionKind::EMPTY,
10269                "quickfix" => CodeActionKind::QUICKFIX,
10270                "refactor" => CodeActionKind::REFACTOR,
10271                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10272                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10273                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10274                "source" => CodeActionKind::SOURCE,
10275                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10276                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10277                _ => anyhow::bail!(
10278                    "Invalid code action kind {}",
10279                    envelope.payload.kind.as_str()
10280                ),
10281            };
10282            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10283        })??;
10284
10285        let project_transaction = format.await?;
10286        let project_transaction = this.update(&mut cx, |this, cx| {
10287            this.buffer_store.update(cx, |buffer_store, cx| {
10288                buffer_store.serialize_project_transaction_for_peer(
10289                    project_transaction,
10290                    sender_id,
10291                    cx,
10292                )
10293            })
10294        })?;
10295        Ok(proto::ApplyCodeActionKindResponse {
10296            transaction: Some(project_transaction),
10297        })
10298    }
10299
10300    async fn shutdown_language_server(
10301        server_state: Option<LanguageServerState>,
10302        name: LanguageServerName,
10303        cx: &mut AsyncApp,
10304    ) {
10305        let server = match server_state {
10306            Some(LanguageServerState::Starting { startup, .. }) => {
10307                let mut timer = cx
10308                    .background_executor()
10309                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10310                    .fuse();
10311
10312                select! {
10313                    server = startup.fuse() => server,
10314                    () = timer => {
10315                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10316                        None
10317                    },
10318                }
10319            }
10320
10321            Some(LanguageServerState::Running { server, .. }) => Some(server),
10322
10323            None => None,
10324        };
10325
10326        if let Some(server) = server
10327            && let Some(shutdown) = server.shutdown()
10328        {
10329            shutdown.await;
10330        }
10331    }
10332
10333    // Returns a list of all of the worktrees which no longer have a language server and the root path
10334    // for the stopped server
10335    fn stop_local_language_server(
10336        &mut self,
10337        server_id: LanguageServerId,
10338        cx: &mut Context<Self>,
10339    ) -> Task<()> {
10340        let local = match &mut self.mode {
10341            LspStoreMode::Local(local) => local,
10342            _ => {
10343                return Task::ready(());
10344            }
10345        };
10346
10347        // Remove this server ID from all entries in the given worktree.
10348        local
10349            .language_server_ids
10350            .retain(|_, state| state.id != server_id);
10351        self.buffer_store.update(cx, |buffer_store, cx| {
10352            for buffer in buffer_store.buffers() {
10353                buffer.update(cx, |buffer, cx| {
10354                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10355                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10356                });
10357            }
10358        });
10359
10360        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10361            summaries.retain(|path, summaries_by_server_id| {
10362                if summaries_by_server_id.remove(&server_id).is_some() {
10363                    if let Some((client, project_id)) = self.downstream_client.clone() {
10364                        client
10365                            .send(proto::UpdateDiagnosticSummary {
10366                                project_id,
10367                                worktree_id: worktree_id.to_proto(),
10368                                summary: Some(proto::DiagnosticSummary {
10369                                    path: path.as_ref().to_proto(),
10370                                    language_server_id: server_id.0 as u64,
10371                                    error_count: 0,
10372                                    warning_count: 0,
10373                                }),
10374                                more_summaries: Vec::new(),
10375                            })
10376                            .log_err();
10377                    }
10378                    !summaries_by_server_id.is_empty()
10379                } else {
10380                    true
10381                }
10382            });
10383        }
10384
10385        let local = self.as_local_mut().unwrap();
10386        for diagnostics in local.diagnostics.values_mut() {
10387            diagnostics.retain(|_, diagnostics_by_server_id| {
10388                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10389                    diagnostics_by_server_id.remove(ix);
10390                    !diagnostics_by_server_id.is_empty()
10391                } else {
10392                    true
10393                }
10394            });
10395        }
10396        local.language_server_watched_paths.remove(&server_id);
10397
10398        let server_state = local.language_servers.remove(&server_id);
10399        self.cleanup_lsp_data(server_id);
10400        let name = self
10401            .language_server_statuses
10402            .remove(&server_id)
10403            .map(|status| status.name)
10404            .or_else(|| {
10405                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10406                    Some(adapter.name())
10407                } else {
10408                    None
10409                }
10410            });
10411
10412        if let Some(name) = name {
10413            log::info!("stopping language server {name}");
10414            self.languages
10415                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10416            cx.notify();
10417
10418            return cx.spawn(async move |lsp_store, cx| {
10419                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10420                lsp_store
10421                    .update(cx, |lsp_store, cx| {
10422                        lsp_store
10423                            .languages
10424                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10425                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10426                        cx.notify();
10427                    })
10428                    .ok();
10429            });
10430        }
10431
10432        if server_state.is_some() {
10433            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10434        }
10435        Task::ready(())
10436    }
10437
10438    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10439        if let Some((client, project_id)) = self.upstream_client() {
10440            let request = client.request(proto::StopLanguageServers {
10441                project_id,
10442                buffer_ids: Vec::new(),
10443                also_servers: Vec::new(),
10444                all: true,
10445            });
10446            cx.background_spawn(request).detach_and_log_err(cx);
10447        } else {
10448            let Some(local) = self.as_local_mut() else {
10449                return;
10450            };
10451            let language_servers_to_stop = local
10452                .language_server_ids
10453                .values()
10454                .map(|state| state.id)
10455                .collect();
10456            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10457            let tasks = language_servers_to_stop
10458                .into_iter()
10459                .map(|server| self.stop_local_language_server(server, cx))
10460                .collect::<Vec<_>>();
10461            cx.background_spawn(async move {
10462                futures::future::join_all(tasks).await;
10463            })
10464            .detach();
10465        }
10466    }
10467
10468    pub fn restart_language_servers_for_buffers(
10469        &mut self,
10470        buffers: Vec<Entity<Buffer>>,
10471        only_restart_servers: HashSet<LanguageServerSelector>,
10472        cx: &mut Context<Self>,
10473    ) {
10474        if let Some((client, project_id)) = self.upstream_client() {
10475            let request = client.request(proto::RestartLanguageServers {
10476                project_id,
10477                buffer_ids: buffers
10478                    .into_iter()
10479                    .map(|b| b.read(cx).remote_id().to_proto())
10480                    .collect(),
10481                only_servers: only_restart_servers
10482                    .into_iter()
10483                    .map(|selector| {
10484                        let selector = match selector {
10485                            LanguageServerSelector::Id(language_server_id) => {
10486                                proto::language_server_selector::Selector::ServerId(
10487                                    language_server_id.to_proto(),
10488                                )
10489                            }
10490                            LanguageServerSelector::Name(language_server_name) => {
10491                                proto::language_server_selector::Selector::Name(
10492                                    language_server_name.to_string(),
10493                                )
10494                            }
10495                        };
10496                        proto::LanguageServerSelector {
10497                            selector: Some(selector),
10498                        }
10499                    })
10500                    .collect(),
10501                all: false,
10502            });
10503            cx.background_spawn(request).detach_and_log_err(cx);
10504        } else {
10505            let stop_task = if only_restart_servers.is_empty() {
10506                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10507            } else {
10508                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10509            };
10510            cx.spawn(async move |lsp_store, cx| {
10511                stop_task.await;
10512                lsp_store
10513                    .update(cx, |lsp_store, cx| {
10514                        for buffer in buffers {
10515                            lsp_store.register_buffer_with_language_servers(
10516                                &buffer,
10517                                only_restart_servers.clone(),
10518                                true,
10519                                cx,
10520                            );
10521                        }
10522                    })
10523                    .ok()
10524            })
10525            .detach();
10526        }
10527    }
10528
10529    pub fn stop_language_servers_for_buffers(
10530        &mut self,
10531        buffers: Vec<Entity<Buffer>>,
10532        also_stop_servers: HashSet<LanguageServerSelector>,
10533        cx: &mut Context<Self>,
10534    ) -> Task<Result<()>> {
10535        if let Some((client, project_id)) = self.upstream_client() {
10536            let request = client.request(proto::StopLanguageServers {
10537                project_id,
10538                buffer_ids: buffers
10539                    .into_iter()
10540                    .map(|b| b.read(cx).remote_id().to_proto())
10541                    .collect(),
10542                also_servers: also_stop_servers
10543                    .into_iter()
10544                    .map(|selector| {
10545                        let selector = match selector {
10546                            LanguageServerSelector::Id(language_server_id) => {
10547                                proto::language_server_selector::Selector::ServerId(
10548                                    language_server_id.to_proto(),
10549                                )
10550                            }
10551                            LanguageServerSelector::Name(language_server_name) => {
10552                                proto::language_server_selector::Selector::Name(
10553                                    language_server_name.to_string(),
10554                                )
10555                            }
10556                        };
10557                        proto::LanguageServerSelector {
10558                            selector: Some(selector),
10559                        }
10560                    })
10561                    .collect(),
10562                all: false,
10563            });
10564            cx.background_spawn(async move {
10565                let _ = request.await?;
10566                Ok(())
10567            })
10568        } else {
10569            let task =
10570                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10571            cx.background_spawn(async move {
10572                task.await;
10573                Ok(())
10574            })
10575        }
10576    }
10577
10578    fn stop_local_language_servers_for_buffers(
10579        &mut self,
10580        buffers: &[Entity<Buffer>],
10581        also_stop_servers: HashSet<LanguageServerSelector>,
10582        cx: &mut Context<Self>,
10583    ) -> Task<()> {
10584        let Some(local) = self.as_local_mut() else {
10585            return Task::ready(());
10586        };
10587        let mut language_server_names_to_stop = BTreeSet::default();
10588        let mut language_servers_to_stop = also_stop_servers
10589            .into_iter()
10590            .flat_map(|selector| match selector {
10591                LanguageServerSelector::Id(id) => Some(id),
10592                LanguageServerSelector::Name(name) => {
10593                    language_server_names_to_stop.insert(name);
10594                    None
10595                }
10596            })
10597            .collect::<BTreeSet<_>>();
10598
10599        let mut covered_worktrees = HashSet::default();
10600        for buffer in buffers {
10601            buffer.update(cx, |buffer, cx| {
10602                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10603                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10604                    && covered_worktrees.insert(worktree_id)
10605                {
10606                    language_server_names_to_stop.retain(|name| {
10607                        let old_ids_count = language_servers_to_stop.len();
10608                        let all_language_servers_with_this_name = local
10609                            .language_server_ids
10610                            .iter()
10611                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10612                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10613                        old_ids_count == language_servers_to_stop.len()
10614                    });
10615                }
10616            });
10617        }
10618        for name in language_server_names_to_stop {
10619            language_servers_to_stop.extend(
10620                local
10621                    .language_server_ids
10622                    .iter()
10623                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10624            );
10625        }
10626
10627        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10628        let tasks = language_servers_to_stop
10629            .into_iter()
10630            .map(|server| self.stop_local_language_server(server, cx))
10631            .collect::<Vec<_>>();
10632
10633        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10634    }
10635
10636    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10637        let (worktree, relative_path) =
10638            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10639
10640        let project_path = ProjectPath {
10641            worktree_id: worktree.read(cx).id(),
10642            path: relative_path,
10643        };
10644
10645        Some(
10646            self.buffer_store()
10647                .read(cx)
10648                .get_by_path(&project_path)?
10649                .read(cx),
10650        )
10651    }
10652
10653    #[cfg(any(test, feature = "test-support"))]
10654    pub fn update_diagnostics(
10655        &mut self,
10656        server_id: LanguageServerId,
10657        diagnostics: lsp::PublishDiagnosticsParams,
10658        result_id: Option<String>,
10659        source_kind: DiagnosticSourceKind,
10660        disk_based_sources: &[String],
10661        cx: &mut Context<Self>,
10662    ) -> Result<()> {
10663        self.merge_lsp_diagnostics(
10664            source_kind,
10665            vec![DocumentDiagnosticsUpdate {
10666                diagnostics,
10667                result_id,
10668                server_id,
10669                disk_based_sources: Cow::Borrowed(disk_based_sources),
10670            }],
10671            |_, _, _| false,
10672            cx,
10673        )
10674    }
10675
10676    pub fn merge_lsp_diagnostics(
10677        &mut self,
10678        source_kind: DiagnosticSourceKind,
10679        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10680        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10681        cx: &mut Context<Self>,
10682    ) -> Result<()> {
10683        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10684        let updates = lsp_diagnostics
10685            .into_iter()
10686            .filter_map(|update| {
10687                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10688                Some(DocumentDiagnosticsUpdate {
10689                    diagnostics: self.lsp_to_document_diagnostics(
10690                        abs_path,
10691                        source_kind,
10692                        update.server_id,
10693                        update.diagnostics,
10694                        &update.disk_based_sources,
10695                    ),
10696                    result_id: update.result_id,
10697                    server_id: update.server_id,
10698                    disk_based_sources: update.disk_based_sources,
10699                })
10700            })
10701            .collect();
10702        self.merge_diagnostic_entries(updates, merge, cx)?;
10703        Ok(())
10704    }
10705
10706    fn lsp_to_document_diagnostics(
10707        &mut self,
10708        document_abs_path: PathBuf,
10709        source_kind: DiagnosticSourceKind,
10710        server_id: LanguageServerId,
10711        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10712        disk_based_sources: &[String],
10713    ) -> DocumentDiagnostics {
10714        let mut diagnostics = Vec::default();
10715        let mut primary_diagnostic_group_ids = HashMap::default();
10716        let mut sources_by_group_id = HashMap::default();
10717        let mut supporting_diagnostics = HashMap::default();
10718
10719        let adapter = self.language_server_adapter_for_id(server_id);
10720
10721        // Ensure that primary diagnostics are always the most severe
10722        lsp_diagnostics
10723            .diagnostics
10724            .sort_by_key(|item| item.severity);
10725
10726        for diagnostic in &lsp_diagnostics.diagnostics {
10727            let source = diagnostic.source.as_ref();
10728            let range = range_from_lsp(diagnostic.range);
10729            let is_supporting = diagnostic
10730                .related_information
10731                .as_ref()
10732                .is_some_and(|infos| {
10733                    infos.iter().any(|info| {
10734                        primary_diagnostic_group_ids.contains_key(&(
10735                            source,
10736                            diagnostic.code.clone(),
10737                            range_from_lsp(info.location.range),
10738                        ))
10739                    })
10740                });
10741
10742            let is_unnecessary = diagnostic
10743                .tags
10744                .as_ref()
10745                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10746
10747            let underline = self
10748                .language_server_adapter_for_id(server_id)
10749                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10750
10751            if is_supporting {
10752                supporting_diagnostics.insert(
10753                    (source, diagnostic.code.clone(), range),
10754                    (diagnostic.severity, is_unnecessary),
10755                );
10756            } else {
10757                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10758                let is_disk_based =
10759                    source.is_some_and(|source| disk_based_sources.contains(source));
10760
10761                sources_by_group_id.insert(group_id, source);
10762                primary_diagnostic_group_ids
10763                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10764
10765                diagnostics.push(DiagnosticEntry {
10766                    range,
10767                    diagnostic: Diagnostic {
10768                        source: diagnostic.source.clone(),
10769                        source_kind,
10770                        code: diagnostic.code.clone(),
10771                        code_description: diagnostic
10772                            .code_description
10773                            .as_ref()
10774                            .and_then(|d| d.href.clone()),
10775                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10776                        markdown: adapter.as_ref().and_then(|adapter| {
10777                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10778                        }),
10779                        message: diagnostic.message.trim().to_string(),
10780                        group_id,
10781                        is_primary: true,
10782                        is_disk_based,
10783                        is_unnecessary,
10784                        underline,
10785                        data: diagnostic.data.clone(),
10786                    },
10787                });
10788                if let Some(infos) = &diagnostic.related_information {
10789                    for info in infos {
10790                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10791                            let range = range_from_lsp(info.location.range);
10792                            diagnostics.push(DiagnosticEntry {
10793                                range,
10794                                diagnostic: Diagnostic {
10795                                    source: diagnostic.source.clone(),
10796                                    source_kind,
10797                                    code: diagnostic.code.clone(),
10798                                    code_description: diagnostic
10799                                        .code_description
10800                                        .as_ref()
10801                                        .and_then(|d| d.href.clone()),
10802                                    severity: DiagnosticSeverity::INFORMATION,
10803                                    markdown: adapter.as_ref().and_then(|adapter| {
10804                                        adapter.diagnostic_message_to_markdown(&info.message)
10805                                    }),
10806                                    message: info.message.trim().to_string(),
10807                                    group_id,
10808                                    is_primary: false,
10809                                    is_disk_based,
10810                                    is_unnecessary: false,
10811                                    underline,
10812                                    data: diagnostic.data.clone(),
10813                                },
10814                            });
10815                        }
10816                    }
10817                }
10818            }
10819        }
10820
10821        for entry in &mut diagnostics {
10822            let diagnostic = &mut entry.diagnostic;
10823            if !diagnostic.is_primary {
10824                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10825                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10826                    source,
10827                    diagnostic.code.clone(),
10828                    entry.range.clone(),
10829                )) {
10830                    if let Some(severity) = severity {
10831                        diagnostic.severity = severity;
10832                    }
10833                    diagnostic.is_unnecessary = is_unnecessary;
10834                }
10835            }
10836        }
10837
10838        DocumentDiagnostics {
10839            diagnostics,
10840            document_abs_path,
10841            version: lsp_diagnostics.version,
10842        }
10843    }
10844
10845    fn insert_newly_running_language_server(
10846        &mut self,
10847        adapter: Arc<CachedLspAdapter>,
10848        language_server: Arc<LanguageServer>,
10849        server_id: LanguageServerId,
10850        key: LanguageServerSeed,
10851        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10852        cx: &mut Context<Self>,
10853    ) {
10854        let Some(local) = self.as_local_mut() else {
10855            return;
10856        };
10857        // If the language server for this key doesn't match the server id, don't store the
10858        // server. Which will cause it to be dropped, killing the process
10859        if local
10860            .language_server_ids
10861            .get(&key)
10862            .map(|state| state.id != server_id)
10863            .unwrap_or(false)
10864        {
10865            return;
10866        }
10867
10868        // Update language_servers collection with Running variant of LanguageServerState
10869        // indicating that the server is up and running and ready
10870        let workspace_folders = workspace_folders.lock().clone();
10871        language_server.set_workspace_folders(workspace_folders);
10872
10873        let workspace_diagnostics_refresh_tasks = language_server
10874            .capabilities()
10875            .diagnostic_provider
10876            .and_then(|provider| {
10877                local
10878                    .language_server_dynamic_registrations
10879                    .entry(server_id)
10880                    .or_default()
10881                    .diagnostics
10882                    .entry(None)
10883                    .or_insert(provider.clone());
10884                let workspace_refresher =
10885                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
10886
10887                Some((None, workspace_refresher))
10888            })
10889            .into_iter()
10890            .collect();
10891        local.language_servers.insert(
10892            server_id,
10893            LanguageServerState::Running {
10894                workspace_diagnostics_refresh_tasks,
10895                adapter: adapter.clone(),
10896                server: language_server.clone(),
10897                simulate_disk_based_diagnostics_completion: None,
10898            },
10899        );
10900        local
10901            .languages
10902            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10903        if let Some(file_ops_caps) = language_server
10904            .capabilities()
10905            .workspace
10906            .as_ref()
10907            .and_then(|ws| ws.file_operations.as_ref())
10908        {
10909            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10910            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10911            if did_rename_caps.or(will_rename_caps).is_some() {
10912                let watcher = RenamePathsWatchedForServer::default()
10913                    .with_did_rename_patterns(did_rename_caps)
10914                    .with_will_rename_patterns(will_rename_caps);
10915                local
10916                    .language_server_paths_watched_for_rename
10917                    .insert(server_id, watcher);
10918            }
10919        }
10920
10921        self.language_server_statuses.insert(
10922            server_id,
10923            LanguageServerStatus {
10924                name: language_server.name(),
10925                pending_work: Default::default(),
10926                has_pending_diagnostic_updates: false,
10927                progress_tokens: Default::default(),
10928                worktree: Some(key.worktree_id),
10929            },
10930        );
10931
10932        cx.emit(LspStoreEvent::LanguageServerAdded(
10933            server_id,
10934            language_server.name(),
10935            Some(key.worktree_id),
10936        ));
10937
10938        let server_capabilities = language_server.capabilities();
10939        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10940            downstream_client
10941                .send(proto::StartLanguageServer {
10942                    project_id: *project_id,
10943                    server: Some(proto::LanguageServer {
10944                        id: server_id.to_proto(),
10945                        name: language_server.name().to_string(),
10946                        worktree_id: Some(key.worktree_id.to_proto()),
10947                    }),
10948                    capabilities: serde_json::to_string(&server_capabilities)
10949                        .expect("serializing server LSP capabilities"),
10950                })
10951                .log_err();
10952        }
10953        self.lsp_server_capabilities
10954            .insert(server_id, server_capabilities);
10955
10956        // Tell the language server about every open buffer in the worktree that matches the language.
10957        // Also check for buffers in worktrees that reused this server
10958        let mut worktrees_using_server = vec![key.worktree_id];
10959        if let Some(local) = self.as_local() {
10960            // Find all worktrees that have this server in their language server tree
10961            for (worktree_id, servers) in &local.lsp_tree.instances {
10962                if *worktree_id != key.worktree_id {
10963                    for server_map in servers.roots.values() {
10964                        if server_map
10965                            .values()
10966                            .any(|(node, _)| node.id() == Some(server_id))
10967                        {
10968                            worktrees_using_server.push(*worktree_id);
10969                        }
10970                    }
10971                }
10972            }
10973        }
10974
10975        let mut buffer_paths_registered = Vec::new();
10976        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10977            let mut lsp_adapters = HashMap::default();
10978            for buffer_handle in buffer_store.buffers() {
10979                let buffer = buffer_handle.read(cx);
10980                let file = match File::from_dyn(buffer.file()) {
10981                    Some(file) => file,
10982                    None => continue,
10983                };
10984                let language = match buffer.language() {
10985                    Some(language) => language,
10986                    None => continue,
10987                };
10988
10989                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10990                    || !lsp_adapters
10991                        .entry(language.name())
10992                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
10993                        .iter()
10994                        .any(|a| a.name == key.name)
10995                {
10996                    continue;
10997                }
10998                // didOpen
10999                let file = match file.as_local() {
11000                    Some(file) => file,
11001                    None => continue,
11002                };
11003
11004                let local = self.as_local_mut().unwrap();
11005
11006                let buffer_id = buffer.remote_id();
11007                if local.registered_buffers.contains_key(&buffer_id) {
11008                    let versions = local
11009                        .buffer_snapshots
11010                        .entry(buffer_id)
11011                        .or_default()
11012                        .entry(server_id)
11013                        .and_modify(|_| {
11014                            assert!(
11015                            false,
11016                            "There should not be an existing snapshot for a newly inserted buffer"
11017                        )
11018                        })
11019                        .or_insert_with(|| {
11020                            vec![LspBufferSnapshot {
11021                                version: 0,
11022                                snapshot: buffer.text_snapshot(),
11023                            }]
11024                        });
11025
11026                    let snapshot = versions.last().unwrap();
11027                    let version = snapshot.version;
11028                    let initial_snapshot = &snapshot.snapshot;
11029                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11030                    language_server.register_buffer(
11031                        uri,
11032                        adapter.language_id(&language.name()),
11033                        version,
11034                        initial_snapshot.text(),
11035                    );
11036                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11037                    local
11038                        .buffers_opened_in_servers
11039                        .entry(buffer_id)
11040                        .or_default()
11041                        .insert(server_id);
11042                }
11043                buffer_handle.update(cx, |buffer, cx| {
11044                    buffer.set_completion_triggers(
11045                        server_id,
11046                        language_server
11047                            .capabilities()
11048                            .completion_provider
11049                            .as_ref()
11050                            .and_then(|provider| {
11051                                provider
11052                                    .trigger_characters
11053                                    .as_ref()
11054                                    .map(|characters| characters.iter().cloned().collect())
11055                            })
11056                            .unwrap_or_default(),
11057                        cx,
11058                    )
11059                });
11060            }
11061        });
11062
11063        for (buffer_id, abs_path) in buffer_paths_registered {
11064            cx.emit(LspStoreEvent::LanguageServerUpdate {
11065                language_server_id: server_id,
11066                name: Some(adapter.name()),
11067                message: proto::update_language_server::Variant::RegisteredForBuffer(
11068                    proto::RegisteredForBuffer {
11069                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11070                        buffer_id: buffer_id.to_proto(),
11071                    },
11072                ),
11073            });
11074        }
11075
11076        cx.notify();
11077    }
11078
11079    pub fn language_servers_running_disk_based_diagnostics(
11080        &self,
11081    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11082        self.language_server_statuses
11083            .iter()
11084            .filter_map(|(id, status)| {
11085                if status.has_pending_diagnostic_updates {
11086                    Some(*id)
11087                } else {
11088                    None
11089                }
11090            })
11091    }
11092
11093    pub(crate) fn cancel_language_server_work_for_buffers(
11094        &mut self,
11095        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11096        cx: &mut Context<Self>,
11097    ) {
11098        if let Some((client, project_id)) = self.upstream_client() {
11099            let request = client.request(proto::CancelLanguageServerWork {
11100                project_id,
11101                work: Some(proto::cancel_language_server_work::Work::Buffers(
11102                    proto::cancel_language_server_work::Buffers {
11103                        buffer_ids: buffers
11104                            .into_iter()
11105                            .map(|b| b.read(cx).remote_id().to_proto())
11106                            .collect(),
11107                    },
11108                )),
11109            });
11110            cx.background_spawn(request).detach_and_log_err(cx);
11111        } else if let Some(local) = self.as_local() {
11112            let servers = buffers
11113                .into_iter()
11114                .flat_map(|buffer| {
11115                    buffer.update(cx, |buffer, cx| {
11116                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11117                    })
11118                })
11119                .collect::<HashSet<_>>();
11120            for server_id in servers {
11121                self.cancel_language_server_work(server_id, None, cx);
11122            }
11123        }
11124    }
11125
11126    pub(crate) fn cancel_language_server_work(
11127        &mut self,
11128        server_id: LanguageServerId,
11129        token_to_cancel: Option<String>,
11130        cx: &mut Context<Self>,
11131    ) {
11132        if let Some(local) = self.as_local() {
11133            let status = self.language_server_statuses.get(&server_id);
11134            let server = local.language_servers.get(&server_id);
11135            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11136            {
11137                for (token, progress) in &status.pending_work {
11138                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11139                        && token != token_to_cancel
11140                    {
11141                        continue;
11142                    }
11143                    if progress.is_cancellable {
11144                        server
11145                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11146                                WorkDoneProgressCancelParams {
11147                                    token: lsp::NumberOrString::String(token.clone()),
11148                                },
11149                            )
11150                            .ok();
11151                    }
11152                }
11153            }
11154        } else if let Some((client, project_id)) = self.upstream_client() {
11155            let request = client.request(proto::CancelLanguageServerWork {
11156                project_id,
11157                work: Some(
11158                    proto::cancel_language_server_work::Work::LanguageServerWork(
11159                        proto::cancel_language_server_work::LanguageServerWork {
11160                            language_server_id: server_id.to_proto(),
11161                            token: token_to_cancel,
11162                        },
11163                    ),
11164                ),
11165            });
11166            cx.background_spawn(request).detach_and_log_err(cx);
11167        }
11168    }
11169
11170    fn register_supplementary_language_server(
11171        &mut self,
11172        id: LanguageServerId,
11173        name: LanguageServerName,
11174        server: Arc<LanguageServer>,
11175        cx: &mut Context<Self>,
11176    ) {
11177        if let Some(local) = self.as_local_mut() {
11178            local
11179                .supplementary_language_servers
11180                .insert(id, (name.clone(), server));
11181            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11182        }
11183    }
11184
11185    fn unregister_supplementary_language_server(
11186        &mut self,
11187        id: LanguageServerId,
11188        cx: &mut Context<Self>,
11189    ) {
11190        if let Some(local) = self.as_local_mut() {
11191            local.supplementary_language_servers.remove(&id);
11192            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11193        }
11194    }
11195
11196    pub(crate) fn supplementary_language_servers(
11197        &self,
11198    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11199        self.as_local().into_iter().flat_map(|local| {
11200            local
11201                .supplementary_language_servers
11202                .iter()
11203                .map(|(id, (name, _))| (*id, name.clone()))
11204        })
11205    }
11206
11207    pub fn language_server_adapter_for_id(
11208        &self,
11209        id: LanguageServerId,
11210    ) -> Option<Arc<CachedLspAdapter>> {
11211        self.as_local()
11212            .and_then(|local| local.language_servers.get(&id))
11213            .and_then(|language_server_state| match language_server_state {
11214                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11215                _ => None,
11216            })
11217    }
11218
11219    pub(super) fn update_local_worktree_language_servers(
11220        &mut self,
11221        worktree_handle: &Entity<Worktree>,
11222        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11223        cx: &mut Context<Self>,
11224    ) {
11225        if changes.is_empty() {
11226            return;
11227        }
11228
11229        let Some(local) = self.as_local() else { return };
11230
11231        local.prettier_store.update(cx, |prettier_store, cx| {
11232            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11233        });
11234
11235        let worktree_id = worktree_handle.read(cx).id();
11236        let mut language_server_ids = local
11237            .language_server_ids
11238            .iter()
11239            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11240            .collect::<Vec<_>>();
11241        language_server_ids.sort();
11242        language_server_ids.dedup();
11243
11244        // let abs_path = worktree_handle.read(cx).abs_path();
11245        for server_id in &language_server_ids {
11246            if let Some(LanguageServerState::Running { server, .. }) =
11247                local.language_servers.get(server_id)
11248                && let Some(watched_paths) = local
11249                    .language_server_watched_paths
11250                    .get(server_id)
11251                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11252            {
11253                let params = lsp::DidChangeWatchedFilesParams {
11254                    changes: changes
11255                        .iter()
11256                        .filter_map(|(path, _, change)| {
11257                            if !watched_paths.is_match(path.as_std_path()) {
11258                                return None;
11259                            }
11260                            let typ = match change {
11261                                PathChange::Loaded => return None,
11262                                PathChange::Added => lsp::FileChangeType::CREATED,
11263                                PathChange::Removed => lsp::FileChangeType::DELETED,
11264                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11265                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11266                            };
11267                            let uri = lsp::Uri::from_file_path(
11268                                worktree_handle.read(cx).absolutize(&path),
11269                            )
11270                            .ok()?;
11271                            Some(lsp::FileEvent { uri, typ })
11272                        })
11273                        .collect(),
11274                };
11275                if !params.changes.is_empty() {
11276                    server
11277                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11278                        .ok();
11279                }
11280            }
11281        }
11282        for (path, _, _) in changes {
11283            if let Some(file_name) = path.file_name()
11284                && local.watched_manifest_filenames.contains(file_name)
11285            {
11286                self.request_workspace_config_refresh();
11287                break;
11288            }
11289        }
11290    }
11291
11292    pub fn wait_for_remote_buffer(
11293        &mut self,
11294        id: BufferId,
11295        cx: &mut Context<Self>,
11296    ) -> Task<Result<Entity<Buffer>>> {
11297        self.buffer_store.update(cx, |buffer_store, cx| {
11298            buffer_store.wait_for_remote_buffer(id, cx)
11299        })
11300    }
11301
11302    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11303        let mut result = proto::Symbol {
11304            language_server_name: symbol.language_server_name.0.to_string(),
11305            source_worktree_id: symbol.source_worktree_id.to_proto(),
11306            language_server_id: symbol.source_language_server_id.to_proto(),
11307            name: symbol.name.clone(),
11308            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11309            start: Some(proto::PointUtf16 {
11310                row: symbol.range.start.0.row,
11311                column: symbol.range.start.0.column,
11312            }),
11313            end: Some(proto::PointUtf16 {
11314                row: symbol.range.end.0.row,
11315                column: symbol.range.end.0.column,
11316            }),
11317            worktree_id: Default::default(),
11318            path: Default::default(),
11319            signature: Default::default(),
11320        };
11321        match &symbol.path {
11322            SymbolLocation::InProject(path) => {
11323                result.worktree_id = path.worktree_id.to_proto();
11324                result.path = path.path.to_proto();
11325            }
11326            SymbolLocation::OutsideProject {
11327                abs_path,
11328                signature,
11329            } => {
11330                result.path = abs_path.to_string_lossy().into_owned();
11331                result.signature = signature.to_vec();
11332            }
11333        }
11334        result
11335    }
11336
11337    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11338        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11339        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11340        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11341
11342        let path = if serialized_symbol.signature.is_empty() {
11343            SymbolLocation::InProject(ProjectPath {
11344                worktree_id,
11345                path: RelPath::from_proto(&serialized_symbol.path)
11346                    .context("invalid symbol path")?,
11347            })
11348        } else {
11349            SymbolLocation::OutsideProject {
11350                abs_path: Path::new(&serialized_symbol.path).into(),
11351                signature: serialized_symbol
11352                    .signature
11353                    .try_into()
11354                    .map_err(|_| anyhow!("invalid signature"))?,
11355            }
11356        };
11357
11358        let start = serialized_symbol.start.context("invalid start")?;
11359        let end = serialized_symbol.end.context("invalid end")?;
11360        Ok(CoreSymbol {
11361            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11362            source_worktree_id,
11363            source_language_server_id: LanguageServerId::from_proto(
11364                serialized_symbol.language_server_id,
11365            ),
11366            path,
11367            name: serialized_symbol.name,
11368            range: Unclipped(PointUtf16::new(start.row, start.column))
11369                ..Unclipped(PointUtf16::new(end.row, end.column)),
11370            kind,
11371        })
11372    }
11373
11374    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11375        let mut serialized_completion = proto::Completion {
11376            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11377            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11378            new_text: completion.new_text.clone(),
11379            ..proto::Completion::default()
11380        };
11381        match &completion.source {
11382            CompletionSource::Lsp {
11383                insert_range,
11384                server_id,
11385                lsp_completion,
11386                lsp_defaults,
11387                resolved,
11388            } => {
11389                let (old_insert_start, old_insert_end) = insert_range
11390                    .as_ref()
11391                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11392                    .unzip();
11393
11394                serialized_completion.old_insert_start = old_insert_start;
11395                serialized_completion.old_insert_end = old_insert_end;
11396                serialized_completion.source = proto::completion::Source::Lsp as i32;
11397                serialized_completion.server_id = server_id.0 as u64;
11398                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11399                serialized_completion.lsp_defaults = lsp_defaults
11400                    .as_deref()
11401                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11402                serialized_completion.resolved = *resolved;
11403            }
11404            CompletionSource::BufferWord {
11405                word_range,
11406                resolved,
11407            } => {
11408                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11409                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11410                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11411                serialized_completion.resolved = *resolved;
11412            }
11413            CompletionSource::Custom => {
11414                serialized_completion.source = proto::completion::Source::Custom as i32;
11415                serialized_completion.resolved = true;
11416            }
11417            CompletionSource::Dap { sort_text } => {
11418                serialized_completion.source = proto::completion::Source::Dap as i32;
11419                serialized_completion.sort_text = Some(sort_text.clone());
11420            }
11421        }
11422
11423        serialized_completion
11424    }
11425
11426    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11427        let old_replace_start = completion
11428            .old_replace_start
11429            .and_then(deserialize_anchor)
11430            .context("invalid old start")?;
11431        let old_replace_end = completion
11432            .old_replace_end
11433            .and_then(deserialize_anchor)
11434            .context("invalid old end")?;
11435        let insert_range = {
11436            match completion.old_insert_start.zip(completion.old_insert_end) {
11437                Some((start, end)) => {
11438                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11439                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11440                    Some(start..end)
11441                }
11442                None => None,
11443            }
11444        };
11445        Ok(CoreCompletion {
11446            replace_range: old_replace_start..old_replace_end,
11447            new_text: completion.new_text,
11448            source: match proto::completion::Source::from_i32(completion.source) {
11449                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11450                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11451                    insert_range,
11452                    server_id: LanguageServerId::from_proto(completion.server_id),
11453                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11454                    lsp_defaults: completion
11455                        .lsp_defaults
11456                        .as_deref()
11457                        .map(serde_json::from_slice)
11458                        .transpose()?,
11459                    resolved: completion.resolved,
11460                },
11461                Some(proto::completion::Source::BufferWord) => {
11462                    let word_range = completion
11463                        .buffer_word_start
11464                        .and_then(deserialize_anchor)
11465                        .context("invalid buffer word start")?
11466                        ..completion
11467                            .buffer_word_end
11468                            .and_then(deserialize_anchor)
11469                            .context("invalid buffer word end")?;
11470                    CompletionSource::BufferWord {
11471                        word_range,
11472                        resolved: completion.resolved,
11473                    }
11474                }
11475                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11476                    sort_text: completion
11477                        .sort_text
11478                        .context("expected sort text to exist")?,
11479                },
11480                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11481            },
11482        })
11483    }
11484
11485    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11486        let (kind, lsp_action) = match &action.lsp_action {
11487            LspAction::Action(code_action) => (
11488                proto::code_action::Kind::Action as i32,
11489                serde_json::to_vec(code_action).unwrap(),
11490            ),
11491            LspAction::Command(command) => (
11492                proto::code_action::Kind::Command as i32,
11493                serde_json::to_vec(command).unwrap(),
11494            ),
11495            LspAction::CodeLens(code_lens) => (
11496                proto::code_action::Kind::CodeLens as i32,
11497                serde_json::to_vec(code_lens).unwrap(),
11498            ),
11499        };
11500
11501        proto::CodeAction {
11502            server_id: action.server_id.0 as u64,
11503            start: Some(serialize_anchor(&action.range.start)),
11504            end: Some(serialize_anchor(&action.range.end)),
11505            lsp_action,
11506            kind,
11507            resolved: action.resolved,
11508        }
11509    }
11510
11511    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11512        let start = action
11513            .start
11514            .and_then(deserialize_anchor)
11515            .context("invalid start")?;
11516        let end = action
11517            .end
11518            .and_then(deserialize_anchor)
11519            .context("invalid end")?;
11520        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11521            Some(proto::code_action::Kind::Action) => {
11522                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11523            }
11524            Some(proto::code_action::Kind::Command) => {
11525                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11526            }
11527            Some(proto::code_action::Kind::CodeLens) => {
11528                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11529            }
11530            None => anyhow::bail!("Unknown action kind {}", action.kind),
11531        };
11532        Ok(CodeAction {
11533            server_id: LanguageServerId(action.server_id as usize),
11534            range: start..end,
11535            resolved: action.resolved,
11536            lsp_action,
11537        })
11538    }
11539
11540    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11541        match &formatting_result {
11542            Ok(_) => self.last_formatting_failure = None,
11543            Err(error) => {
11544                let error_string = format!("{error:#}");
11545                log::error!("Formatting failed: {error_string}");
11546                self.last_formatting_failure
11547                    .replace(error_string.lines().join(" "));
11548            }
11549        }
11550    }
11551
11552    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11553        self.lsp_server_capabilities.remove(&for_server);
11554        for lsp_data in self.lsp_data.values_mut() {
11555            lsp_data.remove_server_data(for_server);
11556        }
11557        if let Some(local) = self.as_local_mut() {
11558            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11559            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11560                buffer_servers.remove(&for_server);
11561            }
11562        }
11563    }
11564
11565    pub fn result_id(
11566        &self,
11567        server_id: LanguageServerId,
11568        buffer_id: BufferId,
11569        cx: &App,
11570    ) -> Option<String> {
11571        let abs_path = self
11572            .buffer_store
11573            .read(cx)
11574            .get(buffer_id)
11575            .and_then(|b| File::from_dyn(b.read(cx).file()))
11576            .map(|f| f.abs_path(cx))?;
11577        self.as_local()?
11578            .buffer_pull_diagnostics_result_ids
11579            .get(&server_id)?
11580            .get(&abs_path)?
11581            .clone()
11582    }
11583
11584    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11585        let Some(local) = self.as_local() else {
11586            return HashMap::default();
11587        };
11588        local
11589            .buffer_pull_diagnostics_result_ids
11590            .get(&server_id)
11591            .into_iter()
11592            .flatten()
11593            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11594            .collect()
11595    }
11596
11597    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11598        if let Some(LanguageServerState::Running {
11599            workspace_diagnostics_refresh_tasks,
11600            ..
11601        }) = self
11602            .as_local_mut()
11603            .and_then(|local| local.language_servers.get_mut(&server_id))
11604        {
11605            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11606                diagnostics.refresh_tx.try_send(()).ok();
11607            }
11608        }
11609    }
11610
11611    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11612        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11613            return;
11614        };
11615        let Some(local) = self.as_local_mut() else {
11616            return;
11617        };
11618
11619        for server_id in buffer.update(cx, |buffer, cx| {
11620            local.language_server_ids_for_buffer(buffer, cx)
11621        }) {
11622            if let Some(LanguageServerState::Running {
11623                workspace_diagnostics_refresh_tasks,
11624                ..
11625            }) = local.language_servers.get_mut(&server_id)
11626            {
11627                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11628                    diagnostics.refresh_tx.try_send(()).ok();
11629                }
11630            }
11631        }
11632    }
11633
11634    fn apply_workspace_diagnostic_report(
11635        &mut self,
11636        server_id: LanguageServerId,
11637        report: lsp::WorkspaceDiagnosticReportResult,
11638        cx: &mut Context<Self>,
11639    ) {
11640        let workspace_diagnostics =
11641            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11642        let mut unchanged_buffers = HashSet::default();
11643        let mut changed_buffers = HashSet::default();
11644        let workspace_diagnostics_updates = workspace_diagnostics
11645            .into_iter()
11646            .filter_map(
11647                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11648                    LspPullDiagnostics::Response {
11649                        server_id,
11650                        uri,
11651                        diagnostics,
11652                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11653                    LspPullDiagnostics::Default => None,
11654                },
11655            )
11656            .fold(
11657                HashMap::default(),
11658                |mut acc, (server_id, uri, diagnostics, version)| {
11659                    let (result_id, diagnostics) = match diagnostics {
11660                        PulledDiagnostics::Unchanged { result_id } => {
11661                            unchanged_buffers.insert(uri.clone());
11662                            (Some(result_id), Vec::new())
11663                        }
11664                        PulledDiagnostics::Changed {
11665                            result_id,
11666                            diagnostics,
11667                        } => {
11668                            changed_buffers.insert(uri.clone());
11669                            (result_id, diagnostics)
11670                        }
11671                    };
11672                    let disk_based_sources = Cow::Owned(
11673                        self.language_server_adapter_for_id(server_id)
11674                            .as_ref()
11675                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11676                            .unwrap_or(&[])
11677                            .to_vec(),
11678                    );
11679                    acc.entry(server_id)
11680                        .or_insert_with(Vec::new)
11681                        .push(DocumentDiagnosticsUpdate {
11682                            server_id,
11683                            diagnostics: lsp::PublishDiagnosticsParams {
11684                                uri,
11685                                diagnostics,
11686                                version,
11687                            },
11688                            result_id,
11689                            disk_based_sources,
11690                        });
11691                    acc
11692                },
11693            );
11694
11695        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11696            self.merge_lsp_diagnostics(
11697                DiagnosticSourceKind::Pulled,
11698                diagnostic_updates,
11699                |buffer, old_diagnostic, cx| {
11700                    File::from_dyn(buffer.file())
11701                        .and_then(|file| {
11702                            let abs_path = file.as_local()?.abs_path(cx);
11703                            lsp::Uri::from_file_path(abs_path).ok()
11704                        })
11705                        .is_none_or(|buffer_uri| {
11706                            unchanged_buffers.contains(&buffer_uri)
11707                                || match old_diagnostic.source_kind {
11708                                    DiagnosticSourceKind::Pulled => {
11709                                        !changed_buffers.contains(&buffer_uri)
11710                                    }
11711                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11712                                        true
11713                                    }
11714                                }
11715                        })
11716                },
11717                cx,
11718            )
11719            .log_err();
11720        }
11721    }
11722
11723    fn register_server_capabilities(
11724        &mut self,
11725        server_id: LanguageServerId,
11726        params: lsp::RegistrationParams,
11727        cx: &mut Context<Self>,
11728    ) -> anyhow::Result<()> {
11729        let server = self
11730            .language_server_for_id(server_id)
11731            .with_context(|| format!("no server {server_id} found"))?;
11732        for reg in params.registrations {
11733            match reg.method.as_str() {
11734                "workspace/didChangeWatchedFiles" => {
11735                    if let Some(options) = reg.register_options {
11736                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11737                            let caps = serde_json::from_value(options)?;
11738                            local_lsp_store
11739                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11740                            true
11741                        } else {
11742                            false
11743                        };
11744                        if notify {
11745                            notify_server_capabilities_updated(&server, cx);
11746                        }
11747                    }
11748                }
11749                "workspace/didChangeConfiguration" => {
11750                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11751                }
11752                "workspace/didChangeWorkspaceFolders" => {
11753                    // In this case register options is an empty object, we can ignore it
11754                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11755                        supported: Some(true),
11756                        change_notifications: Some(OneOf::Right(reg.id)),
11757                    };
11758                    server.update_capabilities(|capabilities| {
11759                        capabilities
11760                            .workspace
11761                            .get_or_insert_default()
11762                            .workspace_folders = Some(caps);
11763                    });
11764                    notify_server_capabilities_updated(&server, cx);
11765                }
11766                "workspace/symbol" => {
11767                    let options = parse_register_capabilities(reg)?;
11768                    server.update_capabilities(|capabilities| {
11769                        capabilities.workspace_symbol_provider = Some(options);
11770                    });
11771                    notify_server_capabilities_updated(&server, cx);
11772                }
11773                "workspace/fileOperations" => {
11774                    if let Some(options) = reg.register_options {
11775                        let caps = serde_json::from_value(options)?;
11776                        server.update_capabilities(|capabilities| {
11777                            capabilities
11778                                .workspace
11779                                .get_or_insert_default()
11780                                .file_operations = Some(caps);
11781                        });
11782                        notify_server_capabilities_updated(&server, cx);
11783                    }
11784                }
11785                "workspace/executeCommand" => {
11786                    if let Some(options) = reg.register_options {
11787                        let options = serde_json::from_value(options)?;
11788                        server.update_capabilities(|capabilities| {
11789                            capabilities.execute_command_provider = Some(options);
11790                        });
11791                        notify_server_capabilities_updated(&server, cx);
11792                    }
11793                }
11794                "textDocument/rangeFormatting" => {
11795                    let options = parse_register_capabilities(reg)?;
11796                    server.update_capabilities(|capabilities| {
11797                        capabilities.document_range_formatting_provider = Some(options);
11798                    });
11799                    notify_server_capabilities_updated(&server, cx);
11800                }
11801                "textDocument/onTypeFormatting" => {
11802                    if let Some(options) = reg
11803                        .register_options
11804                        .map(serde_json::from_value)
11805                        .transpose()?
11806                    {
11807                        server.update_capabilities(|capabilities| {
11808                            capabilities.document_on_type_formatting_provider = Some(options);
11809                        });
11810                        notify_server_capabilities_updated(&server, cx);
11811                    }
11812                }
11813                "textDocument/formatting" => {
11814                    let options = parse_register_capabilities(reg)?;
11815                    server.update_capabilities(|capabilities| {
11816                        capabilities.document_formatting_provider = Some(options);
11817                    });
11818                    notify_server_capabilities_updated(&server, cx);
11819                }
11820                "textDocument/rename" => {
11821                    let options = parse_register_capabilities(reg)?;
11822                    server.update_capabilities(|capabilities| {
11823                        capabilities.rename_provider = Some(options);
11824                    });
11825                    notify_server_capabilities_updated(&server, cx);
11826                }
11827                "textDocument/inlayHint" => {
11828                    let options = parse_register_capabilities(reg)?;
11829                    server.update_capabilities(|capabilities| {
11830                        capabilities.inlay_hint_provider = Some(options);
11831                    });
11832                    notify_server_capabilities_updated(&server, cx);
11833                }
11834                "textDocument/documentSymbol" => {
11835                    let options = parse_register_capabilities(reg)?;
11836                    server.update_capabilities(|capabilities| {
11837                        capabilities.document_symbol_provider = Some(options);
11838                    });
11839                    notify_server_capabilities_updated(&server, cx);
11840                }
11841                "textDocument/codeAction" => {
11842                    let options = parse_register_capabilities(reg)?;
11843                    let provider = match options {
11844                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11845                        OneOf::Right(caps) => caps,
11846                    };
11847                    server.update_capabilities(|capabilities| {
11848                        capabilities.code_action_provider = Some(provider);
11849                    });
11850                    notify_server_capabilities_updated(&server, cx);
11851                }
11852                "textDocument/definition" => {
11853                    let options = parse_register_capabilities(reg)?;
11854                    server.update_capabilities(|capabilities| {
11855                        capabilities.definition_provider = Some(options);
11856                    });
11857                    notify_server_capabilities_updated(&server, cx);
11858                }
11859                "textDocument/completion" => {
11860                    if let Some(caps) = reg
11861                        .register_options
11862                        .map(serde_json::from_value)
11863                        .transpose()?
11864                    {
11865                        server.update_capabilities(|capabilities| {
11866                            capabilities.completion_provider = Some(caps);
11867                        });
11868                        notify_server_capabilities_updated(&server, cx);
11869                    }
11870                }
11871                "textDocument/hover" => {
11872                    let options = parse_register_capabilities(reg)?;
11873                    let provider = match options {
11874                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11875                        OneOf::Right(caps) => caps,
11876                    };
11877                    server.update_capabilities(|capabilities| {
11878                        capabilities.hover_provider = Some(provider);
11879                    });
11880                    notify_server_capabilities_updated(&server, cx);
11881                }
11882                "textDocument/signatureHelp" => {
11883                    if let Some(caps) = reg
11884                        .register_options
11885                        .map(serde_json::from_value)
11886                        .transpose()?
11887                    {
11888                        server.update_capabilities(|capabilities| {
11889                            capabilities.signature_help_provider = Some(caps);
11890                        });
11891                        notify_server_capabilities_updated(&server, cx);
11892                    }
11893                }
11894                "textDocument/didChange" => {
11895                    if let Some(sync_kind) = reg
11896                        .register_options
11897                        .and_then(|opts| opts.get("syncKind").cloned())
11898                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11899                        .transpose()?
11900                    {
11901                        server.update_capabilities(|capabilities| {
11902                            let mut sync_options =
11903                                Self::take_text_document_sync_options(capabilities);
11904                            sync_options.change = Some(sync_kind);
11905                            capabilities.text_document_sync =
11906                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11907                        });
11908                        notify_server_capabilities_updated(&server, cx);
11909                    }
11910                }
11911                "textDocument/didSave" => {
11912                    if let Some(include_text) = reg
11913                        .register_options
11914                        .map(|opts| {
11915                            let transpose = opts
11916                                .get("includeText")
11917                                .cloned()
11918                                .map(serde_json::from_value::<Option<bool>>)
11919                                .transpose();
11920                            match transpose {
11921                                Ok(value) => Ok(value.flatten()),
11922                                Err(e) => Err(e),
11923                            }
11924                        })
11925                        .transpose()?
11926                    {
11927                        server.update_capabilities(|capabilities| {
11928                            let mut sync_options =
11929                                Self::take_text_document_sync_options(capabilities);
11930                            sync_options.save =
11931                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11932                                    include_text,
11933                                }));
11934                            capabilities.text_document_sync =
11935                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11936                        });
11937                        notify_server_capabilities_updated(&server, cx);
11938                    }
11939                }
11940                "textDocument/codeLens" => {
11941                    if let Some(caps) = reg
11942                        .register_options
11943                        .map(serde_json::from_value)
11944                        .transpose()?
11945                    {
11946                        server.update_capabilities(|capabilities| {
11947                            capabilities.code_lens_provider = Some(caps);
11948                        });
11949                        notify_server_capabilities_updated(&server, cx);
11950                    }
11951                }
11952                "textDocument/diagnostic" => {
11953                    if let Some(caps) = reg
11954                        .register_options
11955                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
11956                        .transpose()?
11957                    {
11958                        let local = self
11959                            .as_local_mut()
11960                            .context("Expected LSP Store to be local")?;
11961                        let state = local
11962                            .language_servers
11963                            .get_mut(&server_id)
11964                            .context("Could not obtain Language Servers state")?;
11965                        local
11966                            .language_server_dynamic_registrations
11967                            .get_mut(&server_id)
11968                            .and_then(|registrations| {
11969                                registrations
11970                                    .diagnostics
11971                                    .insert(Some(reg.id.clone()), caps.clone())
11972                            });
11973
11974                        let mut can_now_provide_diagnostics = false;
11975                        if let LanguageServerState::Running {
11976                            workspace_diagnostics_refresh_tasks,
11977                            ..
11978                        } = state
11979                            && let Some(task) = lsp_workspace_diagnostics_refresh(
11980                                Some(reg.id.clone()),
11981                                caps.clone(),
11982                                server.clone(),
11983                                cx,
11984                            )
11985                        {
11986                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
11987                            can_now_provide_diagnostics = true;
11988                        }
11989
11990                        // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
11991                        // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
11992                        // as it'll think that they're not supported.
11993                        if can_now_provide_diagnostics {
11994                            server.update_capabilities(|capabilities| {
11995                                debug_assert!(capabilities.diagnostic_provider.is_none());
11996                                capabilities.diagnostic_provider = Some(caps);
11997                            });
11998                        }
11999
12000                        notify_server_capabilities_updated(&server, cx);
12001                    }
12002                }
12003                "textDocument/documentColor" => {
12004                    let options = parse_register_capabilities(reg)?;
12005                    let provider = match options {
12006                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12007                        OneOf::Right(caps) => caps,
12008                    };
12009                    server.update_capabilities(|capabilities| {
12010                        capabilities.color_provider = Some(provider);
12011                    });
12012                    notify_server_capabilities_updated(&server, cx);
12013                }
12014                _ => log::warn!("unhandled capability registration: {reg:?}"),
12015            }
12016        }
12017
12018        Ok(())
12019    }
12020
12021    fn unregister_server_capabilities(
12022        &mut self,
12023        server_id: LanguageServerId,
12024        params: lsp::UnregistrationParams,
12025        cx: &mut Context<Self>,
12026    ) -> anyhow::Result<()> {
12027        let server = self
12028            .language_server_for_id(server_id)
12029            .with_context(|| format!("no server {server_id} found"))?;
12030        for unreg in params.unregisterations.iter() {
12031            match unreg.method.as_str() {
12032                "workspace/didChangeWatchedFiles" => {
12033                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12034                        local_lsp_store
12035                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12036                        true
12037                    } else {
12038                        false
12039                    };
12040                    if notify {
12041                        notify_server_capabilities_updated(&server, cx);
12042                    }
12043                }
12044                "workspace/didChangeConfiguration" => {
12045                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12046                }
12047                "workspace/didChangeWorkspaceFolders" => {
12048                    server.update_capabilities(|capabilities| {
12049                        capabilities
12050                            .workspace
12051                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12052                                workspace_folders: None,
12053                                file_operations: None,
12054                            })
12055                            .workspace_folders = None;
12056                    });
12057                    notify_server_capabilities_updated(&server, cx);
12058                }
12059                "workspace/symbol" => {
12060                    server.update_capabilities(|capabilities| {
12061                        capabilities.workspace_symbol_provider = None
12062                    });
12063                    notify_server_capabilities_updated(&server, cx);
12064                }
12065                "workspace/fileOperations" => {
12066                    server.update_capabilities(|capabilities| {
12067                        capabilities
12068                            .workspace
12069                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12070                                workspace_folders: None,
12071                                file_operations: None,
12072                            })
12073                            .file_operations = None;
12074                    });
12075                    notify_server_capabilities_updated(&server, cx);
12076                }
12077                "workspace/executeCommand" => {
12078                    server.update_capabilities(|capabilities| {
12079                        capabilities.execute_command_provider = None;
12080                    });
12081                    notify_server_capabilities_updated(&server, cx);
12082                }
12083                "textDocument/rangeFormatting" => {
12084                    server.update_capabilities(|capabilities| {
12085                        capabilities.document_range_formatting_provider = None
12086                    });
12087                    notify_server_capabilities_updated(&server, cx);
12088                }
12089                "textDocument/onTypeFormatting" => {
12090                    server.update_capabilities(|capabilities| {
12091                        capabilities.document_on_type_formatting_provider = None;
12092                    });
12093                    notify_server_capabilities_updated(&server, cx);
12094                }
12095                "textDocument/formatting" => {
12096                    server.update_capabilities(|capabilities| {
12097                        capabilities.document_formatting_provider = None;
12098                    });
12099                    notify_server_capabilities_updated(&server, cx);
12100                }
12101                "textDocument/rename" => {
12102                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12103                    notify_server_capabilities_updated(&server, cx);
12104                }
12105                "textDocument/codeAction" => {
12106                    server.update_capabilities(|capabilities| {
12107                        capabilities.code_action_provider = None;
12108                    });
12109                    notify_server_capabilities_updated(&server, cx);
12110                }
12111                "textDocument/definition" => {
12112                    server.update_capabilities(|capabilities| {
12113                        capabilities.definition_provider = None;
12114                    });
12115                    notify_server_capabilities_updated(&server, cx);
12116                }
12117                "textDocument/completion" => {
12118                    server.update_capabilities(|capabilities| {
12119                        capabilities.completion_provider = None;
12120                    });
12121                    notify_server_capabilities_updated(&server, cx);
12122                }
12123                "textDocument/hover" => {
12124                    server.update_capabilities(|capabilities| {
12125                        capabilities.hover_provider = None;
12126                    });
12127                    notify_server_capabilities_updated(&server, cx);
12128                }
12129                "textDocument/signatureHelp" => {
12130                    server.update_capabilities(|capabilities| {
12131                        capabilities.signature_help_provider = None;
12132                    });
12133                    notify_server_capabilities_updated(&server, cx);
12134                }
12135                "textDocument/didChange" => {
12136                    server.update_capabilities(|capabilities| {
12137                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12138                        sync_options.change = None;
12139                        capabilities.text_document_sync =
12140                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12141                    });
12142                    notify_server_capabilities_updated(&server, cx);
12143                }
12144                "textDocument/didSave" => {
12145                    server.update_capabilities(|capabilities| {
12146                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12147                        sync_options.save = None;
12148                        capabilities.text_document_sync =
12149                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12150                    });
12151                    notify_server_capabilities_updated(&server, cx);
12152                }
12153                "textDocument/codeLens" => {
12154                    server.update_capabilities(|capabilities| {
12155                        capabilities.code_lens_provider = None;
12156                    });
12157                    notify_server_capabilities_updated(&server, cx);
12158                }
12159                "textDocument/diagnostic" => {
12160                    let local = self
12161                        .as_local_mut()
12162                        .context("Expected LSP Store to be local")?;
12163
12164                    let state = local
12165                        .language_servers
12166                        .get_mut(&server_id)
12167                        .context("Could not obtain Language Servers state")?;
12168                    let options = local
12169                        .language_server_dynamic_registrations
12170                        .get_mut(&server_id)
12171                        .with_context(|| {
12172                            format!("Expected dynamic registration to exist for server {server_id}")
12173                        })?.diagnostics
12174                        .remove(&Some(unreg.id.clone()))
12175                        .with_context(|| format!(
12176                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12177                            unreg.id)
12178                        )?;
12179
12180                    let mut has_any_diagnostic_providers_still = true;
12181                    if let Some(identifier) = diagnostic_identifier(&options)
12182                        && let LanguageServerState::Running {
12183                            workspace_diagnostics_refresh_tasks,
12184                            ..
12185                        } = state
12186                    {
12187                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12188                        has_any_diagnostic_providers_still =
12189                            !workspace_diagnostics_refresh_tasks.is_empty();
12190                    }
12191
12192                    if !has_any_diagnostic_providers_still {
12193                        server.update_capabilities(|capabilities| {
12194                            debug_assert!(capabilities.diagnostic_provider.is_some());
12195                            capabilities.diagnostic_provider = None;
12196                        });
12197                    }
12198
12199                    notify_server_capabilities_updated(&server, cx);
12200                }
12201                "textDocument/documentColor" => {
12202                    server.update_capabilities(|capabilities| {
12203                        capabilities.color_provider = None;
12204                    });
12205                    notify_server_capabilities_updated(&server, cx);
12206                }
12207                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12208            }
12209        }
12210
12211        Ok(())
12212    }
12213
12214    async fn deduplicate_range_based_lsp_requests<T>(
12215        lsp_store: &Entity<Self>,
12216        server_id: Option<LanguageServerId>,
12217        lsp_request_id: LspRequestId,
12218        proto_request: &T::ProtoRequest,
12219        range: Range<Anchor>,
12220        cx: &mut AsyncApp,
12221    ) -> Result<()>
12222    where
12223        T: LspCommand,
12224        T::ProtoRequest: proto::LspRequestMessage,
12225    {
12226        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12227        let version = deserialize_version(proto_request.buffer_version());
12228        let buffer = lsp_store.update(cx, |this, cx| {
12229            this.buffer_store.read(cx).get_existing(buffer_id)
12230        })??;
12231        buffer
12232            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12233            .await?;
12234        lsp_store.update(cx, |lsp_store, cx| {
12235            let lsp_data = lsp_store
12236                .lsp_data
12237                .entry(buffer_id)
12238                .or_insert_with(|| BufferLspData::new(&buffer, cx));
12239            let chunks_queried_for = lsp_data
12240                .inlay_hints
12241                .applicable_chunks(&[range])
12242                .collect::<Vec<_>>();
12243            match chunks_queried_for.as_slice() {
12244                &[chunk] => {
12245                    let key = LspKey {
12246                        request_type: TypeId::of::<T>(),
12247                        server_queried: server_id,
12248                    };
12249                    let previous_request = lsp_data
12250                        .chunk_lsp_requests
12251                        .entry(key)
12252                        .or_default()
12253                        .insert(chunk, lsp_request_id);
12254                    if let Some((previous_request, running_requests)) =
12255                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12256                    {
12257                        running_requests.remove(&previous_request);
12258                    }
12259                }
12260                _ambiguous_chunks => {
12261                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12262                    // there, a buffer version-based check will be performed and outdated requests discarded.
12263                }
12264            }
12265            anyhow::Ok(())
12266        })??;
12267
12268        Ok(())
12269    }
12270
12271    async fn query_lsp_locally<T>(
12272        lsp_store: Entity<Self>,
12273        for_server_id: Option<LanguageServerId>,
12274        sender_id: proto::PeerId,
12275        lsp_request_id: LspRequestId,
12276        proto_request: T::ProtoRequest,
12277        position: Option<Anchor>,
12278        cx: &mut AsyncApp,
12279    ) -> Result<()>
12280    where
12281        T: LspCommand + Clone,
12282        T::ProtoRequest: proto::LspRequestMessage,
12283        <T::ProtoRequest as proto::RequestMessage>::Response:
12284            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12285    {
12286        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12287        let version = deserialize_version(proto_request.buffer_version());
12288        let buffer = lsp_store.update(cx, |this, cx| {
12289            this.buffer_store.read(cx).get_existing(buffer_id)
12290        })??;
12291        buffer
12292            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12293            .await?;
12294        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12295        let request =
12296            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12297        let key = LspKey {
12298            request_type: TypeId::of::<T>(),
12299            server_queried: for_server_id,
12300        };
12301        lsp_store.update(cx, |lsp_store, cx| {
12302            let request_task = match for_server_id {
12303                Some(server_id) => {
12304                    let server_task = lsp_store.request_lsp(
12305                        buffer.clone(),
12306                        LanguageServerToQuery::Other(server_id),
12307                        request.clone(),
12308                        cx,
12309                    );
12310                    cx.background_spawn(async move {
12311                        let mut responses = Vec::new();
12312                        match server_task.await {
12313                            Ok(response) => responses.push((server_id, response)),
12314                            Err(e) => log::error!(
12315                                "Error handling response for request {request:?}: {e:#}"
12316                            ),
12317                        }
12318                        responses
12319                    })
12320                }
12321                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12322            };
12323            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12324            if T::ProtoRequest::stop_previous_requests() {
12325                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12326                    lsp_requests.clear();
12327                }
12328            }
12329            lsp_data.lsp_requests.entry(key).or_default().insert(
12330                lsp_request_id,
12331                cx.spawn(async move |lsp_store, cx| {
12332                    let response = request_task.await;
12333                    lsp_store
12334                        .update(cx, |lsp_store, cx| {
12335                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12336                            {
12337                                let response = response
12338                                    .into_iter()
12339                                    .map(|(server_id, response)| {
12340                                        (
12341                                            server_id.to_proto(),
12342                                            T::response_to_proto(
12343                                                response,
12344                                                lsp_store,
12345                                                sender_id,
12346                                                &buffer_version,
12347                                                cx,
12348                                            )
12349                                            .into(),
12350                                        )
12351                                    })
12352                                    .collect::<HashMap<_, _>>();
12353                                match client.send_lsp_response::<T::ProtoRequest>(
12354                                    project_id,
12355                                    lsp_request_id,
12356                                    response,
12357                                ) {
12358                                    Ok(()) => {}
12359                                    Err(e) => {
12360                                        log::error!("Failed to send LSP response: {e:#}",)
12361                                    }
12362                                }
12363                            }
12364                        })
12365                        .ok();
12366                }),
12367            );
12368        })?;
12369        Ok(())
12370    }
12371
12372    fn take_text_document_sync_options(
12373        capabilities: &mut lsp::ServerCapabilities,
12374    ) -> lsp::TextDocumentSyncOptions {
12375        match capabilities.text_document_sync.take() {
12376            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12377            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12378                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12379                sync_options.change = Some(sync_kind);
12380                sync_options
12381            }
12382            None => lsp::TextDocumentSyncOptions::default(),
12383        }
12384    }
12385
12386    #[cfg(any(test, feature = "test-support"))]
12387    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12388        Some(
12389            self.lsp_data
12390                .get_mut(&buffer_id)?
12391                .code_lens
12392                .take()?
12393                .update
12394                .take()?
12395                .1,
12396        )
12397    }
12398
12399    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12400        self.downstream_client.clone()
12401    }
12402
12403    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12404        self.worktree_store.clone()
12405    }
12406
12407    /// Gets what's stored in the LSP data for the given buffer.
12408    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12409        self.lsp_data.get_mut(&buffer_id)
12410    }
12411
12412    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12413    /// new [`BufferLspData`] will be created to replace the previous state.
12414    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12415        let (buffer_id, buffer_version) =
12416            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12417        let lsp_data = self
12418            .lsp_data
12419            .entry(buffer_id)
12420            .or_insert_with(|| BufferLspData::new(buffer, cx));
12421        if buffer_version.changed_since(&lsp_data.buffer_version) {
12422            *lsp_data = BufferLspData::new(buffer, cx);
12423        }
12424        lsp_data
12425    }
12426}
12427
12428// Registration with registerOptions as null, should fallback to true.
12429// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12430fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12431    reg: lsp::Registration,
12432) -> Result<OneOf<bool, T>> {
12433    Ok(match reg.register_options {
12434        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12435        None => OneOf::Left(true),
12436    })
12437}
12438
12439fn subscribe_to_binary_statuses(
12440    languages: &Arc<LanguageRegistry>,
12441    cx: &mut Context<'_, LspStore>,
12442) -> Task<()> {
12443    let mut server_statuses = languages.language_server_binary_statuses();
12444    cx.spawn(async move |lsp_store, cx| {
12445        while let Some((server_name, binary_status)) = server_statuses.next().await {
12446            if lsp_store
12447                .update(cx, |_, cx| {
12448                    let mut message = None;
12449                    let binary_status = match binary_status {
12450                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12451                        BinaryStatus::CheckingForUpdate => {
12452                            proto::ServerBinaryStatus::CheckingForUpdate
12453                        }
12454                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12455                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12456                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12457                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12458                        BinaryStatus::Failed { error } => {
12459                            message = Some(error);
12460                            proto::ServerBinaryStatus::Failed
12461                        }
12462                    };
12463                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12464                        // Binary updates are about the binary that might not have any language server id at that point.
12465                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12466                        language_server_id: LanguageServerId(0),
12467                        name: Some(server_name),
12468                        message: proto::update_language_server::Variant::StatusUpdate(
12469                            proto::StatusUpdate {
12470                                message,
12471                                status: Some(proto::status_update::Status::Binary(
12472                                    binary_status as i32,
12473                                )),
12474                            },
12475                        ),
12476                    });
12477                })
12478                .is_err()
12479            {
12480                break;
12481            }
12482        }
12483    })
12484}
12485
12486fn lsp_workspace_diagnostics_refresh(
12487    registration_id: Option<String>,
12488    options: DiagnosticServerCapabilities,
12489    server: Arc<LanguageServer>,
12490    cx: &mut Context<'_, LspStore>,
12491) -> Option<WorkspaceRefreshTask> {
12492    let identifier = diagnostic_identifier(&options)?;
12493
12494    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12495    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12496    refresh_tx.try_send(()).ok();
12497
12498    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12499        let mut attempts = 0;
12500        let max_attempts = 50;
12501        let mut requests = 0;
12502
12503        loop {
12504            let Some(()) = refresh_rx.recv().await else {
12505                return;
12506            };
12507
12508            'request: loop {
12509                requests += 1;
12510                if attempts > max_attempts {
12511                    log::error!(
12512                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12513                    );
12514                    return;
12515                }
12516                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12517                cx.background_executor()
12518                    .timer(Duration::from_millis(backoff_millis))
12519                    .await;
12520                attempts += 1;
12521
12522                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12523                    lsp_store
12524                        .all_result_ids(server.server_id())
12525                        .into_iter()
12526                        .filter_map(|(abs_path, result_id)| {
12527                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12528                            Some(lsp::PreviousResultId {
12529                                uri,
12530                                value: result_id,
12531                            })
12532                        })
12533                        .collect()
12534                }) else {
12535                    return;
12536                };
12537
12538                let token = if let Some(identifier) = &registration_id {
12539                    format!(
12540                        "workspace/diagnostic/{}/{requests}/id:{identifier}",
12541                        server.server_id(),
12542                    )
12543                } else {
12544                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12545                };
12546
12547                progress_rx.try_recv().ok();
12548                let timer =
12549                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12550                let progress = pin!(progress_rx.recv().fuse());
12551                let response_result = server
12552                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12553                        lsp::WorkspaceDiagnosticParams {
12554                            previous_result_ids,
12555                            identifier: identifier.clone(),
12556                            work_done_progress_params: Default::default(),
12557                            partial_result_params: lsp::PartialResultParams {
12558                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12559                            },
12560                        },
12561                        select(timer, progress).then(|either| match either {
12562                            Either::Left((message, ..)) => ready(message).left_future(),
12563                            Either::Right(..) => pending::<String>().right_future(),
12564                        }),
12565                    )
12566                    .await;
12567
12568                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12569                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12570                match response_result {
12571                    ConnectionResult::Timeout => {
12572                        log::error!("Timeout during workspace diagnostics pull");
12573                        continue 'request;
12574                    }
12575                    ConnectionResult::ConnectionReset => {
12576                        log::error!("Server closed a workspace diagnostics pull request");
12577                        continue 'request;
12578                    }
12579                    ConnectionResult::Result(Err(e)) => {
12580                        log::error!("Error during workspace diagnostics pull: {e:#}");
12581                        break 'request;
12582                    }
12583                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12584                        attempts = 0;
12585                        if lsp_store
12586                            .update(cx, |lsp_store, cx| {
12587                                lsp_store.apply_workspace_diagnostic_report(
12588                                    server.server_id(),
12589                                    pulled_diagnostics,
12590                                    cx,
12591                                )
12592                            })
12593                            .is_err()
12594                        {
12595                            return;
12596                        }
12597                        break 'request;
12598                    }
12599                }
12600            }
12601        }
12602    });
12603
12604    Some(WorkspaceRefreshTask {
12605        refresh_tx,
12606        progress_tx,
12607        task: workspace_query_language_server,
12608    })
12609}
12610
12611fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12612    match &options {
12613        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12614            if !diagnostic_options.workspace_diagnostics {
12615                return None;
12616            }
12617            Some(diagnostic_options.identifier.clone())
12618        }
12619        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12620            let diagnostic_options = &registration_options.diagnostic_options;
12621            if !diagnostic_options.workspace_diagnostics {
12622                return None;
12623            }
12624            Some(diagnostic_options.identifier.clone())
12625        }
12626    }
12627}
12628
12629fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12630    let CompletionSource::BufferWord {
12631        word_range,
12632        resolved,
12633    } = &mut completion.source
12634    else {
12635        return;
12636    };
12637    if *resolved {
12638        return;
12639    }
12640
12641    if completion.new_text
12642        != snapshot
12643            .text_for_range(word_range.clone())
12644            .collect::<String>()
12645    {
12646        return;
12647    }
12648
12649    let mut offset = 0;
12650    for chunk in snapshot.chunks(word_range.clone(), true) {
12651        let end_offset = offset + chunk.text.len();
12652        if let Some(highlight_id) = chunk.syntax_highlight_id {
12653            completion
12654                .label
12655                .runs
12656                .push((offset..end_offset, highlight_id));
12657        }
12658        offset = end_offset;
12659    }
12660    *resolved = true;
12661}
12662
12663impl EventEmitter<LspStoreEvent> for LspStore {}
12664
12665fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12666    hover
12667        .contents
12668        .retain(|hover_block| !hover_block.text.trim().is_empty());
12669    if hover.contents.is_empty() {
12670        None
12671    } else {
12672        Some(hover)
12673    }
12674}
12675
12676async fn populate_labels_for_completions(
12677    new_completions: Vec<CoreCompletion>,
12678    language: Option<Arc<Language>>,
12679    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12680) -> Vec<Completion> {
12681    let lsp_completions = new_completions
12682        .iter()
12683        .filter_map(|new_completion| {
12684            new_completion
12685                .source
12686                .lsp_completion(true)
12687                .map(|lsp_completion| lsp_completion.into_owned())
12688        })
12689        .collect::<Vec<_>>();
12690
12691    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12692        lsp_adapter
12693            .labels_for_completions(&lsp_completions, language)
12694            .await
12695            .log_err()
12696            .unwrap_or_default()
12697    } else {
12698        Vec::new()
12699    }
12700    .into_iter()
12701    .fuse();
12702
12703    let mut completions = Vec::new();
12704    for completion in new_completions {
12705        match completion.source.lsp_completion(true) {
12706            Some(lsp_completion) => {
12707                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12708
12709                let mut label = labels.next().flatten().unwrap_or_else(|| {
12710                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12711                });
12712                ensure_uniform_list_compatible_label(&mut label);
12713                completions.push(Completion {
12714                    label,
12715                    documentation,
12716                    replace_range: completion.replace_range,
12717                    new_text: completion.new_text,
12718                    insert_text_mode: lsp_completion.insert_text_mode,
12719                    source: completion.source,
12720                    icon_path: None,
12721                    confirm: None,
12722                });
12723            }
12724            None => {
12725                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12726                ensure_uniform_list_compatible_label(&mut label);
12727                completions.push(Completion {
12728                    label,
12729                    documentation: None,
12730                    replace_range: completion.replace_range,
12731                    new_text: completion.new_text,
12732                    source: completion.source,
12733                    insert_text_mode: None,
12734                    icon_path: None,
12735                    confirm: None,
12736                });
12737            }
12738        }
12739    }
12740    completions
12741}
12742
12743#[derive(Debug)]
12744pub enum LanguageServerToQuery {
12745    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12746    FirstCapable,
12747    /// Query a specific language server.
12748    Other(LanguageServerId),
12749}
12750
12751#[derive(Default)]
12752struct RenamePathsWatchedForServer {
12753    did_rename: Vec<RenameActionPredicate>,
12754    will_rename: Vec<RenameActionPredicate>,
12755}
12756
12757impl RenamePathsWatchedForServer {
12758    fn with_did_rename_patterns(
12759        mut self,
12760        did_rename: Option<&FileOperationRegistrationOptions>,
12761    ) -> Self {
12762        if let Some(did_rename) = did_rename {
12763            self.did_rename = did_rename
12764                .filters
12765                .iter()
12766                .filter_map(|filter| filter.try_into().log_err())
12767                .collect();
12768        }
12769        self
12770    }
12771    fn with_will_rename_patterns(
12772        mut self,
12773        will_rename: Option<&FileOperationRegistrationOptions>,
12774    ) -> Self {
12775        if let Some(will_rename) = will_rename {
12776            self.will_rename = will_rename
12777                .filters
12778                .iter()
12779                .filter_map(|filter| filter.try_into().log_err())
12780                .collect();
12781        }
12782        self
12783    }
12784
12785    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12786        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12787    }
12788    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12789        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12790    }
12791}
12792
12793impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12794    type Error = globset::Error;
12795    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12796        Ok(Self {
12797            kind: ops.pattern.matches.clone(),
12798            glob: GlobBuilder::new(&ops.pattern.glob)
12799                .case_insensitive(
12800                    ops.pattern
12801                        .options
12802                        .as_ref()
12803                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12804                )
12805                .build()?
12806                .compile_matcher(),
12807        })
12808    }
12809}
12810struct RenameActionPredicate {
12811    glob: GlobMatcher,
12812    kind: Option<FileOperationPatternKind>,
12813}
12814
12815impl RenameActionPredicate {
12816    // Returns true if language server should be notified
12817    fn eval(&self, path: &str, is_dir: bool) -> bool {
12818        self.kind.as_ref().is_none_or(|kind| {
12819            let expected_kind = if is_dir {
12820                FileOperationPatternKind::Folder
12821            } else {
12822                FileOperationPatternKind::File
12823            };
12824            kind == &expected_kind
12825        }) && self.glob.is_match(path)
12826    }
12827}
12828
12829#[derive(Default)]
12830struct LanguageServerWatchedPaths {
12831    worktree_paths: HashMap<WorktreeId, GlobSet>,
12832    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12833}
12834
12835#[derive(Default)]
12836struct LanguageServerWatchedPathsBuilder {
12837    worktree_paths: HashMap<WorktreeId, GlobSet>,
12838    abs_paths: HashMap<Arc<Path>, GlobSet>,
12839}
12840
12841impl LanguageServerWatchedPathsBuilder {
12842    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12843        self.worktree_paths.insert(worktree_id, glob_set);
12844    }
12845    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12846        self.abs_paths.insert(path, glob_set);
12847    }
12848    fn build(
12849        self,
12850        fs: Arc<dyn Fs>,
12851        language_server_id: LanguageServerId,
12852        cx: &mut Context<LspStore>,
12853    ) -> LanguageServerWatchedPaths {
12854        let project = cx.weak_entity();
12855
12856        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12857        let abs_paths = self
12858            .abs_paths
12859            .into_iter()
12860            .map(|(abs_path, globset)| {
12861                let task = cx.spawn({
12862                    let abs_path = abs_path.clone();
12863                    let fs = fs.clone();
12864
12865                    let lsp_store = project.clone();
12866                    async move |_, cx| {
12867                        maybe!(async move {
12868                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12869                            while let Some(update) = push_updates.0.next().await {
12870                                let action = lsp_store
12871                                    .update(cx, |this, _| {
12872                                        let Some(local) = this.as_local() else {
12873                                            return ControlFlow::Break(());
12874                                        };
12875                                        let Some(watcher) = local
12876                                            .language_server_watched_paths
12877                                            .get(&language_server_id)
12878                                        else {
12879                                            return ControlFlow::Break(());
12880                                        };
12881                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12882                                            "Watched abs path is not registered with a watcher",
12883                                        );
12884                                        let matching_entries = update
12885                                            .into_iter()
12886                                            .filter(|event| globs.is_match(&event.path))
12887                                            .collect::<Vec<_>>();
12888                                        this.lsp_notify_abs_paths_changed(
12889                                            language_server_id,
12890                                            matching_entries,
12891                                        );
12892                                        ControlFlow::Continue(())
12893                                    })
12894                                    .ok()?;
12895
12896                                if action.is_break() {
12897                                    break;
12898                                }
12899                            }
12900                            Some(())
12901                        })
12902                        .await;
12903                    }
12904                });
12905                (abs_path, (globset, task))
12906            })
12907            .collect();
12908        LanguageServerWatchedPaths {
12909            worktree_paths: self.worktree_paths,
12910            abs_paths,
12911        }
12912    }
12913}
12914
12915struct LspBufferSnapshot {
12916    version: i32,
12917    snapshot: TextBufferSnapshot,
12918}
12919
12920/// A prompt requested by LSP server.
12921#[derive(Clone, Debug)]
12922pub struct LanguageServerPromptRequest {
12923    pub level: PromptLevel,
12924    pub message: String,
12925    pub actions: Vec<MessageActionItem>,
12926    pub lsp_name: String,
12927    pub(crate) response_channel: Sender<MessageActionItem>,
12928}
12929
12930impl LanguageServerPromptRequest {
12931    pub async fn respond(self, index: usize) -> Option<()> {
12932        if let Some(response) = self.actions.into_iter().nth(index) {
12933            self.response_channel.send(response).await.ok()
12934        } else {
12935            None
12936        }
12937    }
12938}
12939impl PartialEq for LanguageServerPromptRequest {
12940    fn eq(&self, other: &Self) -> bool {
12941        self.message == other.message && self.actions == other.actions
12942    }
12943}
12944
12945#[derive(Clone, Debug, PartialEq)]
12946pub enum LanguageServerLogType {
12947    Log(MessageType),
12948    Trace { verbose_info: Option<String> },
12949    Rpc { received: bool },
12950}
12951
12952impl LanguageServerLogType {
12953    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12954        match self {
12955            Self::Log(log_type) => {
12956                use proto::log_message::LogLevel;
12957                let level = match *log_type {
12958                    MessageType::ERROR => LogLevel::Error,
12959                    MessageType::WARNING => LogLevel::Warning,
12960                    MessageType::INFO => LogLevel::Info,
12961                    MessageType::LOG => LogLevel::Log,
12962                    other => {
12963                        log::warn!("Unknown lsp log message type: {other:?}");
12964                        LogLevel::Log
12965                    }
12966                };
12967                proto::language_server_log::LogType::Log(proto::LogMessage {
12968                    level: level as i32,
12969                })
12970            }
12971            Self::Trace { verbose_info } => {
12972                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12973                    verbose_info: verbose_info.to_owned(),
12974                })
12975            }
12976            Self::Rpc { received } => {
12977                let kind = if *received {
12978                    proto::rpc_message::Kind::Received
12979                } else {
12980                    proto::rpc_message::Kind::Sent
12981                };
12982                let kind = kind as i32;
12983                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12984            }
12985        }
12986    }
12987
12988    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12989        use proto::log_message::LogLevel;
12990        use proto::rpc_message;
12991        match log_type {
12992            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12993                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12994                    LogLevel::Error => MessageType::ERROR,
12995                    LogLevel::Warning => MessageType::WARNING,
12996                    LogLevel::Info => MessageType::INFO,
12997                    LogLevel::Log => MessageType::LOG,
12998                },
12999            ),
13000            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13001                verbose_info: trace_message.verbose_info,
13002            },
13003            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13004                received: match rpc_message::Kind::from_i32(message.kind)
13005                    .unwrap_or(rpc_message::Kind::Received)
13006                {
13007                    rpc_message::Kind::Received => true,
13008                    rpc_message::Kind::Sent => false,
13009                },
13010            },
13011        }
13012    }
13013}
13014
13015pub struct WorkspaceRefreshTask {
13016    refresh_tx: mpsc::Sender<()>,
13017    progress_tx: mpsc::Sender<()>,
13018    #[allow(dead_code)]
13019    task: Task<()>,
13020}
13021
13022pub enum LanguageServerState {
13023    Starting {
13024        startup: Task<Option<Arc<LanguageServer>>>,
13025        /// List of language servers that will be added to the workspace once it's initialization completes.
13026        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13027    },
13028
13029    Running {
13030        adapter: Arc<CachedLspAdapter>,
13031        server: Arc<LanguageServer>,
13032        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13033        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13034    },
13035}
13036
13037impl LanguageServerState {
13038    fn add_workspace_folder(&self, uri: Uri) {
13039        match self {
13040            LanguageServerState::Starting {
13041                pending_workspace_folders,
13042                ..
13043            } => {
13044                pending_workspace_folders.lock().insert(uri);
13045            }
13046            LanguageServerState::Running { server, .. } => {
13047                server.add_workspace_folder(uri);
13048            }
13049        }
13050    }
13051    fn _remove_workspace_folder(&self, uri: Uri) {
13052        match self {
13053            LanguageServerState::Starting {
13054                pending_workspace_folders,
13055                ..
13056            } => {
13057                pending_workspace_folders.lock().remove(&uri);
13058            }
13059            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13060        }
13061    }
13062}
13063
13064impl std::fmt::Debug for LanguageServerState {
13065    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13066        match self {
13067            LanguageServerState::Starting { .. } => {
13068                f.debug_struct("LanguageServerState::Starting").finish()
13069            }
13070            LanguageServerState::Running { .. } => {
13071                f.debug_struct("LanguageServerState::Running").finish()
13072            }
13073        }
13074    }
13075}
13076
13077#[derive(Clone, Debug, Serialize)]
13078pub struct LanguageServerProgress {
13079    pub is_disk_based_diagnostics_progress: bool,
13080    pub is_cancellable: bool,
13081    pub title: Option<String>,
13082    pub message: Option<String>,
13083    pub percentage: Option<usize>,
13084    #[serde(skip_serializing)]
13085    pub last_update_at: Instant,
13086}
13087
13088#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13089pub struct DiagnosticSummary {
13090    pub error_count: usize,
13091    pub warning_count: usize,
13092}
13093
13094impl DiagnosticSummary {
13095    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13096        let mut this = Self {
13097            error_count: 0,
13098            warning_count: 0,
13099        };
13100
13101        for entry in diagnostics {
13102            if entry.diagnostic.is_primary {
13103                match entry.diagnostic.severity {
13104                    DiagnosticSeverity::ERROR => this.error_count += 1,
13105                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13106                    _ => {}
13107                }
13108            }
13109        }
13110
13111        this
13112    }
13113
13114    pub fn is_empty(&self) -> bool {
13115        self.error_count == 0 && self.warning_count == 0
13116    }
13117
13118    pub fn to_proto(
13119        self,
13120        language_server_id: LanguageServerId,
13121        path: &RelPath,
13122    ) -> proto::DiagnosticSummary {
13123        proto::DiagnosticSummary {
13124            path: path.to_proto(),
13125            language_server_id: language_server_id.0 as u64,
13126            error_count: self.error_count as u32,
13127            warning_count: self.warning_count as u32,
13128        }
13129    }
13130}
13131
13132#[derive(Clone, Debug)]
13133pub enum CompletionDocumentation {
13134    /// There is no documentation for this completion.
13135    Undocumented,
13136    /// A single line of documentation.
13137    SingleLine(SharedString),
13138    /// Multiple lines of plain text documentation.
13139    MultiLinePlainText(SharedString),
13140    /// Markdown documentation.
13141    MultiLineMarkdown(SharedString),
13142    /// Both single line and multiple lines of plain text documentation.
13143    SingleLineAndMultiLinePlainText {
13144        single_line: SharedString,
13145        plain_text: Option<SharedString>,
13146    },
13147}
13148
13149impl CompletionDocumentation {
13150    #[cfg(any(test, feature = "test-support"))]
13151    pub fn text(&self) -> SharedString {
13152        match self {
13153            CompletionDocumentation::Undocumented => "".into(),
13154            CompletionDocumentation::SingleLine(s) => s.clone(),
13155            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13156            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13157            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13158                single_line.clone()
13159            }
13160        }
13161    }
13162}
13163
13164impl From<lsp::Documentation> for CompletionDocumentation {
13165    fn from(docs: lsp::Documentation) -> Self {
13166        match docs {
13167            lsp::Documentation::String(text) => {
13168                if text.lines().count() <= 1 {
13169                    CompletionDocumentation::SingleLine(text.into())
13170                } else {
13171                    CompletionDocumentation::MultiLinePlainText(text.into())
13172                }
13173            }
13174
13175            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13176                lsp::MarkupKind::PlainText => {
13177                    if value.lines().count() <= 1 {
13178                        CompletionDocumentation::SingleLine(value.into())
13179                    } else {
13180                        CompletionDocumentation::MultiLinePlainText(value.into())
13181                    }
13182                }
13183
13184                lsp::MarkupKind::Markdown => {
13185                    CompletionDocumentation::MultiLineMarkdown(value.into())
13186                }
13187            },
13188        }
13189    }
13190}
13191
13192pub enum ResolvedHint {
13193    Resolved(InlayHint),
13194    Resolving(Shared<Task<()>>),
13195}
13196
13197fn glob_literal_prefix(glob: &Path) -> PathBuf {
13198    glob.components()
13199        .take_while(|component| match component {
13200            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13201            _ => true,
13202        })
13203        .collect()
13204}
13205
13206pub struct SshLspAdapter {
13207    name: LanguageServerName,
13208    binary: LanguageServerBinary,
13209    initialization_options: Option<String>,
13210    code_action_kinds: Option<Vec<CodeActionKind>>,
13211}
13212
13213impl SshLspAdapter {
13214    pub fn new(
13215        name: LanguageServerName,
13216        binary: LanguageServerBinary,
13217        initialization_options: Option<String>,
13218        code_action_kinds: Option<String>,
13219    ) -> Self {
13220        Self {
13221            name,
13222            binary,
13223            initialization_options,
13224            code_action_kinds: code_action_kinds
13225                .as_ref()
13226                .and_then(|c| serde_json::from_str(c).ok()),
13227        }
13228    }
13229}
13230
13231impl LspInstaller for SshLspAdapter {
13232    type BinaryVersion = ();
13233    async fn check_if_user_installed(
13234        &self,
13235        _: &dyn LspAdapterDelegate,
13236        _: Option<Toolchain>,
13237        _: &AsyncApp,
13238    ) -> Option<LanguageServerBinary> {
13239        Some(self.binary.clone())
13240    }
13241
13242    async fn cached_server_binary(
13243        &self,
13244        _: PathBuf,
13245        _: &dyn LspAdapterDelegate,
13246    ) -> Option<LanguageServerBinary> {
13247        None
13248    }
13249
13250    async fn fetch_latest_server_version(
13251        &self,
13252        _: &dyn LspAdapterDelegate,
13253        _: bool,
13254        _: &mut AsyncApp,
13255    ) -> Result<()> {
13256        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13257    }
13258
13259    async fn fetch_server_binary(
13260        &self,
13261        _: (),
13262        _: PathBuf,
13263        _: &dyn LspAdapterDelegate,
13264    ) -> Result<LanguageServerBinary> {
13265        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13266    }
13267}
13268
13269#[async_trait(?Send)]
13270impl LspAdapter for SshLspAdapter {
13271    fn name(&self) -> LanguageServerName {
13272        self.name.clone()
13273    }
13274
13275    async fn initialization_options(
13276        self: Arc<Self>,
13277        _: &Arc<dyn LspAdapterDelegate>,
13278    ) -> Result<Option<serde_json::Value>> {
13279        let Some(options) = &self.initialization_options else {
13280            return Ok(None);
13281        };
13282        let result = serde_json::from_str(options)?;
13283        Ok(result)
13284    }
13285
13286    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13287        self.code_action_kinds.clone()
13288    }
13289}
13290
13291pub fn language_server_settings<'a>(
13292    delegate: &'a dyn LspAdapterDelegate,
13293    language: &LanguageServerName,
13294    cx: &'a App,
13295) -> Option<&'a LspSettings> {
13296    language_server_settings_for(
13297        SettingsLocation {
13298            worktree_id: delegate.worktree_id(),
13299            path: RelPath::empty(),
13300        },
13301        language,
13302        cx,
13303    )
13304}
13305
13306pub(crate) fn language_server_settings_for<'a>(
13307    location: SettingsLocation<'a>,
13308    language: &LanguageServerName,
13309    cx: &'a App,
13310) -> Option<&'a LspSettings> {
13311    ProjectSettings::get(Some(location), cx).lsp.get(language)
13312}
13313
13314pub struct LocalLspAdapterDelegate {
13315    lsp_store: WeakEntity<LspStore>,
13316    worktree: worktree::Snapshot,
13317    fs: Arc<dyn Fs>,
13318    http_client: Arc<dyn HttpClient>,
13319    language_registry: Arc<LanguageRegistry>,
13320    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13321}
13322
13323impl LocalLspAdapterDelegate {
13324    pub fn new(
13325        language_registry: Arc<LanguageRegistry>,
13326        environment: &Entity<ProjectEnvironment>,
13327        lsp_store: WeakEntity<LspStore>,
13328        worktree: &Entity<Worktree>,
13329        http_client: Arc<dyn HttpClient>,
13330        fs: Arc<dyn Fs>,
13331        cx: &mut App,
13332    ) -> Arc<Self> {
13333        let load_shell_env_task = environment.update(cx, |env, cx| {
13334            env.get_worktree_environment(worktree.clone(), cx)
13335        });
13336
13337        Arc::new(Self {
13338            lsp_store,
13339            worktree: worktree.read(cx).snapshot(),
13340            fs,
13341            http_client,
13342            language_registry,
13343            load_shell_env_task,
13344        })
13345    }
13346
13347    fn from_local_lsp(
13348        local: &LocalLspStore,
13349        worktree: &Entity<Worktree>,
13350        cx: &mut App,
13351    ) -> Arc<Self> {
13352        Self::new(
13353            local.languages.clone(),
13354            &local.environment,
13355            local.weak.clone(),
13356            worktree,
13357            local.http_client.clone(),
13358            local.fs.clone(),
13359            cx,
13360        )
13361    }
13362}
13363
13364#[async_trait]
13365impl LspAdapterDelegate for LocalLspAdapterDelegate {
13366    fn show_notification(&self, message: &str, cx: &mut App) {
13367        self.lsp_store
13368            .update(cx, |_, cx| {
13369                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13370            })
13371            .ok();
13372    }
13373
13374    fn http_client(&self) -> Arc<dyn HttpClient> {
13375        self.http_client.clone()
13376    }
13377
13378    fn worktree_id(&self) -> WorktreeId {
13379        self.worktree.id()
13380    }
13381
13382    fn worktree_root_path(&self) -> &Path {
13383        self.worktree.abs_path().as_ref()
13384    }
13385
13386    async fn shell_env(&self) -> HashMap<String, String> {
13387        let task = self.load_shell_env_task.clone();
13388        task.await.unwrap_or_default()
13389    }
13390
13391    async fn npm_package_installed_version(
13392        &self,
13393        package_name: &str,
13394    ) -> Result<Option<(PathBuf, String)>> {
13395        let local_package_directory = self.worktree_root_path();
13396        let node_modules_directory = local_package_directory.join("node_modules");
13397
13398        if let Some(version) =
13399            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13400        {
13401            return Ok(Some((node_modules_directory, version)));
13402        }
13403        let Some(npm) = self.which("npm".as_ref()).await else {
13404            log::warn!(
13405                "Failed to find npm executable for {:?}",
13406                local_package_directory
13407            );
13408            return Ok(None);
13409        };
13410
13411        let env = self.shell_env().await;
13412        let output = util::command::new_smol_command(&npm)
13413            .args(["root", "-g"])
13414            .envs(env)
13415            .current_dir(local_package_directory)
13416            .output()
13417            .await?;
13418        let global_node_modules =
13419            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13420
13421        if let Some(version) =
13422            read_package_installed_version(global_node_modules.clone(), package_name).await?
13423        {
13424            return Ok(Some((global_node_modules, version)));
13425        }
13426        return Ok(None);
13427    }
13428
13429    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13430        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13431        if self.fs.is_file(&worktree_abs_path).await {
13432            worktree_abs_path.pop();
13433        }
13434
13435        let env = self.shell_env().await;
13436
13437        let shell_path = env.get("PATH").cloned();
13438
13439        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13440    }
13441
13442    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13443        let mut working_dir = self.worktree_root_path().to_path_buf();
13444        if self.fs.is_file(&working_dir).await {
13445            working_dir.pop();
13446        }
13447        let output = util::command::new_smol_command(&command.path)
13448            .args(command.arguments)
13449            .envs(command.env.clone().unwrap_or_default())
13450            .current_dir(working_dir)
13451            .output()
13452            .await?;
13453
13454        anyhow::ensure!(
13455            output.status.success(),
13456            "{}, stdout: {:?}, stderr: {:?}",
13457            output.status,
13458            String::from_utf8_lossy(&output.stdout),
13459            String::from_utf8_lossy(&output.stderr)
13460        );
13461        Ok(())
13462    }
13463
13464    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13465        self.language_registry
13466            .update_lsp_binary_status(server_name, status);
13467    }
13468
13469    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13470        self.language_registry
13471            .all_lsp_adapters()
13472            .into_iter()
13473            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13474            .collect()
13475    }
13476
13477    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13478        let dir = self.language_registry.language_server_download_dir(name)?;
13479
13480        if !dir.exists() {
13481            smol::fs::create_dir_all(&dir)
13482                .await
13483                .context("failed to create container directory")
13484                .log_err()?;
13485        }
13486
13487        Some(dir)
13488    }
13489
13490    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13491        let entry = self
13492            .worktree
13493            .entry_for_path(path)
13494            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13495        let abs_path = self.worktree.absolutize(&entry.path);
13496        self.fs.load(&abs_path).await
13497    }
13498}
13499
13500async fn populate_labels_for_symbols(
13501    symbols: Vec<CoreSymbol>,
13502    language_registry: &Arc<LanguageRegistry>,
13503    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13504    output: &mut Vec<Symbol>,
13505) {
13506    #[allow(clippy::mutable_key_type)]
13507    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13508
13509    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13510    for symbol in symbols {
13511        let Some(file_name) = symbol.path.file_name() else {
13512            continue;
13513        };
13514        let language = language_registry
13515            .load_language_for_file_path(Path::new(file_name))
13516            .await
13517            .ok()
13518            .or_else(|| {
13519                unknown_paths.insert(file_name.into());
13520                None
13521            });
13522        symbols_by_language
13523            .entry(language)
13524            .or_default()
13525            .push(symbol);
13526    }
13527
13528    for unknown_path in unknown_paths {
13529        log::info!("no language found for symbol in file {unknown_path:?}");
13530    }
13531
13532    let mut label_params = Vec::new();
13533    for (language, mut symbols) in symbols_by_language {
13534        label_params.clear();
13535        label_params.extend(
13536            symbols
13537                .iter_mut()
13538                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13539        );
13540
13541        let mut labels = Vec::new();
13542        if let Some(language) = language {
13543            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13544                language_registry
13545                    .lsp_adapters(&language.name())
13546                    .first()
13547                    .cloned()
13548            });
13549            if let Some(lsp_adapter) = lsp_adapter {
13550                labels = lsp_adapter
13551                    .labels_for_symbols(&label_params, &language)
13552                    .await
13553                    .log_err()
13554                    .unwrap_or_default();
13555            }
13556        }
13557
13558        for ((symbol, (name, _)), label) in symbols
13559            .into_iter()
13560            .zip(label_params.drain(..))
13561            .zip(labels.into_iter().chain(iter::repeat(None)))
13562        {
13563            output.push(Symbol {
13564                language_server_name: symbol.language_server_name,
13565                source_worktree_id: symbol.source_worktree_id,
13566                source_language_server_id: symbol.source_language_server_id,
13567                path: symbol.path,
13568                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13569                name,
13570                kind: symbol.kind,
13571                range: symbol.range,
13572            });
13573        }
13574    }
13575}
13576
13577fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13578    match server.capabilities().text_document_sync.as_ref()? {
13579        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13580            // Server wants didSave but didn't specify includeText.
13581            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13582            // Server doesn't want didSave at all.
13583            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13584            // Server provided SaveOptions.
13585            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13586                Some(save_options.include_text.unwrap_or(false))
13587            }
13588        },
13589        // We do not have any save info. Kind affects didChange only.
13590        lsp::TextDocumentSyncCapability::Kind(_) => None,
13591    }
13592}
13593
13594/// Completion items are displayed in a `UniformList`.
13595/// Usually, those items are single-line strings, but in LSP responses,
13596/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13597/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13598/// 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,
13599/// breaking the completions menu presentation.
13600///
13601/// 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.
13602fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13603    let mut new_text = String::with_capacity(label.text.len());
13604    let mut offset_map = vec![0; label.text.len() + 1];
13605    let mut last_char_was_space = false;
13606    let mut new_idx = 0;
13607    let chars = label.text.char_indices().fuse();
13608    let mut newlines_removed = false;
13609
13610    for (idx, c) in chars {
13611        offset_map[idx] = new_idx;
13612
13613        match c {
13614            '\n' if last_char_was_space => {
13615                newlines_removed = true;
13616            }
13617            '\t' | ' ' if last_char_was_space => {}
13618            '\n' if !last_char_was_space => {
13619                new_text.push(' ');
13620                new_idx += 1;
13621                last_char_was_space = true;
13622                newlines_removed = true;
13623            }
13624            ' ' | '\t' => {
13625                new_text.push(' ');
13626                new_idx += 1;
13627                last_char_was_space = true;
13628            }
13629            _ => {
13630                new_text.push(c);
13631                new_idx += c.len_utf8();
13632                last_char_was_space = false;
13633            }
13634        }
13635    }
13636    offset_map[label.text.len()] = new_idx;
13637
13638    // Only modify the label if newlines were removed.
13639    if !newlines_removed {
13640        return;
13641    }
13642
13643    let last_index = new_idx;
13644    let mut run_ranges_errors = Vec::new();
13645    label.runs.retain_mut(|(range, _)| {
13646        match offset_map.get(range.start) {
13647            Some(&start) => range.start = start,
13648            None => {
13649                run_ranges_errors.push(range.clone());
13650                return false;
13651            }
13652        }
13653
13654        match offset_map.get(range.end) {
13655            Some(&end) => range.end = end,
13656            None => {
13657                run_ranges_errors.push(range.clone());
13658                range.end = last_index;
13659            }
13660        }
13661        true
13662    });
13663    if !run_ranges_errors.is_empty() {
13664        log::error!(
13665            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13666            label.text
13667        );
13668    }
13669
13670    let mut wrong_filter_range = None;
13671    if label.filter_range == (0..label.text.len()) {
13672        label.filter_range = 0..new_text.len();
13673    } else {
13674        let mut original_filter_range = Some(label.filter_range.clone());
13675        match offset_map.get(label.filter_range.start) {
13676            Some(&start) => label.filter_range.start = start,
13677            None => {
13678                wrong_filter_range = original_filter_range.take();
13679                label.filter_range.start = last_index;
13680            }
13681        }
13682
13683        match offset_map.get(label.filter_range.end) {
13684            Some(&end) => label.filter_range.end = end,
13685            None => {
13686                wrong_filter_range = original_filter_range.take();
13687                label.filter_range.end = last_index;
13688            }
13689        }
13690    }
13691    if let Some(wrong_filter_range) = wrong_filter_range {
13692        log::error!(
13693            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13694            label.text
13695        );
13696    }
13697
13698    label.text = new_text;
13699}
13700
13701#[cfg(test)]
13702mod tests {
13703    use language::HighlightId;
13704
13705    use super::*;
13706
13707    #[test]
13708    fn test_glob_literal_prefix() {
13709        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13710        assert_eq!(
13711            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13712            Path::new("node_modules")
13713        );
13714        assert_eq!(
13715            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13716            Path::new("foo")
13717        );
13718        assert_eq!(
13719            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13720            Path::new("foo/bar/baz.js")
13721        );
13722
13723        #[cfg(target_os = "windows")]
13724        {
13725            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13726            assert_eq!(
13727                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13728                Path::new("node_modules")
13729            );
13730            assert_eq!(
13731                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13732                Path::new("foo")
13733            );
13734            assert_eq!(
13735                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13736                Path::new("foo/bar/baz.js")
13737            );
13738        }
13739    }
13740
13741    #[test]
13742    fn test_multi_len_chars_normalization() {
13743        let mut label = CodeLabel::new(
13744            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13745            0..6,
13746            vec![(0..6, HighlightId(1))],
13747        );
13748        ensure_uniform_list_compatible_label(&mut label);
13749        assert_eq!(
13750            label,
13751            CodeLabel::new(
13752                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13753                0..6,
13754                vec![(0..6, HighlightId(1))],
13755            )
13756        );
13757    }
13758}