lsp_store.rs

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