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