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