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