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                    match_start: None,
 9977                    insert_text_mode: None,
 9978                    icon_path: None,
 9979                    confirm: None,
 9980                }]))),
 9981                0,
 9982                false,
 9983                cx,
 9984            )
 9985        })?;
 9986
 9987        Ok(proto::ApplyCompletionAdditionalEditsResponse {
 9988            transaction: apply_additional_edits
 9989                .await?
 9990                .as_ref()
 9991                .map(language::proto::serialize_transaction),
 9992        })
 9993    }
 9994
 9995    pub fn last_formatting_failure(&self) -> Option<&str> {
 9996        self.last_formatting_failure.as_deref()
 9997    }
 9998
 9999    pub fn reset_last_formatting_failure(&mut self) {
10000        self.last_formatting_failure = None;
10001    }
10002
10003    pub fn environment_for_buffer(
10004        &self,
10005        buffer: &Entity<Buffer>,
10006        cx: &mut Context<Self>,
10007    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10008        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10009            environment.update(cx, |env, cx| {
10010                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10011            })
10012        } else {
10013            Task::ready(None).shared()
10014        }
10015    }
10016
10017    pub fn format(
10018        &mut self,
10019        buffers: HashSet<Entity<Buffer>>,
10020        target: LspFormatTarget,
10021        push_to_history: bool,
10022        trigger: FormatTrigger,
10023        cx: &mut Context<Self>,
10024    ) -> Task<anyhow::Result<ProjectTransaction>> {
10025        let logger = zlog::scoped!("format");
10026        if self.as_local().is_some() {
10027            zlog::trace!(logger => "Formatting locally");
10028            let logger = zlog::scoped!(logger => "local");
10029            let buffers = buffers
10030                .into_iter()
10031                .map(|buffer_handle| {
10032                    let buffer = buffer_handle.read(cx);
10033                    let buffer_abs_path = File::from_dyn(buffer.file())
10034                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10035
10036                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10037                })
10038                .collect::<Vec<_>>();
10039
10040            cx.spawn(async move |lsp_store, cx| {
10041                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10042
10043                for (handle, abs_path, id) in buffers {
10044                    let env = lsp_store
10045                        .update(cx, |lsp_store, cx| {
10046                            lsp_store.environment_for_buffer(&handle, cx)
10047                        })?
10048                        .await;
10049
10050                    let ranges = match &target {
10051                        LspFormatTarget::Buffers => None,
10052                        LspFormatTarget::Ranges(ranges) => {
10053                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10054                        }
10055                    };
10056
10057                    formattable_buffers.push(FormattableBuffer {
10058                        handle,
10059                        abs_path,
10060                        env,
10061                        ranges,
10062                    });
10063                }
10064                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10065
10066                let format_timer = zlog::time!(logger => "Formatting buffers");
10067                let result = LocalLspStore::format_locally(
10068                    lsp_store.clone(),
10069                    formattable_buffers,
10070                    push_to_history,
10071                    trigger,
10072                    logger,
10073                    cx,
10074                )
10075                .await;
10076                format_timer.end();
10077
10078                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10079
10080                lsp_store.update(cx, |lsp_store, _| {
10081                    lsp_store.update_last_formatting_failure(&result);
10082                })?;
10083
10084                result
10085            })
10086        } else if let Some((client, project_id)) = self.upstream_client() {
10087            zlog::trace!(logger => "Formatting remotely");
10088            let logger = zlog::scoped!(logger => "remote");
10089            // Don't support formatting ranges via remote
10090            match target {
10091                LspFormatTarget::Buffers => {}
10092                LspFormatTarget::Ranges(_) => {
10093                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10094                    return Task::ready(Ok(ProjectTransaction::default()));
10095                }
10096            }
10097
10098            let buffer_store = self.buffer_store();
10099            cx.spawn(async move |lsp_store, cx| {
10100                zlog::trace!(logger => "Sending remote format request");
10101                let request_timer = zlog::time!(logger => "remote format request");
10102                let result = client
10103                    .request(proto::FormatBuffers {
10104                        project_id,
10105                        trigger: trigger as i32,
10106                        buffer_ids: buffers
10107                            .iter()
10108                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10109                            .collect::<Result<_>>()?,
10110                    })
10111                    .await
10112                    .and_then(|result| result.transaction.context("missing transaction"));
10113                request_timer.end();
10114
10115                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10116
10117                lsp_store.update(cx, |lsp_store, _| {
10118                    lsp_store.update_last_formatting_failure(&result);
10119                })?;
10120
10121                let transaction_response = result?;
10122                let _timer = zlog::time!(logger => "deserializing project transaction");
10123                buffer_store
10124                    .update(cx, |buffer_store, cx| {
10125                        buffer_store.deserialize_project_transaction(
10126                            transaction_response,
10127                            push_to_history,
10128                            cx,
10129                        )
10130                    })?
10131                    .await
10132            })
10133        } else {
10134            zlog::trace!(logger => "Not formatting");
10135            Task::ready(Ok(ProjectTransaction::default()))
10136        }
10137    }
10138
10139    async fn handle_format_buffers(
10140        this: Entity<Self>,
10141        envelope: TypedEnvelope<proto::FormatBuffers>,
10142        mut cx: AsyncApp,
10143    ) -> Result<proto::FormatBuffersResponse> {
10144        let sender_id = envelope.original_sender_id().unwrap_or_default();
10145        let format = this.update(&mut cx, |this, cx| {
10146            let mut buffers = HashSet::default();
10147            for buffer_id in &envelope.payload.buffer_ids {
10148                let buffer_id = BufferId::new(*buffer_id)?;
10149                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10150            }
10151            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10152            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10153        })??;
10154
10155        let project_transaction = format.await?;
10156        let project_transaction = this.update(&mut cx, |this, cx| {
10157            this.buffer_store.update(cx, |buffer_store, cx| {
10158                buffer_store.serialize_project_transaction_for_peer(
10159                    project_transaction,
10160                    sender_id,
10161                    cx,
10162                )
10163            })
10164        })?;
10165        Ok(proto::FormatBuffersResponse {
10166            transaction: Some(project_transaction),
10167        })
10168    }
10169
10170    async fn handle_apply_code_action_kind(
10171        this: Entity<Self>,
10172        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10173        mut cx: AsyncApp,
10174    ) -> Result<proto::ApplyCodeActionKindResponse> {
10175        let sender_id = envelope.original_sender_id().unwrap_or_default();
10176        let format = this.update(&mut cx, |this, cx| {
10177            let mut buffers = HashSet::default();
10178            for buffer_id in &envelope.payload.buffer_ids {
10179                let buffer_id = BufferId::new(*buffer_id)?;
10180                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10181            }
10182            let kind = match envelope.payload.kind.as_str() {
10183                "" => CodeActionKind::EMPTY,
10184                "quickfix" => CodeActionKind::QUICKFIX,
10185                "refactor" => CodeActionKind::REFACTOR,
10186                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10187                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10188                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10189                "source" => CodeActionKind::SOURCE,
10190                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10191                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10192                _ => anyhow::bail!(
10193                    "Invalid code action kind {}",
10194                    envelope.payload.kind.as_str()
10195                ),
10196            };
10197            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10198        })??;
10199
10200        let project_transaction = format.await?;
10201        let project_transaction = this.update(&mut cx, |this, cx| {
10202            this.buffer_store.update(cx, |buffer_store, cx| {
10203                buffer_store.serialize_project_transaction_for_peer(
10204                    project_transaction,
10205                    sender_id,
10206                    cx,
10207                )
10208            })
10209        })?;
10210        Ok(proto::ApplyCodeActionKindResponse {
10211            transaction: Some(project_transaction),
10212        })
10213    }
10214
10215    async fn shutdown_language_server(
10216        server_state: Option<LanguageServerState>,
10217        name: LanguageServerName,
10218        cx: &mut AsyncApp,
10219    ) {
10220        let server = match server_state {
10221            Some(LanguageServerState::Starting { startup, .. }) => {
10222                let mut timer = cx
10223                    .background_executor()
10224                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10225                    .fuse();
10226
10227                select! {
10228                    server = startup.fuse() => server,
10229                    () = timer => {
10230                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10231                        None
10232                    },
10233                }
10234            }
10235
10236            Some(LanguageServerState::Running { server, .. }) => Some(server),
10237
10238            None => None,
10239        };
10240
10241        if let Some(server) = server
10242            && let Some(shutdown) = server.shutdown()
10243        {
10244            shutdown.await;
10245        }
10246    }
10247
10248    // Returns a list of all of the worktrees which no longer have a language server and the root path
10249    // for the stopped server
10250    fn stop_local_language_server(
10251        &mut self,
10252        server_id: LanguageServerId,
10253        cx: &mut Context<Self>,
10254    ) -> Task<()> {
10255        let local = match &mut self.mode {
10256            LspStoreMode::Local(local) => local,
10257            _ => {
10258                return Task::ready(());
10259            }
10260        };
10261
10262        // Remove this server ID from all entries in the given worktree.
10263        local
10264            .language_server_ids
10265            .retain(|_, state| state.id != server_id);
10266        self.buffer_store.update(cx, |buffer_store, cx| {
10267            for buffer in buffer_store.buffers() {
10268                buffer.update(cx, |buffer, cx| {
10269                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10270                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10271                });
10272            }
10273        });
10274
10275        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10276            summaries.retain(|path, summaries_by_server_id| {
10277                if summaries_by_server_id.remove(&server_id).is_some() {
10278                    if let Some((client, project_id)) = self.downstream_client.clone() {
10279                        client
10280                            .send(proto::UpdateDiagnosticSummary {
10281                                project_id,
10282                                worktree_id: worktree_id.to_proto(),
10283                                summary: Some(proto::DiagnosticSummary {
10284                                    path: path.as_ref().to_proto(),
10285                                    language_server_id: server_id.0 as u64,
10286                                    error_count: 0,
10287                                    warning_count: 0,
10288                                }),
10289                                more_summaries: Vec::new(),
10290                            })
10291                            .log_err();
10292                    }
10293                    !summaries_by_server_id.is_empty()
10294                } else {
10295                    true
10296                }
10297            });
10298        }
10299
10300        let local = self.as_local_mut().unwrap();
10301        for diagnostics in local.diagnostics.values_mut() {
10302            diagnostics.retain(|_, diagnostics_by_server_id| {
10303                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10304                    diagnostics_by_server_id.remove(ix);
10305                    !diagnostics_by_server_id.is_empty()
10306                } else {
10307                    true
10308                }
10309            });
10310        }
10311        local.language_server_watched_paths.remove(&server_id);
10312
10313        let server_state = local.language_servers.remove(&server_id);
10314        self.cleanup_lsp_data(server_id);
10315        let name = self
10316            .language_server_statuses
10317            .remove(&server_id)
10318            .map(|status| status.name)
10319            .or_else(|| {
10320                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10321                    Some(adapter.name())
10322                } else {
10323                    None
10324                }
10325            });
10326
10327        if let Some(name) = name {
10328            log::info!("stopping language server {name}");
10329            self.languages
10330                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10331            cx.notify();
10332
10333            return cx.spawn(async move |lsp_store, cx| {
10334                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10335                lsp_store
10336                    .update(cx, |lsp_store, cx| {
10337                        lsp_store
10338                            .languages
10339                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10340                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10341                        cx.notify();
10342                    })
10343                    .ok();
10344            });
10345        }
10346
10347        if server_state.is_some() {
10348            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10349        }
10350        Task::ready(())
10351    }
10352
10353    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10354        if let Some((client, project_id)) = self.upstream_client() {
10355            let request = client.request(proto::StopLanguageServers {
10356                project_id,
10357                buffer_ids: Vec::new(),
10358                also_servers: Vec::new(),
10359                all: true,
10360            });
10361            cx.background_spawn(request).detach_and_log_err(cx);
10362        } else {
10363            let Some(local) = self.as_local_mut() else {
10364                return;
10365            };
10366            let language_servers_to_stop = local
10367                .language_server_ids
10368                .values()
10369                .map(|state| state.id)
10370                .collect();
10371            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10372            let tasks = language_servers_to_stop
10373                .into_iter()
10374                .map(|server| self.stop_local_language_server(server, cx))
10375                .collect::<Vec<_>>();
10376            cx.background_spawn(async move {
10377                futures::future::join_all(tasks).await;
10378            })
10379            .detach();
10380        }
10381    }
10382
10383    pub fn restart_language_servers_for_buffers(
10384        &mut self,
10385        buffers: Vec<Entity<Buffer>>,
10386        only_restart_servers: HashSet<LanguageServerSelector>,
10387        cx: &mut Context<Self>,
10388    ) {
10389        if let Some((client, project_id)) = self.upstream_client() {
10390            let request = client.request(proto::RestartLanguageServers {
10391                project_id,
10392                buffer_ids: buffers
10393                    .into_iter()
10394                    .map(|b| b.read(cx).remote_id().to_proto())
10395                    .collect(),
10396                only_servers: only_restart_servers
10397                    .into_iter()
10398                    .map(|selector| {
10399                        let selector = match selector {
10400                            LanguageServerSelector::Id(language_server_id) => {
10401                                proto::language_server_selector::Selector::ServerId(
10402                                    language_server_id.to_proto(),
10403                                )
10404                            }
10405                            LanguageServerSelector::Name(language_server_name) => {
10406                                proto::language_server_selector::Selector::Name(
10407                                    language_server_name.to_string(),
10408                                )
10409                            }
10410                        };
10411                        proto::LanguageServerSelector {
10412                            selector: Some(selector),
10413                        }
10414                    })
10415                    .collect(),
10416                all: false,
10417            });
10418            cx.background_spawn(request).detach_and_log_err(cx);
10419        } else {
10420            let stop_task = if only_restart_servers.is_empty() {
10421                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10422            } else {
10423                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10424            };
10425            cx.spawn(async move |lsp_store, cx| {
10426                stop_task.await;
10427                lsp_store
10428                    .update(cx, |lsp_store, cx| {
10429                        for buffer in buffers {
10430                            lsp_store.register_buffer_with_language_servers(
10431                                &buffer,
10432                                only_restart_servers.clone(),
10433                                true,
10434                                cx,
10435                            );
10436                        }
10437                    })
10438                    .ok()
10439            })
10440            .detach();
10441        }
10442    }
10443
10444    pub fn stop_language_servers_for_buffers(
10445        &mut self,
10446        buffers: Vec<Entity<Buffer>>,
10447        also_stop_servers: HashSet<LanguageServerSelector>,
10448        cx: &mut Context<Self>,
10449    ) -> Task<Result<()>> {
10450        if let Some((client, project_id)) = self.upstream_client() {
10451            let request = client.request(proto::StopLanguageServers {
10452                project_id,
10453                buffer_ids: buffers
10454                    .into_iter()
10455                    .map(|b| b.read(cx).remote_id().to_proto())
10456                    .collect(),
10457                also_servers: also_stop_servers
10458                    .into_iter()
10459                    .map(|selector| {
10460                        let selector = match selector {
10461                            LanguageServerSelector::Id(language_server_id) => {
10462                                proto::language_server_selector::Selector::ServerId(
10463                                    language_server_id.to_proto(),
10464                                )
10465                            }
10466                            LanguageServerSelector::Name(language_server_name) => {
10467                                proto::language_server_selector::Selector::Name(
10468                                    language_server_name.to_string(),
10469                                )
10470                            }
10471                        };
10472                        proto::LanguageServerSelector {
10473                            selector: Some(selector),
10474                        }
10475                    })
10476                    .collect(),
10477                all: false,
10478            });
10479            cx.background_spawn(async move {
10480                let _ = request.await?;
10481                Ok(())
10482            })
10483        } else {
10484            let task =
10485                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10486            cx.background_spawn(async move {
10487                task.await;
10488                Ok(())
10489            })
10490        }
10491    }
10492
10493    fn stop_local_language_servers_for_buffers(
10494        &mut self,
10495        buffers: &[Entity<Buffer>],
10496        also_stop_servers: HashSet<LanguageServerSelector>,
10497        cx: &mut Context<Self>,
10498    ) -> Task<()> {
10499        let Some(local) = self.as_local_mut() else {
10500            return Task::ready(());
10501        };
10502        let mut language_server_names_to_stop = BTreeSet::default();
10503        let mut language_servers_to_stop = also_stop_servers
10504            .into_iter()
10505            .flat_map(|selector| match selector {
10506                LanguageServerSelector::Id(id) => Some(id),
10507                LanguageServerSelector::Name(name) => {
10508                    language_server_names_to_stop.insert(name);
10509                    None
10510                }
10511            })
10512            .collect::<BTreeSet<_>>();
10513
10514        let mut covered_worktrees = HashSet::default();
10515        for buffer in buffers {
10516            buffer.update(cx, |buffer, cx| {
10517                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10518                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10519                    && covered_worktrees.insert(worktree_id)
10520                {
10521                    language_server_names_to_stop.retain(|name| {
10522                        let old_ids_count = language_servers_to_stop.len();
10523                        let all_language_servers_with_this_name = local
10524                            .language_server_ids
10525                            .iter()
10526                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10527                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10528                        old_ids_count == language_servers_to_stop.len()
10529                    });
10530                }
10531            });
10532        }
10533        for name in language_server_names_to_stop {
10534            language_servers_to_stop.extend(
10535                local
10536                    .language_server_ids
10537                    .iter()
10538                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10539            );
10540        }
10541
10542        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10543        let tasks = language_servers_to_stop
10544            .into_iter()
10545            .map(|server| self.stop_local_language_server(server, cx))
10546            .collect::<Vec<_>>();
10547
10548        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10549    }
10550
10551    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10552        let (worktree, relative_path) =
10553            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10554
10555        let project_path = ProjectPath {
10556            worktree_id: worktree.read(cx).id(),
10557            path: relative_path,
10558        };
10559
10560        Some(
10561            self.buffer_store()
10562                .read(cx)
10563                .get_by_path(&project_path)?
10564                .read(cx),
10565        )
10566    }
10567
10568    #[cfg(any(test, feature = "test-support"))]
10569    pub fn update_diagnostics(
10570        &mut self,
10571        server_id: LanguageServerId,
10572        diagnostics: lsp::PublishDiagnosticsParams,
10573        result_id: Option<String>,
10574        source_kind: DiagnosticSourceKind,
10575        disk_based_sources: &[String],
10576        cx: &mut Context<Self>,
10577    ) -> Result<()> {
10578        self.merge_lsp_diagnostics(
10579            source_kind,
10580            vec![DocumentDiagnosticsUpdate {
10581                diagnostics,
10582                result_id,
10583                server_id,
10584                disk_based_sources: Cow::Borrowed(disk_based_sources),
10585            }],
10586            |_, _, _| false,
10587            cx,
10588        )
10589    }
10590
10591    pub fn merge_lsp_diagnostics(
10592        &mut self,
10593        source_kind: DiagnosticSourceKind,
10594        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10595        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10596        cx: &mut Context<Self>,
10597    ) -> Result<()> {
10598        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10599        let updates = lsp_diagnostics
10600            .into_iter()
10601            .filter_map(|update| {
10602                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10603                Some(DocumentDiagnosticsUpdate {
10604                    diagnostics: self.lsp_to_document_diagnostics(
10605                        abs_path,
10606                        source_kind,
10607                        update.server_id,
10608                        update.diagnostics,
10609                        &update.disk_based_sources,
10610                    ),
10611                    result_id: update.result_id,
10612                    server_id: update.server_id,
10613                    disk_based_sources: update.disk_based_sources,
10614                })
10615            })
10616            .collect();
10617        self.merge_diagnostic_entries(updates, merge, cx)?;
10618        Ok(())
10619    }
10620
10621    fn lsp_to_document_diagnostics(
10622        &mut self,
10623        document_abs_path: PathBuf,
10624        source_kind: DiagnosticSourceKind,
10625        server_id: LanguageServerId,
10626        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10627        disk_based_sources: &[String],
10628    ) -> DocumentDiagnostics {
10629        let mut diagnostics = Vec::default();
10630        let mut primary_diagnostic_group_ids = HashMap::default();
10631        let mut sources_by_group_id = HashMap::default();
10632        let mut supporting_diagnostics = HashMap::default();
10633
10634        let adapter = self.language_server_adapter_for_id(server_id);
10635
10636        // Ensure that primary diagnostics are always the most severe
10637        lsp_diagnostics
10638            .diagnostics
10639            .sort_by_key(|item| item.severity);
10640
10641        for diagnostic in &lsp_diagnostics.diagnostics {
10642            let source = diagnostic.source.as_ref();
10643            let range = range_from_lsp(diagnostic.range);
10644            let is_supporting = diagnostic
10645                .related_information
10646                .as_ref()
10647                .is_some_and(|infos| {
10648                    infos.iter().any(|info| {
10649                        primary_diagnostic_group_ids.contains_key(&(
10650                            source,
10651                            diagnostic.code.clone(),
10652                            range_from_lsp(info.location.range),
10653                        ))
10654                    })
10655                });
10656
10657            let is_unnecessary = diagnostic
10658                .tags
10659                .as_ref()
10660                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10661
10662            let underline = self
10663                .language_server_adapter_for_id(server_id)
10664                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10665
10666            if is_supporting {
10667                supporting_diagnostics.insert(
10668                    (source, diagnostic.code.clone(), range),
10669                    (diagnostic.severity, is_unnecessary),
10670                );
10671            } else {
10672                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10673                let is_disk_based =
10674                    source.is_some_and(|source| disk_based_sources.contains(source));
10675
10676                sources_by_group_id.insert(group_id, source);
10677                primary_diagnostic_group_ids
10678                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10679
10680                diagnostics.push(DiagnosticEntry {
10681                    range,
10682                    diagnostic: Diagnostic {
10683                        source: diagnostic.source.clone(),
10684                        source_kind,
10685                        code: diagnostic.code.clone(),
10686                        code_description: diagnostic
10687                            .code_description
10688                            .as_ref()
10689                            .and_then(|d| d.href.clone()),
10690                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10691                        markdown: adapter.as_ref().and_then(|adapter| {
10692                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10693                        }),
10694                        message: diagnostic.message.trim().to_string(),
10695                        group_id,
10696                        is_primary: true,
10697                        is_disk_based,
10698                        is_unnecessary,
10699                        underline,
10700                        data: diagnostic.data.clone(),
10701                    },
10702                });
10703                if let Some(infos) = &diagnostic.related_information {
10704                    for info in infos {
10705                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10706                            let range = range_from_lsp(info.location.range);
10707                            diagnostics.push(DiagnosticEntry {
10708                                range,
10709                                diagnostic: Diagnostic {
10710                                    source: diagnostic.source.clone(),
10711                                    source_kind,
10712                                    code: diagnostic.code.clone(),
10713                                    code_description: diagnostic
10714                                        .code_description
10715                                        .as_ref()
10716                                        .and_then(|d| d.href.clone()),
10717                                    severity: DiagnosticSeverity::INFORMATION,
10718                                    markdown: adapter.as_ref().and_then(|adapter| {
10719                                        adapter.diagnostic_message_to_markdown(&info.message)
10720                                    }),
10721                                    message: info.message.trim().to_string(),
10722                                    group_id,
10723                                    is_primary: false,
10724                                    is_disk_based,
10725                                    is_unnecessary: false,
10726                                    underline,
10727                                    data: diagnostic.data.clone(),
10728                                },
10729                            });
10730                        }
10731                    }
10732                }
10733            }
10734        }
10735
10736        for entry in &mut diagnostics {
10737            let diagnostic = &mut entry.diagnostic;
10738            if !diagnostic.is_primary {
10739                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10740                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10741                    source,
10742                    diagnostic.code.clone(),
10743                    entry.range.clone(),
10744                )) {
10745                    if let Some(severity) = severity {
10746                        diagnostic.severity = severity;
10747                    }
10748                    diagnostic.is_unnecessary = is_unnecessary;
10749                }
10750            }
10751        }
10752
10753        DocumentDiagnostics {
10754            diagnostics,
10755            document_abs_path,
10756            version: lsp_diagnostics.version,
10757        }
10758    }
10759
10760    fn insert_newly_running_language_server(
10761        &mut self,
10762        adapter: Arc<CachedLspAdapter>,
10763        language_server: Arc<LanguageServer>,
10764        server_id: LanguageServerId,
10765        key: LanguageServerSeed,
10766        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10767        cx: &mut Context<Self>,
10768    ) {
10769        let Some(local) = self.as_local_mut() else {
10770            return;
10771        };
10772        // If the language server for this key doesn't match the server id, don't store the
10773        // server. Which will cause it to be dropped, killing the process
10774        if local
10775            .language_server_ids
10776            .get(&key)
10777            .map(|state| state.id != server_id)
10778            .unwrap_or(false)
10779        {
10780            return;
10781        }
10782
10783        // Update language_servers collection with Running variant of LanguageServerState
10784        // indicating that the server is up and running and ready
10785        let workspace_folders = workspace_folders.lock().clone();
10786        language_server.set_workspace_folders(workspace_folders);
10787
10788        local.language_servers.insert(
10789            server_id,
10790            LanguageServerState::Running {
10791                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10792                    language_server.clone(),
10793                    cx,
10794                ),
10795                adapter: adapter.clone(),
10796                server: language_server.clone(),
10797                simulate_disk_based_diagnostics_completion: None,
10798            },
10799        );
10800        local
10801            .languages
10802            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10803        if let Some(file_ops_caps) = language_server
10804            .capabilities()
10805            .workspace
10806            .as_ref()
10807            .and_then(|ws| ws.file_operations.as_ref())
10808        {
10809            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10810            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10811            if did_rename_caps.or(will_rename_caps).is_some() {
10812                let watcher = RenamePathsWatchedForServer::default()
10813                    .with_did_rename_patterns(did_rename_caps)
10814                    .with_will_rename_patterns(will_rename_caps);
10815                local
10816                    .language_server_paths_watched_for_rename
10817                    .insert(server_id, watcher);
10818            }
10819        }
10820
10821        self.language_server_statuses.insert(
10822            server_id,
10823            LanguageServerStatus {
10824                name: language_server.name(),
10825                pending_work: Default::default(),
10826                has_pending_diagnostic_updates: false,
10827                progress_tokens: Default::default(),
10828                worktree: Some(key.worktree_id),
10829            },
10830        );
10831
10832        cx.emit(LspStoreEvent::LanguageServerAdded(
10833            server_id,
10834            language_server.name(),
10835            Some(key.worktree_id),
10836        ));
10837        cx.emit(LspStoreEvent::RefreshInlayHints(server_id));
10838
10839        let server_capabilities = language_server.capabilities();
10840        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10841            downstream_client
10842                .send(proto::StartLanguageServer {
10843                    project_id: *project_id,
10844                    server: Some(proto::LanguageServer {
10845                        id: server_id.to_proto(),
10846                        name: language_server.name().to_string(),
10847                        worktree_id: Some(key.worktree_id.to_proto()),
10848                    }),
10849                    capabilities: serde_json::to_string(&server_capabilities)
10850                        .expect("serializing server LSP capabilities"),
10851                })
10852                .log_err();
10853        }
10854        self.lsp_server_capabilities
10855            .insert(server_id, server_capabilities);
10856
10857        // Tell the language server about every open buffer in the worktree that matches the language.
10858        // Also check for buffers in worktrees that reused this server
10859        let mut worktrees_using_server = vec![key.worktree_id];
10860        if let Some(local) = self.as_local() {
10861            // Find all worktrees that have this server in their language server tree
10862            for (worktree_id, servers) in &local.lsp_tree.instances {
10863                if *worktree_id != key.worktree_id {
10864                    for server_map in servers.roots.values() {
10865                        if server_map
10866                            .values()
10867                            .any(|(node, _)| node.id() == Some(server_id))
10868                        {
10869                            worktrees_using_server.push(*worktree_id);
10870                        }
10871                    }
10872                }
10873            }
10874        }
10875
10876        let mut buffer_paths_registered = Vec::new();
10877        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10878            let mut lsp_adapters = HashMap::default();
10879            for buffer_handle in buffer_store.buffers() {
10880                let buffer = buffer_handle.read(cx);
10881                let file = match File::from_dyn(buffer.file()) {
10882                    Some(file) => file,
10883                    None => continue,
10884                };
10885                let language = match buffer.language() {
10886                    Some(language) => language,
10887                    None => continue,
10888                };
10889
10890                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10891                    || !lsp_adapters
10892                        .entry(language.name())
10893                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
10894                        .iter()
10895                        .any(|a| a.name == key.name)
10896                {
10897                    continue;
10898                }
10899                // didOpen
10900                let file = match file.as_local() {
10901                    Some(file) => file,
10902                    None => continue,
10903                };
10904
10905                let local = self.as_local_mut().unwrap();
10906
10907                let buffer_id = buffer.remote_id();
10908                if local.registered_buffers.contains_key(&buffer_id) {
10909                    let versions = local
10910                        .buffer_snapshots
10911                        .entry(buffer_id)
10912                        .or_default()
10913                        .entry(server_id)
10914                        .and_modify(|_| {
10915                            assert!(
10916                            false,
10917                            "There should not be an existing snapshot for a newly inserted buffer"
10918                        )
10919                        })
10920                        .or_insert_with(|| {
10921                            vec![LspBufferSnapshot {
10922                                version: 0,
10923                                snapshot: buffer.text_snapshot(),
10924                            }]
10925                        });
10926
10927                    let snapshot = versions.last().unwrap();
10928                    let version = snapshot.version;
10929                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
10930                    language_server.register_buffer(
10931                        uri,
10932                        adapter.language_id(&language.name()),
10933                        version,
10934                        buffer_handle.read(cx).text_with_original_line_endings(),
10935                    );
10936                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
10937                    local
10938                        .buffers_opened_in_servers
10939                        .entry(buffer_id)
10940                        .or_default()
10941                        .insert(server_id);
10942                }
10943                buffer_handle.update(cx, |buffer, cx| {
10944                    buffer.set_completion_triggers(
10945                        server_id,
10946                        language_server
10947                            .capabilities()
10948                            .completion_provider
10949                            .as_ref()
10950                            .and_then(|provider| {
10951                                provider
10952                                    .trigger_characters
10953                                    .as_ref()
10954                                    .map(|characters| characters.iter().cloned().collect())
10955                            })
10956                            .unwrap_or_default(),
10957                        cx,
10958                    )
10959                });
10960            }
10961        });
10962
10963        for (buffer_id, abs_path) in buffer_paths_registered {
10964            cx.emit(LspStoreEvent::LanguageServerUpdate {
10965                language_server_id: server_id,
10966                name: Some(adapter.name()),
10967                message: proto::update_language_server::Variant::RegisteredForBuffer(
10968                    proto::RegisteredForBuffer {
10969                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
10970                        buffer_id: buffer_id.to_proto(),
10971                    },
10972                ),
10973            });
10974        }
10975
10976        cx.notify();
10977    }
10978
10979    pub fn language_servers_running_disk_based_diagnostics(
10980        &self,
10981    ) -> impl Iterator<Item = LanguageServerId> + '_ {
10982        self.language_server_statuses
10983            .iter()
10984            .filter_map(|(id, status)| {
10985                if status.has_pending_diagnostic_updates {
10986                    Some(*id)
10987                } else {
10988                    None
10989                }
10990            })
10991    }
10992
10993    pub(crate) fn cancel_language_server_work_for_buffers(
10994        &mut self,
10995        buffers: impl IntoIterator<Item = Entity<Buffer>>,
10996        cx: &mut Context<Self>,
10997    ) {
10998        if let Some((client, project_id)) = self.upstream_client() {
10999            let request = client.request(proto::CancelLanguageServerWork {
11000                project_id,
11001                work: Some(proto::cancel_language_server_work::Work::Buffers(
11002                    proto::cancel_language_server_work::Buffers {
11003                        buffer_ids: buffers
11004                            .into_iter()
11005                            .map(|b| b.read(cx).remote_id().to_proto())
11006                            .collect(),
11007                    },
11008                )),
11009            });
11010            cx.background_spawn(request).detach_and_log_err(cx);
11011        } else if let Some(local) = self.as_local() {
11012            let servers = buffers
11013                .into_iter()
11014                .flat_map(|buffer| {
11015                    buffer.update(cx, |buffer, cx| {
11016                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11017                    })
11018                })
11019                .collect::<HashSet<_>>();
11020            for server_id in servers {
11021                self.cancel_language_server_work(server_id, None, cx);
11022            }
11023        }
11024    }
11025
11026    pub(crate) fn cancel_language_server_work(
11027        &mut self,
11028        server_id: LanguageServerId,
11029        token_to_cancel: Option<String>,
11030        cx: &mut Context<Self>,
11031    ) {
11032        if let Some(local) = self.as_local() {
11033            let status = self.language_server_statuses.get(&server_id);
11034            let server = local.language_servers.get(&server_id);
11035            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11036            {
11037                for (token, progress) in &status.pending_work {
11038                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11039                        && token != token_to_cancel
11040                    {
11041                        continue;
11042                    }
11043                    if progress.is_cancellable {
11044                        server
11045                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11046                                WorkDoneProgressCancelParams {
11047                                    token: lsp::NumberOrString::String(token.clone()),
11048                                },
11049                            )
11050                            .ok();
11051                    }
11052                }
11053            }
11054        } else if let Some((client, project_id)) = self.upstream_client() {
11055            let request = client.request(proto::CancelLanguageServerWork {
11056                project_id,
11057                work: Some(
11058                    proto::cancel_language_server_work::Work::LanguageServerWork(
11059                        proto::cancel_language_server_work::LanguageServerWork {
11060                            language_server_id: server_id.to_proto(),
11061                            token: token_to_cancel,
11062                        },
11063                    ),
11064                ),
11065            });
11066            cx.background_spawn(request).detach_and_log_err(cx);
11067        }
11068    }
11069
11070    fn register_supplementary_language_server(
11071        &mut self,
11072        id: LanguageServerId,
11073        name: LanguageServerName,
11074        server: Arc<LanguageServer>,
11075        cx: &mut Context<Self>,
11076    ) {
11077        if let Some(local) = self.as_local_mut() {
11078            local
11079                .supplementary_language_servers
11080                .insert(id, (name.clone(), server));
11081            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11082        }
11083    }
11084
11085    fn unregister_supplementary_language_server(
11086        &mut self,
11087        id: LanguageServerId,
11088        cx: &mut Context<Self>,
11089    ) {
11090        if let Some(local) = self.as_local_mut() {
11091            local.supplementary_language_servers.remove(&id);
11092            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11093        }
11094    }
11095
11096    pub(crate) fn supplementary_language_servers(
11097        &self,
11098    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11099        self.as_local().into_iter().flat_map(|local| {
11100            local
11101                .supplementary_language_servers
11102                .iter()
11103                .map(|(id, (name, _))| (*id, name.clone()))
11104        })
11105    }
11106
11107    pub fn language_server_adapter_for_id(
11108        &self,
11109        id: LanguageServerId,
11110    ) -> Option<Arc<CachedLspAdapter>> {
11111        self.as_local()
11112            .and_then(|local| local.language_servers.get(&id))
11113            .and_then(|language_server_state| match language_server_state {
11114                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11115                _ => None,
11116            })
11117    }
11118
11119    pub(super) fn update_local_worktree_language_servers(
11120        &mut self,
11121        worktree_handle: &Entity<Worktree>,
11122        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11123        cx: &mut Context<Self>,
11124    ) {
11125        if changes.is_empty() {
11126            return;
11127        }
11128
11129        let Some(local) = self.as_local() else { return };
11130
11131        local.prettier_store.update(cx, |prettier_store, cx| {
11132            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11133        });
11134
11135        let worktree_id = worktree_handle.read(cx).id();
11136        let mut language_server_ids = local
11137            .language_server_ids
11138            .iter()
11139            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11140            .collect::<Vec<_>>();
11141        language_server_ids.sort();
11142        language_server_ids.dedup();
11143
11144        // let abs_path = worktree_handle.read(cx).abs_path();
11145        for server_id in &language_server_ids {
11146            if let Some(LanguageServerState::Running { server, .. }) =
11147                local.language_servers.get(server_id)
11148                && let Some(watched_paths) = local
11149                    .language_server_watched_paths
11150                    .get(server_id)
11151                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11152            {
11153                let params = lsp::DidChangeWatchedFilesParams {
11154                    changes: changes
11155                        .iter()
11156                        .filter_map(|(path, _, change)| {
11157                            if !watched_paths.is_match(path.as_std_path()) {
11158                                return None;
11159                            }
11160                            let typ = match change {
11161                                PathChange::Loaded => return None,
11162                                PathChange::Added => lsp::FileChangeType::CREATED,
11163                                PathChange::Removed => lsp::FileChangeType::DELETED,
11164                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11165                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11166                            };
11167                            let uri = lsp::Uri::from_file_path(
11168                                worktree_handle.read(cx).absolutize(&path),
11169                            )
11170                            .ok()?;
11171                            Some(lsp::FileEvent { uri, typ })
11172                        })
11173                        .collect(),
11174                };
11175                if !params.changes.is_empty() {
11176                    server
11177                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11178                        .ok();
11179                }
11180            }
11181        }
11182        for (path, _, _) in changes {
11183            if let Some(file_name) = path.file_name()
11184                && local.watched_manifest_filenames.contains(file_name)
11185            {
11186                self.request_workspace_config_refresh();
11187                break;
11188            }
11189        }
11190    }
11191
11192    pub fn wait_for_remote_buffer(
11193        &mut self,
11194        id: BufferId,
11195        cx: &mut Context<Self>,
11196    ) -> Task<Result<Entity<Buffer>>> {
11197        self.buffer_store.update(cx, |buffer_store, cx| {
11198            buffer_store.wait_for_remote_buffer(id, cx)
11199        })
11200    }
11201
11202    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11203        let mut result = proto::Symbol {
11204            language_server_name: symbol.language_server_name.0.to_string(),
11205            source_worktree_id: symbol.source_worktree_id.to_proto(),
11206            language_server_id: symbol.source_language_server_id.to_proto(),
11207            name: symbol.name.clone(),
11208            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11209            start: Some(proto::PointUtf16 {
11210                row: symbol.range.start.0.row,
11211                column: symbol.range.start.0.column,
11212            }),
11213            end: Some(proto::PointUtf16 {
11214                row: symbol.range.end.0.row,
11215                column: symbol.range.end.0.column,
11216            }),
11217            worktree_id: Default::default(),
11218            path: Default::default(),
11219            signature: Default::default(),
11220        };
11221        match &symbol.path {
11222            SymbolLocation::InProject(path) => {
11223                result.worktree_id = path.worktree_id.to_proto();
11224                result.path = path.path.to_proto();
11225            }
11226            SymbolLocation::OutsideProject {
11227                abs_path,
11228                signature,
11229            } => {
11230                result.path = abs_path.to_string_lossy().into_owned();
11231                result.signature = signature.to_vec();
11232            }
11233        }
11234        result
11235    }
11236
11237    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11238        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11239        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11240        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11241
11242        let path = if serialized_symbol.signature.is_empty() {
11243            SymbolLocation::InProject(ProjectPath {
11244                worktree_id,
11245                path: RelPath::from_proto(&serialized_symbol.path)
11246                    .context("invalid symbol path")?,
11247            })
11248        } else {
11249            SymbolLocation::OutsideProject {
11250                abs_path: Path::new(&serialized_symbol.path).into(),
11251                signature: serialized_symbol
11252                    .signature
11253                    .try_into()
11254                    .map_err(|_| anyhow!("invalid signature"))?,
11255            }
11256        };
11257
11258        let start = serialized_symbol.start.context("invalid start")?;
11259        let end = serialized_symbol.end.context("invalid end")?;
11260        Ok(CoreSymbol {
11261            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11262            source_worktree_id,
11263            source_language_server_id: LanguageServerId::from_proto(
11264                serialized_symbol.language_server_id,
11265            ),
11266            path,
11267            name: serialized_symbol.name,
11268            range: Unclipped(PointUtf16::new(start.row, start.column))
11269                ..Unclipped(PointUtf16::new(end.row, end.column)),
11270            kind,
11271        })
11272    }
11273
11274    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11275        let mut serialized_completion = proto::Completion {
11276            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11277            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11278            new_text: completion.new_text.clone(),
11279            ..proto::Completion::default()
11280        };
11281        match &completion.source {
11282            CompletionSource::Lsp {
11283                insert_range,
11284                server_id,
11285                lsp_completion,
11286                lsp_defaults,
11287                resolved,
11288            } => {
11289                let (old_insert_start, old_insert_end) = insert_range
11290                    .as_ref()
11291                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11292                    .unzip();
11293
11294                serialized_completion.old_insert_start = old_insert_start;
11295                serialized_completion.old_insert_end = old_insert_end;
11296                serialized_completion.source = proto::completion::Source::Lsp as i32;
11297                serialized_completion.server_id = server_id.0 as u64;
11298                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11299                serialized_completion.lsp_defaults = lsp_defaults
11300                    .as_deref()
11301                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11302                serialized_completion.resolved = *resolved;
11303            }
11304            CompletionSource::BufferWord {
11305                word_range,
11306                resolved,
11307            } => {
11308                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11309                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11310                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11311                serialized_completion.resolved = *resolved;
11312            }
11313            CompletionSource::Custom => {
11314                serialized_completion.source = proto::completion::Source::Custom as i32;
11315                serialized_completion.resolved = true;
11316            }
11317            CompletionSource::Dap { sort_text } => {
11318                serialized_completion.source = proto::completion::Source::Dap as i32;
11319                serialized_completion.sort_text = Some(sort_text.clone());
11320            }
11321        }
11322
11323        serialized_completion
11324    }
11325
11326    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11327        let old_replace_start = completion
11328            .old_replace_start
11329            .and_then(deserialize_anchor)
11330            .context("invalid old start")?;
11331        let old_replace_end = completion
11332            .old_replace_end
11333            .and_then(deserialize_anchor)
11334            .context("invalid old end")?;
11335        let insert_range = {
11336            match completion.old_insert_start.zip(completion.old_insert_end) {
11337                Some((start, end)) => {
11338                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11339                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11340                    Some(start..end)
11341                }
11342                None => None,
11343            }
11344        };
11345        Ok(CoreCompletion {
11346            replace_range: old_replace_start..old_replace_end,
11347            new_text: completion.new_text,
11348            source: match proto::completion::Source::from_i32(completion.source) {
11349                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11350                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11351                    insert_range,
11352                    server_id: LanguageServerId::from_proto(completion.server_id),
11353                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11354                    lsp_defaults: completion
11355                        .lsp_defaults
11356                        .as_deref()
11357                        .map(serde_json::from_slice)
11358                        .transpose()?,
11359                    resolved: completion.resolved,
11360                },
11361                Some(proto::completion::Source::BufferWord) => {
11362                    let word_range = completion
11363                        .buffer_word_start
11364                        .and_then(deserialize_anchor)
11365                        .context("invalid buffer word start")?
11366                        ..completion
11367                            .buffer_word_end
11368                            .and_then(deserialize_anchor)
11369                            .context("invalid buffer word end")?;
11370                    CompletionSource::BufferWord {
11371                        word_range,
11372                        resolved: completion.resolved,
11373                    }
11374                }
11375                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11376                    sort_text: completion
11377                        .sort_text
11378                        .context("expected sort text to exist")?,
11379                },
11380                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11381            },
11382        })
11383    }
11384
11385    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11386        let (kind, lsp_action) = match &action.lsp_action {
11387            LspAction::Action(code_action) => (
11388                proto::code_action::Kind::Action as i32,
11389                serde_json::to_vec(code_action).unwrap(),
11390            ),
11391            LspAction::Command(command) => (
11392                proto::code_action::Kind::Command as i32,
11393                serde_json::to_vec(command).unwrap(),
11394            ),
11395            LspAction::CodeLens(code_lens) => (
11396                proto::code_action::Kind::CodeLens as i32,
11397                serde_json::to_vec(code_lens).unwrap(),
11398            ),
11399        };
11400
11401        proto::CodeAction {
11402            server_id: action.server_id.0 as u64,
11403            start: Some(serialize_anchor(&action.range.start)),
11404            end: Some(serialize_anchor(&action.range.end)),
11405            lsp_action,
11406            kind,
11407            resolved: action.resolved,
11408        }
11409    }
11410
11411    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11412        let start = action
11413            .start
11414            .and_then(deserialize_anchor)
11415            .context("invalid start")?;
11416        let end = action
11417            .end
11418            .and_then(deserialize_anchor)
11419            .context("invalid end")?;
11420        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11421            Some(proto::code_action::Kind::Action) => {
11422                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11423            }
11424            Some(proto::code_action::Kind::Command) => {
11425                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11426            }
11427            Some(proto::code_action::Kind::CodeLens) => {
11428                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11429            }
11430            None => anyhow::bail!("Unknown action kind {}", action.kind),
11431        };
11432        Ok(CodeAction {
11433            server_id: LanguageServerId(action.server_id as usize),
11434            range: start..end,
11435            resolved: action.resolved,
11436            lsp_action,
11437        })
11438    }
11439
11440    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11441        match &formatting_result {
11442            Ok(_) => self.last_formatting_failure = None,
11443            Err(error) => {
11444                let error_string = format!("{error:#}");
11445                log::error!("Formatting failed: {error_string}");
11446                self.last_formatting_failure
11447                    .replace(error_string.lines().join(" "));
11448            }
11449        }
11450    }
11451
11452    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11453        self.lsp_server_capabilities.remove(&for_server);
11454        for lsp_data in self.lsp_data.values_mut() {
11455            lsp_data.remove_server_data(for_server);
11456        }
11457        if let Some(local) = self.as_local_mut() {
11458            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11459            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11460                buffer_servers.remove(&for_server);
11461            }
11462        }
11463    }
11464
11465    pub fn result_id(
11466        &self,
11467        server_id: LanguageServerId,
11468        buffer_id: BufferId,
11469        cx: &App,
11470    ) -> Option<String> {
11471        let abs_path = self
11472            .buffer_store
11473            .read(cx)
11474            .get(buffer_id)
11475            .and_then(|b| File::from_dyn(b.read(cx).file()))
11476            .map(|f| f.abs_path(cx))?;
11477        self.as_local()?
11478            .buffer_pull_diagnostics_result_ids
11479            .get(&server_id)?
11480            .get(&abs_path)?
11481            .clone()
11482    }
11483
11484    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11485        let Some(local) = self.as_local() else {
11486            return HashMap::default();
11487        };
11488        local
11489            .buffer_pull_diagnostics_result_ids
11490            .get(&server_id)
11491            .into_iter()
11492            .flatten()
11493            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11494            .collect()
11495    }
11496
11497    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11498        if let Some(LanguageServerState::Running {
11499            workspace_refresh_task: Some(workspace_refresh_task),
11500            ..
11501        }) = self
11502            .as_local_mut()
11503            .and_then(|local| local.language_servers.get_mut(&server_id))
11504        {
11505            workspace_refresh_task.refresh_tx.try_send(()).ok();
11506        }
11507    }
11508
11509    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11510        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11511            return;
11512        };
11513        let Some(local) = self.as_local_mut() else {
11514            return;
11515        };
11516
11517        for server_id in buffer.update(cx, |buffer, cx| {
11518            local.language_server_ids_for_buffer(buffer, cx)
11519        }) {
11520            if let Some(LanguageServerState::Running {
11521                workspace_refresh_task: Some(workspace_refresh_task),
11522                ..
11523            }) = local.language_servers.get_mut(&server_id)
11524            {
11525                workspace_refresh_task.refresh_tx.try_send(()).ok();
11526            }
11527        }
11528    }
11529
11530    fn apply_workspace_diagnostic_report(
11531        &mut self,
11532        server_id: LanguageServerId,
11533        report: lsp::WorkspaceDiagnosticReportResult,
11534        cx: &mut Context<Self>,
11535    ) {
11536        let workspace_diagnostics =
11537            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11538        let mut unchanged_buffers = HashSet::default();
11539        let mut changed_buffers = HashSet::default();
11540        let workspace_diagnostics_updates = workspace_diagnostics
11541            .into_iter()
11542            .filter_map(
11543                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11544                    LspPullDiagnostics::Response {
11545                        server_id,
11546                        uri,
11547                        diagnostics,
11548                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11549                    LspPullDiagnostics::Default => None,
11550                },
11551            )
11552            .fold(
11553                HashMap::default(),
11554                |mut acc, (server_id, uri, diagnostics, version)| {
11555                    let (result_id, diagnostics) = match diagnostics {
11556                        PulledDiagnostics::Unchanged { result_id } => {
11557                            unchanged_buffers.insert(uri.clone());
11558                            (Some(result_id), Vec::new())
11559                        }
11560                        PulledDiagnostics::Changed {
11561                            result_id,
11562                            diagnostics,
11563                        } => {
11564                            changed_buffers.insert(uri.clone());
11565                            (result_id, diagnostics)
11566                        }
11567                    };
11568                    let disk_based_sources = Cow::Owned(
11569                        self.language_server_adapter_for_id(server_id)
11570                            .as_ref()
11571                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11572                            .unwrap_or(&[])
11573                            .to_vec(),
11574                    );
11575                    acc.entry(server_id)
11576                        .or_insert_with(Vec::new)
11577                        .push(DocumentDiagnosticsUpdate {
11578                            server_id,
11579                            diagnostics: lsp::PublishDiagnosticsParams {
11580                                uri,
11581                                diagnostics,
11582                                version,
11583                            },
11584                            result_id,
11585                            disk_based_sources,
11586                        });
11587                    acc
11588                },
11589            );
11590
11591        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11592            self.merge_lsp_diagnostics(
11593                DiagnosticSourceKind::Pulled,
11594                diagnostic_updates,
11595                |buffer, old_diagnostic, cx| {
11596                    File::from_dyn(buffer.file())
11597                        .and_then(|file| {
11598                            let abs_path = file.as_local()?.abs_path(cx);
11599                            lsp::Uri::from_file_path(abs_path).ok()
11600                        })
11601                        .is_none_or(|buffer_uri| {
11602                            unchanged_buffers.contains(&buffer_uri)
11603                                || match old_diagnostic.source_kind {
11604                                    DiagnosticSourceKind::Pulled => {
11605                                        !changed_buffers.contains(&buffer_uri)
11606                                    }
11607                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11608                                        true
11609                                    }
11610                                }
11611                        })
11612                },
11613                cx,
11614            )
11615            .log_err();
11616        }
11617    }
11618
11619    fn register_server_capabilities(
11620        &mut self,
11621        server_id: LanguageServerId,
11622        params: lsp::RegistrationParams,
11623        cx: &mut Context<Self>,
11624    ) -> anyhow::Result<()> {
11625        let server = self
11626            .language_server_for_id(server_id)
11627            .with_context(|| format!("no server {server_id} found"))?;
11628        for reg in params.registrations {
11629            match reg.method.as_str() {
11630                "workspace/didChangeWatchedFiles" => {
11631                    if let Some(options) = reg.register_options {
11632                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11633                            let caps = serde_json::from_value(options)?;
11634                            local_lsp_store
11635                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11636                            true
11637                        } else {
11638                            false
11639                        };
11640                        if notify {
11641                            notify_server_capabilities_updated(&server, cx);
11642                        }
11643                    }
11644                }
11645                "workspace/didChangeConfiguration" => {
11646                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11647                }
11648                "workspace/didChangeWorkspaceFolders" => {
11649                    // In this case register options is an empty object, we can ignore it
11650                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11651                        supported: Some(true),
11652                        change_notifications: Some(OneOf::Right(reg.id)),
11653                    };
11654                    server.update_capabilities(|capabilities| {
11655                        capabilities
11656                            .workspace
11657                            .get_or_insert_default()
11658                            .workspace_folders = Some(caps);
11659                    });
11660                    notify_server_capabilities_updated(&server, cx);
11661                }
11662                "workspace/symbol" => {
11663                    let options = parse_register_capabilities(reg)?;
11664                    server.update_capabilities(|capabilities| {
11665                        capabilities.workspace_symbol_provider = Some(options);
11666                    });
11667                    notify_server_capabilities_updated(&server, cx);
11668                }
11669                "workspace/fileOperations" => {
11670                    if let Some(options) = reg.register_options {
11671                        let caps = serde_json::from_value(options)?;
11672                        server.update_capabilities(|capabilities| {
11673                            capabilities
11674                                .workspace
11675                                .get_or_insert_default()
11676                                .file_operations = Some(caps);
11677                        });
11678                        notify_server_capabilities_updated(&server, cx);
11679                    }
11680                }
11681                "workspace/executeCommand" => {
11682                    if let Some(options) = reg.register_options {
11683                        let options = serde_json::from_value(options)?;
11684                        server.update_capabilities(|capabilities| {
11685                            capabilities.execute_command_provider = Some(options);
11686                        });
11687                        notify_server_capabilities_updated(&server, cx);
11688                    }
11689                }
11690                "textDocument/rangeFormatting" => {
11691                    let options = parse_register_capabilities(reg)?;
11692                    server.update_capabilities(|capabilities| {
11693                        capabilities.document_range_formatting_provider = Some(options);
11694                    });
11695                    notify_server_capabilities_updated(&server, cx);
11696                }
11697                "textDocument/onTypeFormatting" => {
11698                    if let Some(options) = reg
11699                        .register_options
11700                        .map(serde_json::from_value)
11701                        .transpose()?
11702                    {
11703                        server.update_capabilities(|capabilities| {
11704                            capabilities.document_on_type_formatting_provider = Some(options);
11705                        });
11706                        notify_server_capabilities_updated(&server, cx);
11707                    }
11708                }
11709                "textDocument/formatting" => {
11710                    let options = parse_register_capabilities(reg)?;
11711                    server.update_capabilities(|capabilities| {
11712                        capabilities.document_formatting_provider = Some(options);
11713                    });
11714                    notify_server_capabilities_updated(&server, cx);
11715                }
11716                "textDocument/rename" => {
11717                    let options = parse_register_capabilities(reg)?;
11718                    server.update_capabilities(|capabilities| {
11719                        capabilities.rename_provider = Some(options);
11720                    });
11721                    notify_server_capabilities_updated(&server, cx);
11722                }
11723                "textDocument/inlayHint" => {
11724                    let options = parse_register_capabilities(reg)?;
11725                    server.update_capabilities(|capabilities| {
11726                        capabilities.inlay_hint_provider = Some(options);
11727                    });
11728                    notify_server_capabilities_updated(&server, cx);
11729                }
11730                "textDocument/documentSymbol" => {
11731                    let options = parse_register_capabilities(reg)?;
11732                    server.update_capabilities(|capabilities| {
11733                        capabilities.document_symbol_provider = Some(options);
11734                    });
11735                    notify_server_capabilities_updated(&server, cx);
11736                }
11737                "textDocument/codeAction" => {
11738                    let options = parse_register_capabilities(reg)?;
11739                    let provider = match options {
11740                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11741                        OneOf::Right(caps) => caps,
11742                    };
11743                    server.update_capabilities(|capabilities| {
11744                        capabilities.code_action_provider = Some(provider);
11745                    });
11746                    notify_server_capabilities_updated(&server, cx);
11747                }
11748                "textDocument/definition" => {
11749                    let options = parse_register_capabilities(reg)?;
11750                    server.update_capabilities(|capabilities| {
11751                        capabilities.definition_provider = Some(options);
11752                    });
11753                    notify_server_capabilities_updated(&server, cx);
11754                }
11755                "textDocument/completion" => {
11756                    if let Some(caps) = reg
11757                        .register_options
11758                        .map(serde_json::from_value)
11759                        .transpose()?
11760                    {
11761                        server.update_capabilities(|capabilities| {
11762                            capabilities.completion_provider = Some(caps);
11763                        });
11764                        notify_server_capabilities_updated(&server, cx);
11765                    }
11766                }
11767                "textDocument/hover" => {
11768                    let options = parse_register_capabilities(reg)?;
11769                    let provider = match options {
11770                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11771                        OneOf::Right(caps) => caps,
11772                    };
11773                    server.update_capabilities(|capabilities| {
11774                        capabilities.hover_provider = Some(provider);
11775                    });
11776                    notify_server_capabilities_updated(&server, cx);
11777                }
11778                "textDocument/signatureHelp" => {
11779                    if let Some(caps) = reg
11780                        .register_options
11781                        .map(serde_json::from_value)
11782                        .transpose()?
11783                    {
11784                        server.update_capabilities(|capabilities| {
11785                            capabilities.signature_help_provider = Some(caps);
11786                        });
11787                        notify_server_capabilities_updated(&server, cx);
11788                    }
11789                }
11790                "textDocument/didChange" => {
11791                    if let Some(sync_kind) = reg
11792                        .register_options
11793                        .and_then(|opts| opts.get("syncKind").cloned())
11794                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11795                        .transpose()?
11796                    {
11797                        server.update_capabilities(|capabilities| {
11798                            let mut sync_options =
11799                                Self::take_text_document_sync_options(capabilities);
11800                            sync_options.change = Some(sync_kind);
11801                            capabilities.text_document_sync =
11802                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11803                        });
11804                        notify_server_capabilities_updated(&server, cx);
11805                    }
11806                }
11807                "textDocument/didSave" => {
11808                    if let Some(include_text) = reg
11809                        .register_options
11810                        .map(|opts| {
11811                            let transpose = opts
11812                                .get("includeText")
11813                                .cloned()
11814                                .map(serde_json::from_value::<Option<bool>>)
11815                                .transpose();
11816                            match transpose {
11817                                Ok(value) => Ok(value.flatten()),
11818                                Err(e) => Err(e),
11819                            }
11820                        })
11821                        .transpose()?
11822                    {
11823                        server.update_capabilities(|capabilities| {
11824                            let mut sync_options =
11825                                Self::take_text_document_sync_options(capabilities);
11826                            sync_options.save =
11827                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11828                                    include_text,
11829                                }));
11830                            capabilities.text_document_sync =
11831                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11832                        });
11833                        notify_server_capabilities_updated(&server, cx);
11834                    }
11835                }
11836                "textDocument/codeLens" => {
11837                    if let Some(caps) = reg
11838                        .register_options
11839                        .map(serde_json::from_value)
11840                        .transpose()?
11841                    {
11842                        server.update_capabilities(|capabilities| {
11843                            capabilities.code_lens_provider = Some(caps);
11844                        });
11845                        notify_server_capabilities_updated(&server, cx);
11846                    }
11847                }
11848                "textDocument/diagnostic" => {
11849                    if let Some(caps) = reg
11850                        .register_options
11851                        .map(serde_json::from_value)
11852                        .transpose()?
11853                    {
11854                        let state = self
11855                            .as_local_mut()
11856                            .context("Expected LSP Store to be local")?
11857                            .language_servers
11858                            .get_mut(&server_id)
11859                            .context("Could not obtain Language Servers state")?;
11860                        server.update_capabilities(|capabilities| {
11861                            capabilities.diagnostic_provider = Some(caps);
11862                        });
11863                        if let LanguageServerState::Running {
11864                            workspace_refresh_task,
11865                            ..
11866                        } = state
11867                            && workspace_refresh_task.is_none()
11868                        {
11869                            *workspace_refresh_task =
11870                                lsp_workspace_diagnostics_refresh(server.clone(), cx)
11871                        }
11872
11873                        notify_server_capabilities_updated(&server, cx);
11874                    }
11875                }
11876                "textDocument/documentColor" => {
11877                    let options = parse_register_capabilities(reg)?;
11878                    let provider = match options {
11879                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
11880                        OneOf::Right(caps) => caps,
11881                    };
11882                    server.update_capabilities(|capabilities| {
11883                        capabilities.color_provider = Some(provider);
11884                    });
11885                    notify_server_capabilities_updated(&server, cx);
11886                }
11887                _ => log::warn!("unhandled capability registration: {reg:?}"),
11888            }
11889        }
11890
11891        Ok(())
11892    }
11893
11894    fn unregister_server_capabilities(
11895        &mut self,
11896        server_id: LanguageServerId,
11897        params: lsp::UnregistrationParams,
11898        cx: &mut Context<Self>,
11899    ) -> anyhow::Result<()> {
11900        let server = self
11901            .language_server_for_id(server_id)
11902            .with_context(|| format!("no server {server_id} found"))?;
11903        for unreg in params.unregisterations.iter() {
11904            match unreg.method.as_str() {
11905                "workspace/didChangeWatchedFiles" => {
11906                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11907                        local_lsp_store
11908                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11909                        true
11910                    } else {
11911                        false
11912                    };
11913                    if notify {
11914                        notify_server_capabilities_updated(&server, cx);
11915                    }
11916                }
11917                "workspace/didChangeConfiguration" => {
11918                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11919                }
11920                "workspace/didChangeWorkspaceFolders" => {
11921                    server.update_capabilities(|capabilities| {
11922                        capabilities
11923                            .workspace
11924                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11925                                workspace_folders: None,
11926                                file_operations: None,
11927                            })
11928                            .workspace_folders = None;
11929                    });
11930                    notify_server_capabilities_updated(&server, cx);
11931                }
11932                "workspace/symbol" => {
11933                    server.update_capabilities(|capabilities| {
11934                        capabilities.workspace_symbol_provider = None
11935                    });
11936                    notify_server_capabilities_updated(&server, cx);
11937                }
11938                "workspace/fileOperations" => {
11939                    server.update_capabilities(|capabilities| {
11940                        capabilities
11941                            .workspace
11942                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11943                                workspace_folders: None,
11944                                file_operations: None,
11945                            })
11946                            .file_operations = None;
11947                    });
11948                    notify_server_capabilities_updated(&server, cx);
11949                }
11950                "workspace/executeCommand" => {
11951                    server.update_capabilities(|capabilities| {
11952                        capabilities.execute_command_provider = None;
11953                    });
11954                    notify_server_capabilities_updated(&server, cx);
11955                }
11956                "textDocument/rangeFormatting" => {
11957                    server.update_capabilities(|capabilities| {
11958                        capabilities.document_range_formatting_provider = None
11959                    });
11960                    notify_server_capabilities_updated(&server, cx);
11961                }
11962                "textDocument/onTypeFormatting" => {
11963                    server.update_capabilities(|capabilities| {
11964                        capabilities.document_on_type_formatting_provider = None;
11965                    });
11966                    notify_server_capabilities_updated(&server, cx);
11967                }
11968                "textDocument/formatting" => {
11969                    server.update_capabilities(|capabilities| {
11970                        capabilities.document_formatting_provider = None;
11971                    });
11972                    notify_server_capabilities_updated(&server, cx);
11973                }
11974                "textDocument/rename" => {
11975                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
11976                    notify_server_capabilities_updated(&server, cx);
11977                }
11978                "textDocument/codeAction" => {
11979                    server.update_capabilities(|capabilities| {
11980                        capabilities.code_action_provider = None;
11981                    });
11982                    notify_server_capabilities_updated(&server, cx);
11983                }
11984                "textDocument/definition" => {
11985                    server.update_capabilities(|capabilities| {
11986                        capabilities.definition_provider = None;
11987                    });
11988                    notify_server_capabilities_updated(&server, cx);
11989                }
11990                "textDocument/completion" => {
11991                    server.update_capabilities(|capabilities| {
11992                        capabilities.completion_provider = None;
11993                    });
11994                    notify_server_capabilities_updated(&server, cx);
11995                }
11996                "textDocument/hover" => {
11997                    server.update_capabilities(|capabilities| {
11998                        capabilities.hover_provider = None;
11999                    });
12000                    notify_server_capabilities_updated(&server, cx);
12001                }
12002                "textDocument/signatureHelp" => {
12003                    server.update_capabilities(|capabilities| {
12004                        capabilities.signature_help_provider = None;
12005                    });
12006                    notify_server_capabilities_updated(&server, cx);
12007                }
12008                "textDocument/didChange" => {
12009                    server.update_capabilities(|capabilities| {
12010                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12011                        sync_options.change = None;
12012                        capabilities.text_document_sync =
12013                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12014                    });
12015                    notify_server_capabilities_updated(&server, cx);
12016                }
12017                "textDocument/didSave" => {
12018                    server.update_capabilities(|capabilities| {
12019                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12020                        sync_options.save = None;
12021                        capabilities.text_document_sync =
12022                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12023                    });
12024                    notify_server_capabilities_updated(&server, cx);
12025                }
12026                "textDocument/codeLens" => {
12027                    server.update_capabilities(|capabilities| {
12028                        capabilities.code_lens_provider = None;
12029                    });
12030                    notify_server_capabilities_updated(&server, cx);
12031                }
12032                "textDocument/diagnostic" => {
12033                    server.update_capabilities(|capabilities| {
12034                        capabilities.diagnostic_provider = None;
12035                    });
12036                    let state = self
12037                        .as_local_mut()
12038                        .context("Expected LSP Store to be local")?
12039                        .language_servers
12040                        .get_mut(&server_id)
12041                        .context("Could not obtain Language Servers state")?;
12042                    if let LanguageServerState::Running {
12043                        workspace_refresh_task,
12044                        ..
12045                    } = state
12046                    {
12047                        _ = workspace_refresh_task.take();
12048                    }
12049                    notify_server_capabilities_updated(&server, cx);
12050                }
12051                "textDocument/documentColor" => {
12052                    server.update_capabilities(|capabilities| {
12053                        capabilities.color_provider = None;
12054                    });
12055                    notify_server_capabilities_updated(&server, cx);
12056                }
12057                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12058            }
12059        }
12060
12061        Ok(())
12062    }
12063
12064    async fn deduplicate_range_based_lsp_requests<T>(
12065        lsp_store: &Entity<Self>,
12066        server_id: Option<LanguageServerId>,
12067        lsp_request_id: LspRequestId,
12068        proto_request: &T::ProtoRequest,
12069        range: Range<Anchor>,
12070        cx: &mut AsyncApp,
12071    ) -> Result<()>
12072    where
12073        T: LspCommand,
12074        T::ProtoRequest: proto::LspRequestMessage,
12075    {
12076        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12077        let version = deserialize_version(proto_request.buffer_version());
12078        let buffer = lsp_store.update(cx, |this, cx| {
12079            this.buffer_store.read(cx).get_existing(buffer_id)
12080        })??;
12081        buffer
12082            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12083            .await?;
12084        lsp_store.update(cx, |lsp_store, cx| {
12085            let lsp_data = lsp_store
12086                .lsp_data
12087                .entry(buffer_id)
12088                .or_insert_with(|| BufferLspData::new(&buffer, cx));
12089            let chunks_queried_for = lsp_data
12090                .inlay_hints
12091                .applicable_chunks(&[range])
12092                .collect::<Vec<_>>();
12093            match chunks_queried_for.as_slice() {
12094                &[chunk] => {
12095                    let key = LspKey {
12096                        request_type: TypeId::of::<T>(),
12097                        server_queried: server_id,
12098                    };
12099                    let previous_request = lsp_data
12100                        .chunk_lsp_requests
12101                        .entry(key)
12102                        .or_default()
12103                        .insert(chunk, lsp_request_id);
12104                    if let Some((previous_request, running_requests)) =
12105                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12106                    {
12107                        running_requests.remove(&previous_request);
12108                    }
12109                }
12110                _ambiguous_chunks => {
12111                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12112                    // there, a buffer version-based check will be performed and outdated requests discarded.
12113                }
12114            }
12115            anyhow::Ok(())
12116        })??;
12117
12118        Ok(())
12119    }
12120
12121    async fn query_lsp_locally<T>(
12122        lsp_store: Entity<Self>,
12123        for_server_id: Option<LanguageServerId>,
12124        sender_id: proto::PeerId,
12125        lsp_request_id: LspRequestId,
12126        proto_request: T::ProtoRequest,
12127        position: Option<Anchor>,
12128        cx: &mut AsyncApp,
12129    ) -> Result<()>
12130    where
12131        T: LspCommand + Clone,
12132        T::ProtoRequest: proto::LspRequestMessage,
12133        <T::ProtoRequest as proto::RequestMessage>::Response:
12134            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12135    {
12136        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12137        let version = deserialize_version(proto_request.buffer_version());
12138        let buffer = lsp_store.update(cx, |this, cx| {
12139            this.buffer_store.read(cx).get_existing(buffer_id)
12140        })??;
12141        buffer
12142            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12143            .await?;
12144        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12145        let request =
12146            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12147        let key = LspKey {
12148            request_type: TypeId::of::<T>(),
12149            server_queried: for_server_id,
12150        };
12151        lsp_store.update(cx, |lsp_store, cx| {
12152            let request_task = match for_server_id {
12153                Some(server_id) => {
12154                    let server_task = lsp_store.request_lsp(
12155                        buffer.clone(),
12156                        LanguageServerToQuery::Other(server_id),
12157                        request.clone(),
12158                        cx,
12159                    );
12160                    cx.background_spawn(async move {
12161                        let mut responses = Vec::new();
12162                        match server_task.await {
12163                            Ok(response) => responses.push((server_id, response)),
12164                            Err(e) => log::error!(
12165                                "Error handling response for request {request:?}: {e:#}"
12166                            ),
12167                        }
12168                        responses
12169                    })
12170                }
12171                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12172            };
12173            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12174            if T::ProtoRequest::stop_previous_requests() {
12175                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12176                    lsp_requests.clear();
12177                }
12178            }
12179            lsp_data.lsp_requests.entry(key).or_default().insert(
12180                lsp_request_id,
12181                cx.spawn(async move |lsp_store, cx| {
12182                    let response = request_task.await;
12183                    lsp_store
12184                        .update(cx, |lsp_store, cx| {
12185                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12186                            {
12187                                let response = response
12188                                    .into_iter()
12189                                    .map(|(server_id, response)| {
12190                                        (
12191                                            server_id.to_proto(),
12192                                            T::response_to_proto(
12193                                                response,
12194                                                lsp_store,
12195                                                sender_id,
12196                                                &buffer_version,
12197                                                cx,
12198                                            )
12199                                            .into(),
12200                                        )
12201                                    })
12202                                    .collect::<HashMap<_, _>>();
12203                                match client.send_lsp_response::<T::ProtoRequest>(
12204                                    project_id,
12205                                    lsp_request_id,
12206                                    response,
12207                                ) {
12208                                    Ok(()) => {}
12209                                    Err(e) => {
12210                                        log::error!("Failed to send LSP response: {e:#}",)
12211                                    }
12212                                }
12213                            }
12214                        })
12215                        .ok();
12216                }),
12217            );
12218        })?;
12219        Ok(())
12220    }
12221
12222    fn take_text_document_sync_options(
12223        capabilities: &mut lsp::ServerCapabilities,
12224    ) -> lsp::TextDocumentSyncOptions {
12225        match capabilities.text_document_sync.take() {
12226            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12227            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12228                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12229                sync_options.change = Some(sync_kind);
12230                sync_options
12231            }
12232            None => lsp::TextDocumentSyncOptions::default(),
12233        }
12234    }
12235
12236    #[cfg(any(test, feature = "test-support"))]
12237    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12238        Some(
12239            self.lsp_data
12240                .get_mut(&buffer_id)?
12241                .code_lens
12242                .take()?
12243                .update
12244                .take()?
12245                .1,
12246        )
12247    }
12248
12249    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12250        self.downstream_client.clone()
12251    }
12252
12253    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12254        self.worktree_store.clone()
12255    }
12256
12257    /// Gets what's stored in the LSP data for the given buffer.
12258    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12259        self.lsp_data.get_mut(&buffer_id)
12260    }
12261
12262    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12263    /// new [`BufferLspData`] will be created to replace the previous state.
12264    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12265        let (buffer_id, buffer_version) =
12266            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12267        let lsp_data = self
12268            .lsp_data
12269            .entry(buffer_id)
12270            .or_insert_with(|| BufferLspData::new(buffer, cx));
12271        if buffer_version.changed_since(&lsp_data.buffer_version) {
12272            *lsp_data = BufferLspData::new(buffer, cx);
12273        }
12274        lsp_data
12275    }
12276}
12277
12278// Registration with registerOptions as null, should fallback to true.
12279// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12280fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12281    reg: lsp::Registration,
12282) -> Result<OneOf<bool, T>> {
12283    Ok(match reg.register_options {
12284        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12285        None => OneOf::Left(true),
12286    })
12287}
12288
12289fn subscribe_to_binary_statuses(
12290    languages: &Arc<LanguageRegistry>,
12291    cx: &mut Context<'_, LspStore>,
12292) -> Task<()> {
12293    let mut server_statuses = languages.language_server_binary_statuses();
12294    cx.spawn(async move |lsp_store, cx| {
12295        while let Some((server_name, binary_status)) = server_statuses.next().await {
12296            if lsp_store
12297                .update(cx, |_, cx| {
12298                    let mut message = None;
12299                    let binary_status = match binary_status {
12300                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12301                        BinaryStatus::CheckingForUpdate => {
12302                            proto::ServerBinaryStatus::CheckingForUpdate
12303                        }
12304                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12305                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12306                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12307                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12308                        BinaryStatus::Failed { error } => {
12309                            message = Some(error);
12310                            proto::ServerBinaryStatus::Failed
12311                        }
12312                    };
12313                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12314                        // Binary updates are about the binary that might not have any language server id at that point.
12315                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12316                        language_server_id: LanguageServerId(0),
12317                        name: Some(server_name),
12318                        message: proto::update_language_server::Variant::StatusUpdate(
12319                            proto::StatusUpdate {
12320                                message,
12321                                status: Some(proto::status_update::Status::Binary(
12322                                    binary_status as i32,
12323                                )),
12324                            },
12325                        ),
12326                    });
12327                })
12328                .is_err()
12329            {
12330                break;
12331            }
12332        }
12333    })
12334}
12335
12336fn lsp_workspace_diagnostics_refresh(
12337    server: Arc<LanguageServer>,
12338    cx: &mut Context<'_, LspStore>,
12339) -> Option<WorkspaceRefreshTask> {
12340    let identifier = match server.capabilities().diagnostic_provider? {
12341        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12342            if !diagnostic_options.workspace_diagnostics {
12343                return None;
12344            }
12345            diagnostic_options.identifier
12346        }
12347        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12348            let diagnostic_options = registration_options.diagnostic_options;
12349            if !diagnostic_options.workspace_diagnostics {
12350                return None;
12351            }
12352            diagnostic_options.identifier
12353        }
12354    };
12355
12356    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12357    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12358    refresh_tx.try_send(()).ok();
12359
12360    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12361        let mut attempts = 0;
12362        let max_attempts = 50;
12363        let mut requests = 0;
12364
12365        loop {
12366            let Some(()) = refresh_rx.recv().await else {
12367                return;
12368            };
12369
12370            'request: loop {
12371                requests += 1;
12372                if attempts > max_attempts {
12373                    log::error!(
12374                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12375                    );
12376                    return;
12377                }
12378                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12379                cx.background_executor()
12380                    .timer(Duration::from_millis(backoff_millis))
12381                    .await;
12382                attempts += 1;
12383
12384                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12385                    lsp_store
12386                        .all_result_ids(server.server_id())
12387                        .into_iter()
12388                        .filter_map(|(abs_path, result_id)| {
12389                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12390                            Some(lsp::PreviousResultId {
12391                                uri,
12392                                value: result_id,
12393                            })
12394                        })
12395                        .collect()
12396                }) else {
12397                    return;
12398                };
12399
12400                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
12401
12402                progress_rx.try_recv().ok();
12403                let timer =
12404                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12405                let progress = pin!(progress_rx.recv().fuse());
12406                let response_result = server
12407                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12408                        lsp::WorkspaceDiagnosticParams {
12409                            previous_result_ids,
12410                            identifier: identifier.clone(),
12411                            work_done_progress_params: Default::default(),
12412                            partial_result_params: lsp::PartialResultParams {
12413                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12414                            },
12415                        },
12416                        select(timer, progress).then(|either| match either {
12417                            Either::Left((message, ..)) => ready(message).left_future(),
12418                            Either::Right(..) => pending::<String>().right_future(),
12419                        }),
12420                    )
12421                    .await;
12422
12423                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12424                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12425                match response_result {
12426                    ConnectionResult::Timeout => {
12427                        log::error!("Timeout during workspace diagnostics pull");
12428                        continue 'request;
12429                    }
12430                    ConnectionResult::ConnectionReset => {
12431                        log::error!("Server closed a workspace diagnostics pull request");
12432                        continue 'request;
12433                    }
12434                    ConnectionResult::Result(Err(e)) => {
12435                        log::error!("Error during workspace diagnostics pull: {e:#}");
12436                        break 'request;
12437                    }
12438                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12439                        attempts = 0;
12440                        if lsp_store
12441                            .update(cx, |lsp_store, cx| {
12442                                lsp_store.apply_workspace_diagnostic_report(
12443                                    server.server_id(),
12444                                    pulled_diagnostics,
12445                                    cx,
12446                                )
12447                            })
12448                            .is_err()
12449                        {
12450                            return;
12451                        }
12452                        break 'request;
12453                    }
12454                }
12455            }
12456        }
12457    });
12458
12459    Some(WorkspaceRefreshTask {
12460        refresh_tx,
12461        progress_tx,
12462        task: workspace_query_language_server,
12463    })
12464}
12465
12466fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12467    let CompletionSource::BufferWord {
12468        word_range,
12469        resolved,
12470    } = &mut completion.source
12471    else {
12472        return;
12473    };
12474    if *resolved {
12475        return;
12476    }
12477
12478    if completion.new_text
12479        != snapshot
12480            .text_for_range(word_range.clone())
12481            .collect::<String>()
12482    {
12483        return;
12484    }
12485
12486    let mut offset = 0;
12487    for chunk in snapshot.chunks(word_range.clone(), true) {
12488        let end_offset = offset + chunk.text.len();
12489        if let Some(highlight_id) = chunk.syntax_highlight_id {
12490            completion
12491                .label
12492                .runs
12493                .push((offset..end_offset, highlight_id));
12494        }
12495        offset = end_offset;
12496    }
12497    *resolved = true;
12498}
12499
12500impl EventEmitter<LspStoreEvent> for LspStore {}
12501
12502fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12503    hover
12504        .contents
12505        .retain(|hover_block| !hover_block.text.trim().is_empty());
12506    if hover.contents.is_empty() {
12507        None
12508    } else {
12509        Some(hover)
12510    }
12511}
12512
12513async fn populate_labels_for_completions(
12514    new_completions: Vec<CoreCompletion>,
12515    language: Option<Arc<Language>>,
12516    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12517) -> Vec<Completion> {
12518    let lsp_completions = new_completions
12519        .iter()
12520        .filter_map(|new_completion| {
12521            new_completion
12522                .source
12523                .lsp_completion(true)
12524                .map(|lsp_completion| lsp_completion.into_owned())
12525        })
12526        .collect::<Vec<_>>();
12527
12528    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12529        lsp_adapter
12530            .labels_for_completions(&lsp_completions, language)
12531            .await
12532            .log_err()
12533            .unwrap_or_default()
12534    } else {
12535        Vec::new()
12536    }
12537    .into_iter()
12538    .fuse();
12539
12540    let mut completions = Vec::new();
12541    for completion in new_completions {
12542        match completion.source.lsp_completion(true) {
12543            Some(lsp_completion) => {
12544                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12545
12546                let mut label = labels.next().flatten().unwrap_or_else(|| {
12547                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12548                });
12549                ensure_uniform_list_compatible_label(&mut label);
12550                completions.push(Completion {
12551                    label,
12552                    documentation,
12553                    replace_range: completion.replace_range,
12554                    new_text: completion.new_text,
12555                    insert_text_mode: lsp_completion.insert_text_mode,
12556                    source: completion.source,
12557                    icon_path: None,
12558                    confirm: None,
12559                    match_start: None,
12560                });
12561            }
12562            None => {
12563                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12564                ensure_uniform_list_compatible_label(&mut label);
12565                completions.push(Completion {
12566                    label,
12567                    documentation: None,
12568                    replace_range: completion.replace_range,
12569                    new_text: completion.new_text,
12570                    source: completion.source,
12571                    insert_text_mode: None,
12572                    icon_path: None,
12573                    confirm: None,
12574                    match_start: None,
12575                });
12576            }
12577        }
12578    }
12579    completions
12580}
12581
12582#[derive(Debug)]
12583pub enum LanguageServerToQuery {
12584    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12585    FirstCapable,
12586    /// Query a specific language server.
12587    Other(LanguageServerId),
12588}
12589
12590#[derive(Default)]
12591struct RenamePathsWatchedForServer {
12592    did_rename: Vec<RenameActionPredicate>,
12593    will_rename: Vec<RenameActionPredicate>,
12594}
12595
12596impl RenamePathsWatchedForServer {
12597    fn with_did_rename_patterns(
12598        mut self,
12599        did_rename: Option<&FileOperationRegistrationOptions>,
12600    ) -> Self {
12601        if let Some(did_rename) = did_rename {
12602            self.did_rename = did_rename
12603                .filters
12604                .iter()
12605                .filter_map(|filter| filter.try_into().log_err())
12606                .collect();
12607        }
12608        self
12609    }
12610    fn with_will_rename_patterns(
12611        mut self,
12612        will_rename: Option<&FileOperationRegistrationOptions>,
12613    ) -> Self {
12614        if let Some(will_rename) = will_rename {
12615            self.will_rename = will_rename
12616                .filters
12617                .iter()
12618                .filter_map(|filter| filter.try_into().log_err())
12619                .collect();
12620        }
12621        self
12622    }
12623
12624    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12625        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12626    }
12627    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12628        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12629    }
12630}
12631
12632impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12633    type Error = globset::Error;
12634    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12635        Ok(Self {
12636            kind: ops.pattern.matches.clone(),
12637            glob: GlobBuilder::new(&ops.pattern.glob)
12638                .case_insensitive(
12639                    ops.pattern
12640                        .options
12641                        .as_ref()
12642                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12643                )
12644                .build()?
12645                .compile_matcher(),
12646        })
12647    }
12648}
12649struct RenameActionPredicate {
12650    glob: GlobMatcher,
12651    kind: Option<FileOperationPatternKind>,
12652}
12653
12654impl RenameActionPredicate {
12655    // Returns true if language server should be notified
12656    fn eval(&self, path: &str, is_dir: bool) -> bool {
12657        self.kind.as_ref().is_none_or(|kind| {
12658            let expected_kind = if is_dir {
12659                FileOperationPatternKind::Folder
12660            } else {
12661                FileOperationPatternKind::File
12662            };
12663            kind == &expected_kind
12664        }) && self.glob.is_match(path)
12665    }
12666}
12667
12668#[derive(Default)]
12669struct LanguageServerWatchedPaths {
12670    worktree_paths: HashMap<WorktreeId, GlobSet>,
12671    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12672}
12673
12674#[derive(Default)]
12675struct LanguageServerWatchedPathsBuilder {
12676    worktree_paths: HashMap<WorktreeId, GlobSet>,
12677    abs_paths: HashMap<Arc<Path>, GlobSet>,
12678}
12679
12680impl LanguageServerWatchedPathsBuilder {
12681    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12682        self.worktree_paths.insert(worktree_id, glob_set);
12683    }
12684    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12685        self.abs_paths.insert(path, glob_set);
12686    }
12687    fn build(
12688        self,
12689        fs: Arc<dyn Fs>,
12690        language_server_id: LanguageServerId,
12691        cx: &mut Context<LspStore>,
12692    ) -> LanguageServerWatchedPaths {
12693        let project = cx.weak_entity();
12694
12695        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12696        let abs_paths = self
12697            .abs_paths
12698            .into_iter()
12699            .map(|(abs_path, globset)| {
12700                let task = cx.spawn({
12701                    let abs_path = abs_path.clone();
12702                    let fs = fs.clone();
12703
12704                    let lsp_store = project.clone();
12705                    async move |_, cx| {
12706                        maybe!(async move {
12707                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12708                            while let Some(update) = push_updates.0.next().await {
12709                                let action = lsp_store
12710                                    .update(cx, |this, _| {
12711                                        let Some(local) = this.as_local() else {
12712                                            return ControlFlow::Break(());
12713                                        };
12714                                        let Some(watcher) = local
12715                                            .language_server_watched_paths
12716                                            .get(&language_server_id)
12717                                        else {
12718                                            return ControlFlow::Break(());
12719                                        };
12720                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12721                                            "Watched abs path is not registered with a watcher",
12722                                        );
12723                                        let matching_entries = update
12724                                            .into_iter()
12725                                            .filter(|event| globs.is_match(&event.path))
12726                                            .collect::<Vec<_>>();
12727                                        this.lsp_notify_abs_paths_changed(
12728                                            language_server_id,
12729                                            matching_entries,
12730                                        );
12731                                        ControlFlow::Continue(())
12732                                    })
12733                                    .ok()?;
12734
12735                                if action.is_break() {
12736                                    break;
12737                                }
12738                            }
12739                            Some(())
12740                        })
12741                        .await;
12742                    }
12743                });
12744                (abs_path, (globset, task))
12745            })
12746            .collect();
12747        LanguageServerWatchedPaths {
12748            worktree_paths: self.worktree_paths,
12749            abs_paths,
12750        }
12751    }
12752}
12753
12754struct LspBufferSnapshot {
12755    version: i32,
12756    snapshot: TextBufferSnapshot,
12757}
12758
12759/// A prompt requested by LSP server.
12760#[derive(Clone, Debug)]
12761pub struct LanguageServerPromptRequest {
12762    pub level: PromptLevel,
12763    pub message: String,
12764    pub actions: Vec<MessageActionItem>,
12765    pub lsp_name: String,
12766    pub(crate) response_channel: Sender<MessageActionItem>,
12767}
12768
12769impl LanguageServerPromptRequest {
12770    pub async fn respond(self, index: usize) -> Option<()> {
12771        if let Some(response) = self.actions.into_iter().nth(index) {
12772            self.response_channel.send(response).await.ok()
12773        } else {
12774            None
12775        }
12776    }
12777}
12778impl PartialEq for LanguageServerPromptRequest {
12779    fn eq(&self, other: &Self) -> bool {
12780        self.message == other.message && self.actions == other.actions
12781    }
12782}
12783
12784#[derive(Clone, Debug, PartialEq)]
12785pub enum LanguageServerLogType {
12786    Log(MessageType),
12787    Trace { verbose_info: Option<String> },
12788    Rpc { received: bool },
12789}
12790
12791impl LanguageServerLogType {
12792    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12793        match self {
12794            Self::Log(log_type) => {
12795                use proto::log_message::LogLevel;
12796                let level = match *log_type {
12797                    MessageType::ERROR => LogLevel::Error,
12798                    MessageType::WARNING => LogLevel::Warning,
12799                    MessageType::INFO => LogLevel::Info,
12800                    MessageType::LOG => LogLevel::Log,
12801                    other => {
12802                        log::warn!("Unknown lsp log message type: {other:?}");
12803                        LogLevel::Log
12804                    }
12805                };
12806                proto::language_server_log::LogType::Log(proto::LogMessage {
12807                    level: level as i32,
12808                })
12809            }
12810            Self::Trace { verbose_info } => {
12811                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12812                    verbose_info: verbose_info.to_owned(),
12813                })
12814            }
12815            Self::Rpc { received } => {
12816                let kind = if *received {
12817                    proto::rpc_message::Kind::Received
12818                } else {
12819                    proto::rpc_message::Kind::Sent
12820                };
12821                let kind = kind as i32;
12822                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12823            }
12824        }
12825    }
12826
12827    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12828        use proto::log_message::LogLevel;
12829        use proto::rpc_message;
12830        match log_type {
12831            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12832                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12833                    LogLevel::Error => MessageType::ERROR,
12834                    LogLevel::Warning => MessageType::WARNING,
12835                    LogLevel::Info => MessageType::INFO,
12836                    LogLevel::Log => MessageType::LOG,
12837                },
12838            ),
12839            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12840                verbose_info: trace_message.verbose_info,
12841            },
12842            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12843                received: match rpc_message::Kind::from_i32(message.kind)
12844                    .unwrap_or(rpc_message::Kind::Received)
12845                {
12846                    rpc_message::Kind::Received => true,
12847                    rpc_message::Kind::Sent => false,
12848                },
12849            },
12850        }
12851    }
12852}
12853
12854pub struct WorkspaceRefreshTask {
12855    refresh_tx: mpsc::Sender<()>,
12856    progress_tx: mpsc::Sender<()>,
12857    #[allow(dead_code)]
12858    task: Task<()>,
12859}
12860
12861pub enum LanguageServerState {
12862    Starting {
12863        startup: Task<Option<Arc<LanguageServer>>>,
12864        /// List of language servers that will be added to the workspace once it's initialization completes.
12865        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
12866    },
12867
12868    Running {
12869        adapter: Arc<CachedLspAdapter>,
12870        server: Arc<LanguageServer>,
12871        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12872        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12873    },
12874}
12875
12876impl LanguageServerState {
12877    fn add_workspace_folder(&self, uri: Uri) {
12878        match self {
12879            LanguageServerState::Starting {
12880                pending_workspace_folders,
12881                ..
12882            } => {
12883                pending_workspace_folders.lock().insert(uri);
12884            }
12885            LanguageServerState::Running { server, .. } => {
12886                server.add_workspace_folder(uri);
12887            }
12888        }
12889    }
12890    fn _remove_workspace_folder(&self, uri: Uri) {
12891        match self {
12892            LanguageServerState::Starting {
12893                pending_workspace_folders,
12894                ..
12895            } => {
12896                pending_workspace_folders.lock().remove(&uri);
12897            }
12898            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12899        }
12900    }
12901}
12902
12903impl std::fmt::Debug for LanguageServerState {
12904    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12905        match self {
12906            LanguageServerState::Starting { .. } => {
12907                f.debug_struct("LanguageServerState::Starting").finish()
12908            }
12909            LanguageServerState::Running { .. } => {
12910                f.debug_struct("LanguageServerState::Running").finish()
12911            }
12912        }
12913    }
12914}
12915
12916#[derive(Clone, Debug, Serialize)]
12917pub struct LanguageServerProgress {
12918    pub is_disk_based_diagnostics_progress: bool,
12919    pub is_cancellable: bool,
12920    pub title: Option<String>,
12921    pub message: Option<String>,
12922    pub percentage: Option<usize>,
12923    #[serde(skip_serializing)]
12924    pub last_update_at: Instant,
12925}
12926
12927#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12928pub struct DiagnosticSummary {
12929    pub error_count: usize,
12930    pub warning_count: usize,
12931}
12932
12933impl DiagnosticSummary {
12934    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12935        let mut this = Self {
12936            error_count: 0,
12937            warning_count: 0,
12938        };
12939
12940        for entry in diagnostics {
12941            if entry.diagnostic.is_primary {
12942                match entry.diagnostic.severity {
12943                    DiagnosticSeverity::ERROR => this.error_count += 1,
12944                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12945                    _ => {}
12946                }
12947            }
12948        }
12949
12950        this
12951    }
12952
12953    pub fn is_empty(&self) -> bool {
12954        self.error_count == 0 && self.warning_count == 0
12955    }
12956
12957    pub fn to_proto(
12958        self,
12959        language_server_id: LanguageServerId,
12960        path: &RelPath,
12961    ) -> proto::DiagnosticSummary {
12962        proto::DiagnosticSummary {
12963            path: path.to_proto(),
12964            language_server_id: language_server_id.0 as u64,
12965            error_count: self.error_count as u32,
12966            warning_count: self.warning_count as u32,
12967        }
12968    }
12969}
12970
12971#[derive(Clone, Debug)]
12972pub enum CompletionDocumentation {
12973    /// There is no documentation for this completion.
12974    Undocumented,
12975    /// A single line of documentation.
12976    SingleLine(SharedString),
12977    /// Multiple lines of plain text documentation.
12978    MultiLinePlainText(SharedString),
12979    /// Markdown documentation.
12980    MultiLineMarkdown(SharedString),
12981    /// Both single line and multiple lines of plain text documentation.
12982    SingleLineAndMultiLinePlainText {
12983        single_line: SharedString,
12984        plain_text: Option<SharedString>,
12985    },
12986}
12987
12988impl CompletionDocumentation {
12989    #[cfg(any(test, feature = "test-support"))]
12990    pub fn text(&self) -> SharedString {
12991        match self {
12992            CompletionDocumentation::Undocumented => "".into(),
12993            CompletionDocumentation::SingleLine(s) => s.clone(),
12994            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
12995            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
12996            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
12997                single_line.clone()
12998            }
12999        }
13000    }
13001}
13002
13003impl From<lsp::Documentation> for CompletionDocumentation {
13004    fn from(docs: lsp::Documentation) -> Self {
13005        match docs {
13006            lsp::Documentation::String(text) => {
13007                if text.lines().count() <= 1 {
13008                    CompletionDocumentation::SingleLine(text.into())
13009                } else {
13010                    CompletionDocumentation::MultiLinePlainText(text.into())
13011                }
13012            }
13013
13014            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13015                lsp::MarkupKind::PlainText => {
13016                    if value.lines().count() <= 1 {
13017                        CompletionDocumentation::SingleLine(value.into())
13018                    } else {
13019                        CompletionDocumentation::MultiLinePlainText(value.into())
13020                    }
13021                }
13022
13023                lsp::MarkupKind::Markdown => {
13024                    CompletionDocumentation::MultiLineMarkdown(value.into())
13025                }
13026            },
13027        }
13028    }
13029}
13030
13031pub enum ResolvedHint {
13032    Resolved(InlayHint),
13033    Resolving(Shared<Task<()>>),
13034}
13035
13036fn glob_literal_prefix(glob: &Path) -> PathBuf {
13037    glob.components()
13038        .take_while(|component| match component {
13039            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13040            _ => true,
13041        })
13042        .collect()
13043}
13044
13045pub struct SshLspAdapter {
13046    name: LanguageServerName,
13047    binary: LanguageServerBinary,
13048    initialization_options: Option<String>,
13049    code_action_kinds: Option<Vec<CodeActionKind>>,
13050}
13051
13052impl SshLspAdapter {
13053    pub fn new(
13054        name: LanguageServerName,
13055        binary: LanguageServerBinary,
13056        initialization_options: Option<String>,
13057        code_action_kinds: Option<String>,
13058    ) -> Self {
13059        Self {
13060            name,
13061            binary,
13062            initialization_options,
13063            code_action_kinds: code_action_kinds
13064                .as_ref()
13065                .and_then(|c| serde_json::from_str(c).ok()),
13066        }
13067    }
13068}
13069
13070impl LspInstaller for SshLspAdapter {
13071    type BinaryVersion = ();
13072    async fn check_if_user_installed(
13073        &self,
13074        _: &dyn LspAdapterDelegate,
13075        _: Option<Toolchain>,
13076        _: &AsyncApp,
13077    ) -> Option<LanguageServerBinary> {
13078        Some(self.binary.clone())
13079    }
13080
13081    async fn cached_server_binary(
13082        &self,
13083        _: PathBuf,
13084        _: &dyn LspAdapterDelegate,
13085    ) -> Option<LanguageServerBinary> {
13086        None
13087    }
13088
13089    async fn fetch_latest_server_version(
13090        &self,
13091        _: &dyn LspAdapterDelegate,
13092        _: bool,
13093        _: &mut AsyncApp,
13094    ) -> Result<()> {
13095        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13096    }
13097
13098    async fn fetch_server_binary(
13099        &self,
13100        _: (),
13101        _: PathBuf,
13102        _: &dyn LspAdapterDelegate,
13103    ) -> Result<LanguageServerBinary> {
13104        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13105    }
13106}
13107
13108#[async_trait(?Send)]
13109impl LspAdapter for SshLspAdapter {
13110    fn name(&self) -> LanguageServerName {
13111        self.name.clone()
13112    }
13113
13114    async fn initialization_options(
13115        self: Arc<Self>,
13116        _: &Arc<dyn LspAdapterDelegate>,
13117    ) -> Result<Option<serde_json::Value>> {
13118        let Some(options) = &self.initialization_options else {
13119            return Ok(None);
13120        };
13121        let result = serde_json::from_str(options)?;
13122        Ok(result)
13123    }
13124
13125    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13126        self.code_action_kinds.clone()
13127    }
13128}
13129
13130pub fn language_server_settings<'a>(
13131    delegate: &'a dyn LspAdapterDelegate,
13132    language: &LanguageServerName,
13133    cx: &'a App,
13134) -> Option<&'a LspSettings> {
13135    language_server_settings_for(
13136        SettingsLocation {
13137            worktree_id: delegate.worktree_id(),
13138            path: RelPath::empty(),
13139        },
13140        language,
13141        cx,
13142    )
13143}
13144
13145pub(crate) fn language_server_settings_for<'a>(
13146    location: SettingsLocation<'a>,
13147    language: &LanguageServerName,
13148    cx: &'a App,
13149) -> Option<&'a LspSettings> {
13150    ProjectSettings::get(Some(location), cx).lsp.get(language)
13151}
13152
13153pub struct LocalLspAdapterDelegate {
13154    lsp_store: WeakEntity<LspStore>,
13155    worktree: worktree::Snapshot,
13156    fs: Arc<dyn Fs>,
13157    http_client: Arc<dyn HttpClient>,
13158    language_registry: Arc<LanguageRegistry>,
13159    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13160}
13161
13162impl LocalLspAdapterDelegate {
13163    pub fn new(
13164        language_registry: Arc<LanguageRegistry>,
13165        environment: &Entity<ProjectEnvironment>,
13166        lsp_store: WeakEntity<LspStore>,
13167        worktree: &Entity<Worktree>,
13168        http_client: Arc<dyn HttpClient>,
13169        fs: Arc<dyn Fs>,
13170        cx: &mut App,
13171    ) -> Arc<Self> {
13172        let load_shell_env_task = environment.update(cx, |env, cx| {
13173            env.get_worktree_environment(worktree.clone(), cx)
13174        });
13175
13176        Arc::new(Self {
13177            lsp_store,
13178            worktree: worktree.read(cx).snapshot(),
13179            fs,
13180            http_client,
13181            language_registry,
13182            load_shell_env_task,
13183        })
13184    }
13185
13186    fn from_local_lsp(
13187        local: &LocalLspStore,
13188        worktree: &Entity<Worktree>,
13189        cx: &mut App,
13190    ) -> Arc<Self> {
13191        Self::new(
13192            local.languages.clone(),
13193            &local.environment,
13194            local.weak.clone(),
13195            worktree,
13196            local.http_client.clone(),
13197            local.fs.clone(),
13198            cx,
13199        )
13200    }
13201}
13202
13203#[async_trait]
13204impl LspAdapterDelegate for LocalLspAdapterDelegate {
13205    fn show_notification(&self, message: &str, cx: &mut App) {
13206        self.lsp_store
13207            .update(cx, |_, cx| {
13208                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13209            })
13210            .ok();
13211    }
13212
13213    fn http_client(&self) -> Arc<dyn HttpClient> {
13214        self.http_client.clone()
13215    }
13216
13217    fn worktree_id(&self) -> WorktreeId {
13218        self.worktree.id()
13219    }
13220
13221    fn worktree_root_path(&self) -> &Path {
13222        self.worktree.abs_path().as_ref()
13223    }
13224
13225    async fn shell_env(&self) -> HashMap<String, String> {
13226        let task = self.load_shell_env_task.clone();
13227        task.await.unwrap_or_default()
13228    }
13229
13230    async fn npm_package_installed_version(
13231        &self,
13232        package_name: &str,
13233    ) -> Result<Option<(PathBuf, String)>> {
13234        let local_package_directory = self.worktree_root_path();
13235        let node_modules_directory = local_package_directory.join("node_modules");
13236
13237        if let Some(version) =
13238            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13239        {
13240            return Ok(Some((node_modules_directory, version)));
13241        }
13242        let Some(npm) = self.which("npm".as_ref()).await else {
13243            log::warn!(
13244                "Failed to find npm executable for {:?}",
13245                local_package_directory
13246            );
13247            return Ok(None);
13248        };
13249
13250        let env = self.shell_env().await;
13251        let output = util::command::new_smol_command(&npm)
13252            .args(["root", "-g"])
13253            .envs(env)
13254            .current_dir(local_package_directory)
13255            .output()
13256            .await?;
13257        let global_node_modules =
13258            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13259
13260        if let Some(version) =
13261            read_package_installed_version(global_node_modules.clone(), package_name).await?
13262        {
13263            return Ok(Some((global_node_modules, version)));
13264        }
13265        return Ok(None);
13266    }
13267
13268    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13269        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13270        if self.fs.is_file(&worktree_abs_path).await {
13271            worktree_abs_path.pop();
13272        }
13273
13274        let env = self.shell_env().await;
13275
13276        let shell_path = env.get("PATH").cloned();
13277
13278        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13279    }
13280
13281    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13282        let mut working_dir = self.worktree_root_path().to_path_buf();
13283        if self.fs.is_file(&working_dir).await {
13284            working_dir.pop();
13285        }
13286        let output = util::command::new_smol_command(&command.path)
13287            .args(command.arguments)
13288            .envs(command.env.clone().unwrap_or_default())
13289            .current_dir(working_dir)
13290            .output()
13291            .await?;
13292
13293        anyhow::ensure!(
13294            output.status.success(),
13295            "{}, stdout: {:?}, stderr: {:?}",
13296            output.status,
13297            String::from_utf8_lossy(&output.stdout),
13298            String::from_utf8_lossy(&output.stderr)
13299        );
13300        Ok(())
13301    }
13302
13303    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13304        self.language_registry
13305            .update_lsp_binary_status(server_name, status);
13306    }
13307
13308    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13309        self.language_registry
13310            .all_lsp_adapters()
13311            .into_iter()
13312            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13313            .collect()
13314    }
13315
13316    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13317        let dir = self.language_registry.language_server_download_dir(name)?;
13318
13319        if !dir.exists() {
13320            smol::fs::create_dir_all(&dir)
13321                .await
13322                .context("failed to create container directory")
13323                .log_err()?;
13324        }
13325
13326        Some(dir)
13327    }
13328
13329    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13330        let entry = self
13331            .worktree
13332            .entry_for_path(path)
13333            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13334        let abs_path = self.worktree.absolutize(&entry.path);
13335        self.fs.load(&abs_path).await
13336    }
13337}
13338
13339async fn populate_labels_for_symbols(
13340    symbols: Vec<CoreSymbol>,
13341    language_registry: &Arc<LanguageRegistry>,
13342    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13343    output: &mut Vec<Symbol>,
13344) {
13345    #[allow(clippy::mutable_key_type)]
13346    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13347
13348    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13349    for symbol in symbols {
13350        let Some(file_name) = symbol.path.file_name() else {
13351            continue;
13352        };
13353        let language = language_registry
13354            .load_language_for_file_path(Path::new(file_name))
13355            .await
13356            .ok()
13357            .or_else(|| {
13358                unknown_paths.insert(file_name.into());
13359                None
13360            });
13361        symbols_by_language
13362            .entry(language)
13363            .or_default()
13364            .push(symbol);
13365    }
13366
13367    for unknown_path in unknown_paths {
13368        log::info!("no language found for symbol in file {unknown_path:?}");
13369    }
13370
13371    let mut label_params = Vec::new();
13372    for (language, mut symbols) in symbols_by_language {
13373        label_params.clear();
13374        label_params.extend(
13375            symbols
13376                .iter_mut()
13377                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13378        );
13379
13380        let mut labels = Vec::new();
13381        if let Some(language) = language {
13382            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13383                language_registry
13384                    .lsp_adapters(&language.name())
13385                    .first()
13386                    .cloned()
13387            });
13388            if let Some(lsp_adapter) = lsp_adapter {
13389                labels = lsp_adapter
13390                    .labels_for_symbols(&label_params, &language)
13391                    .await
13392                    .log_err()
13393                    .unwrap_or_default();
13394            }
13395        }
13396
13397        for ((symbol, (name, _)), label) in symbols
13398            .into_iter()
13399            .zip(label_params.drain(..))
13400            .zip(labels.into_iter().chain(iter::repeat(None)))
13401        {
13402            output.push(Symbol {
13403                language_server_name: symbol.language_server_name,
13404                source_worktree_id: symbol.source_worktree_id,
13405                source_language_server_id: symbol.source_language_server_id,
13406                path: symbol.path,
13407                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13408                name,
13409                kind: symbol.kind,
13410                range: symbol.range,
13411            });
13412        }
13413    }
13414}
13415
13416fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13417    match server.capabilities().text_document_sync.as_ref()? {
13418        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13419            // Server wants didSave but didn't specify includeText.
13420            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13421            // Server doesn't want didSave at all.
13422            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13423            // Server provided SaveOptions.
13424            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13425                Some(save_options.include_text.unwrap_or(false))
13426            }
13427        },
13428        // We do not have any save info. Kind affects didChange only.
13429        lsp::TextDocumentSyncCapability::Kind(_) => None,
13430    }
13431}
13432
13433/// Completion items are displayed in a `UniformList`.
13434/// Usually, those items are single-line strings, but in LSP responses,
13435/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13436/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13437/// 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,
13438/// breaking the completions menu presentation.
13439///
13440/// 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.
13441fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13442    let mut new_text = String::with_capacity(label.text.len());
13443    let mut offset_map = vec![0; label.text.len() + 1];
13444    let mut last_char_was_space = false;
13445    let mut new_idx = 0;
13446    let chars = label.text.char_indices().fuse();
13447    let mut newlines_removed = false;
13448
13449    for (idx, c) in chars {
13450        offset_map[idx] = new_idx;
13451
13452        match c {
13453            '\n' if last_char_was_space => {
13454                newlines_removed = true;
13455            }
13456            '\t' | ' ' if last_char_was_space => {}
13457            '\n' if !last_char_was_space => {
13458                new_text.push(' ');
13459                new_idx += 1;
13460                last_char_was_space = true;
13461                newlines_removed = true;
13462            }
13463            ' ' | '\t' => {
13464                new_text.push(' ');
13465                new_idx += 1;
13466                last_char_was_space = true;
13467            }
13468            _ => {
13469                new_text.push(c);
13470                new_idx += c.len_utf8();
13471                last_char_was_space = false;
13472            }
13473        }
13474    }
13475    offset_map[label.text.len()] = new_idx;
13476
13477    // Only modify the label if newlines were removed.
13478    if !newlines_removed {
13479        return;
13480    }
13481
13482    let last_index = new_idx;
13483    let mut run_ranges_errors = Vec::new();
13484    label.runs.retain_mut(|(range, _)| {
13485        match offset_map.get(range.start) {
13486            Some(&start) => range.start = start,
13487            None => {
13488                run_ranges_errors.push(range.clone());
13489                return false;
13490            }
13491        }
13492
13493        match offset_map.get(range.end) {
13494            Some(&end) => range.end = end,
13495            None => {
13496                run_ranges_errors.push(range.clone());
13497                range.end = last_index;
13498            }
13499        }
13500        true
13501    });
13502    if !run_ranges_errors.is_empty() {
13503        log::error!(
13504            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13505            label.text
13506        );
13507    }
13508
13509    let mut wrong_filter_range = None;
13510    if label.filter_range == (0..label.text.len()) {
13511        label.filter_range = 0..new_text.len();
13512    } else {
13513        let mut original_filter_range = Some(label.filter_range.clone());
13514        match offset_map.get(label.filter_range.start) {
13515            Some(&start) => label.filter_range.start = start,
13516            None => {
13517                wrong_filter_range = original_filter_range.take();
13518                label.filter_range.start = last_index;
13519            }
13520        }
13521
13522        match offset_map.get(label.filter_range.end) {
13523            Some(&end) => label.filter_range.end = end,
13524            None => {
13525                wrong_filter_range = original_filter_range.take();
13526                label.filter_range.end = last_index;
13527            }
13528        }
13529    }
13530    if let Some(wrong_filter_range) = wrong_filter_range {
13531        log::error!(
13532            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13533            label.text
13534        );
13535    }
13536
13537    label.text = new_text;
13538}
13539
13540#[cfg(test)]
13541mod tests {
13542    use language::HighlightId;
13543
13544    use super::*;
13545
13546    #[test]
13547    fn test_glob_literal_prefix() {
13548        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13549        assert_eq!(
13550            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13551            Path::new("node_modules")
13552        );
13553        assert_eq!(
13554            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13555            Path::new("foo")
13556        );
13557        assert_eq!(
13558            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13559            Path::new("foo/bar/baz.js")
13560        );
13561
13562        #[cfg(target_os = "windows")]
13563        {
13564            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13565            assert_eq!(
13566                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13567                Path::new("node_modules")
13568            );
13569            assert_eq!(
13570                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13571                Path::new("foo")
13572            );
13573            assert_eq!(
13574                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13575                Path::new("foo/bar/baz.js")
13576            );
13577        }
13578    }
13579
13580    #[test]
13581    fn test_multi_len_chars_normalization() {
13582        let mut label = CodeLabel::new(
13583            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13584            0..6,
13585            vec![(0..6, HighlightId(1))],
13586        );
13587        ensure_uniform_list_compatible_label(&mut label);
13588        assert_eq!(
13589            label,
13590            CodeLabel::new(
13591                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13592                0..6,
13593                vec![(0..6, HighlightId(1))],
13594            )
13595        );
13596    }
13597}