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        log_store::{GlobalLogStore, LanguageServerKind},
   33    },
   34    manifest_tree::{
   35        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   36        ManifestTree,
   37    },
   38    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   39    project_settings::{LspSettings, ProjectSettings},
   40    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   41    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   42    yarn::YarnPathStore,
   43};
   44use anyhow::{Context as _, Result, anyhow};
   45use async_trait::async_trait;
   46use client::{TypedEnvelope, proto};
   47use clock::Global;
   48use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   49use futures::{
   50    AsyncWriteExt, Future, FutureExt, StreamExt,
   51    future::{Either, Shared, join_all, pending, select},
   52    select, select_biased,
   53    stream::FuturesUnordered,
   54};
   55use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   56use gpui::{
   57    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   58    WeakEntity,
   59};
   60use http_client::HttpClient;
   61use itertools::Itertools as _;
   62use language::{
   63    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   64    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   65    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   66    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   67    Transaction, Unclipped,
   68    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   69    point_to_lsp,
   70    proto::{
   71        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   72        serialize_lsp_edit, serialize_version,
   73    },
   74    range_from_lsp, range_to_lsp,
   75    row_chunk::RowChunk,
   76};
   77use lsp::{
   78    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   79    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   80    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   81    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   82    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   83    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   84    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   85    WillRenameFiles, WorkDoneProgressCancelParams, 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 serde_json::Value;
   97use settings::{Settings, SettingsLocation, SettingsStore};
   98use sha2::{Digest, Sha256};
   99use smol::channel::Sender;
  100use snippet::Snippet;
  101use std::{
  102    any::TypeId,
  103    borrow::Cow,
  104    cell::RefCell,
  105    cmp::{Ordering, Reverse},
  106    convert::TryInto,
  107    ffi::OsStr,
  108    future::ready,
  109    iter, mem,
  110    ops::{ControlFlow, Range},
  111    path::{self, Path, PathBuf},
  112    pin::pin,
  113    rc::Rc,
  114    sync::{
  115        Arc,
  116        atomic::{self, AtomicUsize},
  117    },
  118    time::{Duration, Instant},
  119    vec,
  120};
  121use sum_tree::Dimensions;
  122use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  123
  124use util::{
  125    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  126    paths::{PathStyle, SanitizedPath},
  127    post_inc,
  128    rel_path::RelPath,
  129};
  130
  131pub use fs::*;
  132pub use language::Location;
  133pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  134#[cfg(any(test, feature = "test-support"))]
  135pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  136pub use worktree::{
  137    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  138    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  139};
  140
  141const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  142pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  143const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  144const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  145
  146#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  147pub enum ProgressToken {
  148    Number(i32),
  149    String(SharedString),
  150}
  151
  152impl std::fmt::Display for ProgressToken {
  153    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  154        match self {
  155            Self::Number(number) => write!(f, "{number}"),
  156            Self::String(string) => write!(f, "{string}"),
  157        }
  158    }
  159}
  160
  161impl ProgressToken {
  162    fn from_lsp(value: lsp::NumberOrString) -> Self {
  163        match value {
  164            lsp::NumberOrString::Number(number) => Self::Number(number),
  165            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  166        }
  167    }
  168
  169    fn to_lsp(&self) -> lsp::NumberOrString {
  170        match self {
  171            Self::Number(number) => lsp::NumberOrString::Number(*number),
  172            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  173        }
  174    }
  175
  176    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  177        Some(match value.value? {
  178            proto::progress_token::Value::Number(number) => Self::Number(number),
  179            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  180        })
  181    }
  182
  183    fn to_proto(&self) -> proto::ProgressToken {
  184        proto::ProgressToken {
  185            value: Some(match self {
  186                Self::Number(number) => proto::progress_token::Value::Number(*number),
  187                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  188            }),
  189        }
  190    }
  191}
  192
  193#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  194pub enum FormatTrigger {
  195    Save,
  196    Manual,
  197}
  198
  199pub enum LspFormatTarget {
  200    Buffers,
  201    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  202}
  203
  204#[derive(Clone, PartialEq, Eq, Hash)]
  205pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  206
  207struct OpenLspBuffer(Entity<Buffer>);
  208
  209impl FormatTrigger {
  210    fn from_proto(value: i32) -> FormatTrigger {
  211        match value {
  212            0 => FormatTrigger::Save,
  213            1 => FormatTrigger::Manual,
  214            _ => FormatTrigger::Save,
  215        }
  216    }
  217}
  218
  219#[derive(Clone)]
  220struct UnifiedLanguageServer {
  221    id: LanguageServerId,
  222    project_roots: HashSet<Arc<RelPath>>,
  223}
  224
  225#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  226struct LanguageServerSeed {
  227    worktree_id: WorktreeId,
  228    name: LanguageServerName,
  229    toolchain: Option<Toolchain>,
  230    settings: Arc<LspSettings>,
  231}
  232
  233#[derive(Debug)]
  234pub struct DocumentDiagnosticsUpdate<'a, D> {
  235    pub diagnostics: D,
  236    pub result_id: Option<SharedString>,
  237    pub registration_id: Option<SharedString>,
  238    pub server_id: LanguageServerId,
  239    pub disk_based_sources: Cow<'a, [String]>,
  240}
  241
  242pub struct DocumentDiagnostics {
  243    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  244    document_abs_path: PathBuf,
  245    version: Option<i32>,
  246}
  247
  248#[derive(Default, Debug)]
  249struct DynamicRegistrations {
  250    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  251    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  252}
  253
  254pub struct LocalLspStore {
  255    weak: WeakEntity<LspStore>,
  256    worktree_store: Entity<WorktreeStore>,
  257    toolchain_store: Entity<LocalToolchainStore>,
  258    http_client: Arc<dyn HttpClient>,
  259    environment: Entity<ProjectEnvironment>,
  260    fs: Arc<dyn Fs>,
  261    languages: Arc<LanguageRegistry>,
  262    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  263    yarn: Entity<YarnPathStore>,
  264    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  265    buffers_being_formatted: HashSet<BufferId>,
  266    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  267    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  268    watched_manifest_filenames: HashSet<ManifestName>,
  269    language_server_paths_watched_for_rename:
  270        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  271    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  272    supplementary_language_servers:
  273        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  274    prettier_store: Entity<PrettierStore>,
  275    next_diagnostic_group_id: usize,
  276    diagnostics: HashMap<
  277        WorktreeId,
  278        HashMap<
  279            Arc<RelPath>,
  280            Vec<(
  281                LanguageServerId,
  282                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  283            )>,
  284        >,
  285    >,
  286    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  287    _subscription: gpui::Subscription,
  288    lsp_tree: LanguageServerTree,
  289    registered_buffers: HashMap<BufferId, usize>,
  290    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  291    buffer_pull_diagnostics_result_ids: HashMap<
  292        LanguageServerId,
  293        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  294    >,
  295    workspace_pull_diagnostics_result_ids: HashMap<
  296        LanguageServerId,
  297        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  298    >,
  299}
  300
  301impl LocalLspStore {
  302    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  303    pub fn running_language_server_for_id(
  304        &self,
  305        id: LanguageServerId,
  306    ) -> Option<&Arc<LanguageServer>> {
  307        let language_server_state = self.language_servers.get(&id)?;
  308
  309        match language_server_state {
  310            LanguageServerState::Running { server, .. } => Some(server),
  311            LanguageServerState::Starting { .. } => None,
  312        }
  313    }
  314
  315    fn get_or_insert_language_server(
  316        &mut self,
  317        worktree_handle: &Entity<Worktree>,
  318        delegate: Arc<LocalLspAdapterDelegate>,
  319        disposition: &Arc<LaunchDisposition>,
  320        language_name: &LanguageName,
  321        cx: &mut App,
  322    ) -> LanguageServerId {
  323        let key = LanguageServerSeed {
  324            worktree_id: worktree_handle.read(cx).id(),
  325            name: disposition.server_name.clone(),
  326            settings: disposition.settings.clone(),
  327            toolchain: disposition.toolchain.clone(),
  328        };
  329        if let Some(state) = self.language_server_ids.get_mut(&key) {
  330            state.project_roots.insert(disposition.path.path.clone());
  331            state.id
  332        } else {
  333            let adapter = self
  334                .languages
  335                .lsp_adapters(language_name)
  336                .into_iter()
  337                .find(|adapter| adapter.name() == disposition.server_name)
  338                .expect("To find LSP adapter");
  339            let new_language_server_id = self.start_language_server(
  340                worktree_handle,
  341                delegate,
  342                adapter,
  343                disposition.settings.clone(),
  344                key.clone(),
  345                cx,
  346            );
  347            if let Some(state) = self.language_server_ids.get_mut(&key) {
  348                state.project_roots.insert(disposition.path.path.clone());
  349            } else {
  350                debug_assert!(
  351                    false,
  352                    "Expected `start_language_server` to ensure that `key` exists in a map"
  353                );
  354            }
  355            new_language_server_id
  356        }
  357    }
  358
  359    fn start_language_server(
  360        &mut self,
  361        worktree_handle: &Entity<Worktree>,
  362        delegate: Arc<LocalLspAdapterDelegate>,
  363        adapter: Arc<CachedLspAdapter>,
  364        settings: Arc<LspSettings>,
  365        key: LanguageServerSeed,
  366        cx: &mut App,
  367    ) -> LanguageServerId {
  368        let worktree = worktree_handle.read(cx);
  369
  370        let root_path = worktree.abs_path();
  371        let toolchain = key.toolchain.clone();
  372        let override_options = settings.initialization_options.clone();
  373
  374        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  375
  376        let server_id = self.languages.next_language_server_id();
  377        log::trace!(
  378            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  379            adapter.name.0
  380        );
  381
  382        let binary = self.get_language_server_binary(
  383            adapter.clone(),
  384            settings,
  385            toolchain.clone(),
  386            delegate.clone(),
  387            true,
  388            cx,
  389        );
  390        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  391
  392        let pending_server = cx.spawn({
  393            let adapter = adapter.clone();
  394            let server_name = adapter.name.clone();
  395            let stderr_capture = stderr_capture.clone();
  396            #[cfg(any(test, feature = "test-support"))]
  397            let lsp_store = self.weak.clone();
  398            let pending_workspace_folders = pending_workspace_folders.clone();
  399            async move |cx| {
  400                let binary = binary.await?;
  401                #[cfg(any(test, feature = "test-support"))]
  402                if let Some(server) = lsp_store
  403                    .update(&mut cx.clone(), |this, cx| {
  404                        this.languages.create_fake_language_server(
  405                            server_id,
  406                            &server_name,
  407                            binary.clone(),
  408                            &mut cx.to_async(),
  409                        )
  410                    })
  411                    .ok()
  412                    .flatten()
  413                {
  414                    return Ok(server);
  415                }
  416
  417                let code_action_kinds = adapter.code_action_kinds();
  418                lsp::LanguageServer::new(
  419                    stderr_capture,
  420                    server_id,
  421                    server_name,
  422                    binary,
  423                    &root_path,
  424                    code_action_kinds,
  425                    Some(pending_workspace_folders),
  426                    cx,
  427                )
  428            }
  429        });
  430
  431        let startup = {
  432            let server_name = adapter.name.0.clone();
  433            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  434            let key = key.clone();
  435            let adapter = adapter.clone();
  436            let lsp_store = self.weak.clone();
  437            let pending_workspace_folders = pending_workspace_folders.clone();
  438
  439            let pull_diagnostics = ProjectSettings::get_global(cx)
  440                .diagnostics
  441                .lsp_pull_diagnostics
  442                .enabled;
  443            cx.spawn(async move |cx| {
  444                let result = async {
  445                    let language_server = pending_server.await?;
  446
  447                    let workspace_config = Self::workspace_configuration_for_adapter(
  448                        adapter.adapter.clone(),
  449                        &delegate,
  450                        toolchain,
  451                        None,
  452                        cx,
  453                    )
  454                    .await?;
  455
  456                    let mut initialization_options = Self::initialization_options_for_adapter(
  457                        adapter.adapter.clone(),
  458                        &delegate,
  459                    )
  460                    .await?;
  461
  462                    match (&mut initialization_options, override_options) {
  463                        (Some(initialization_options), Some(override_options)) => {
  464                            merge_json_value_into(override_options, initialization_options);
  465                        }
  466                        (None, override_options) => initialization_options = override_options,
  467                        _ => {}
  468                    }
  469
  470                    let initialization_params = cx.update(|cx| {
  471                        let mut params =
  472                            language_server.default_initialize_params(pull_diagnostics, cx);
  473                        params.initialization_options = initialization_options;
  474                        adapter.adapter.prepare_initialize_params(params, cx)
  475                    })??;
  476
  477                    Self::setup_lsp_messages(
  478                        lsp_store.clone(),
  479                        &language_server,
  480                        delegate.clone(),
  481                        adapter.clone(),
  482                    );
  483
  484                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  485                        settings: workspace_config,
  486                    };
  487                    let language_server = cx
  488                        .update(|cx| {
  489                            language_server.initialize(
  490                                initialization_params,
  491                                Arc::new(did_change_configuration_params.clone()),
  492                                cx,
  493                            )
  494                        })?
  495                        .await
  496                        .inspect_err(|_| {
  497                            if let Some(lsp_store) = lsp_store.upgrade() {
  498                                lsp_store
  499                                    .update(cx, |lsp_store, cx| {
  500                                        lsp_store.cleanup_lsp_data(server_id);
  501                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  502                                    })
  503                                    .ok();
  504                            }
  505                        })?;
  506
  507                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  508                        did_change_configuration_params,
  509                    )?;
  510
  511                    anyhow::Ok(language_server)
  512                }
  513                .await;
  514
  515                match result {
  516                    Ok(server) => {
  517                        lsp_store
  518                            .update(cx, |lsp_store, cx| {
  519                                lsp_store.insert_newly_running_language_server(
  520                                    adapter,
  521                                    server.clone(),
  522                                    server_id,
  523                                    key,
  524                                    pending_workspace_folders,
  525                                    cx,
  526                                );
  527                            })
  528                            .ok();
  529                        stderr_capture.lock().take();
  530                        Some(server)
  531                    }
  532
  533                    Err(err) => {
  534                        let log = stderr_capture.lock().take().unwrap_or_default();
  535                        delegate.update_status(
  536                            adapter.name(),
  537                            BinaryStatus::Failed {
  538                                error: if log.is_empty() {
  539                                    format!("{err:#}")
  540                                } else {
  541                                    format!("{err:#}\n-- stderr --\n{log}")
  542                                },
  543                            },
  544                        );
  545                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  546                        if !log.is_empty() {
  547                            log::error!("server stderr: {log}");
  548                        }
  549                        None
  550                    }
  551                }
  552            })
  553        };
  554        let state = LanguageServerState::Starting {
  555            startup,
  556            pending_workspace_folders,
  557        };
  558
  559        self.languages
  560            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  561
  562        self.language_servers.insert(server_id, state);
  563        self.language_server_ids
  564            .entry(key)
  565            .or_insert(UnifiedLanguageServer {
  566                id: server_id,
  567                project_roots: Default::default(),
  568            });
  569        server_id
  570    }
  571
  572    fn get_language_server_binary(
  573        &self,
  574        adapter: Arc<CachedLspAdapter>,
  575        settings: Arc<LspSettings>,
  576        toolchain: Option<Toolchain>,
  577        delegate: Arc<dyn LspAdapterDelegate>,
  578        allow_binary_download: bool,
  579        cx: &mut App,
  580    ) -> Task<Result<LanguageServerBinary>> {
  581        if let Some(settings) = &settings.binary
  582            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  583        {
  584            let settings = settings.clone();
  585
  586            return cx.background_spawn(async move {
  587                let mut env = delegate.shell_env().await;
  588                env.extend(settings.env.unwrap_or_default());
  589
  590                Ok(LanguageServerBinary {
  591                    path: delegate.resolve_executable_path(path),
  592                    env: Some(env),
  593                    arguments: settings
  594                        .arguments
  595                        .unwrap_or_default()
  596                        .iter()
  597                        .map(Into::into)
  598                        .collect(),
  599                })
  600            });
  601        }
  602        let lsp_binary_options = LanguageServerBinaryOptions {
  603            allow_path_lookup: !settings
  604                .binary
  605                .as_ref()
  606                .and_then(|b| b.ignore_system_version)
  607                .unwrap_or_default(),
  608            allow_binary_download,
  609            pre_release: settings
  610                .fetch
  611                .as_ref()
  612                .and_then(|f| f.pre_release)
  613                .unwrap_or(false),
  614        };
  615
  616        cx.spawn(async move |cx| {
  617            let (existing_binary, maybe_download_binary) = adapter
  618                .clone()
  619                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  620                .await
  621                .await;
  622
  623            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  624
  625            let mut binary = match (existing_binary, maybe_download_binary) {
  626                (binary, None) => binary?,
  627                (Err(_), Some(downloader)) => downloader.await?,
  628                (Ok(existing_binary), Some(downloader)) => {
  629                    let mut download_timeout = cx
  630                        .background_executor()
  631                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  632                        .fuse();
  633                    let mut downloader = downloader.fuse();
  634                    futures::select! {
  635                        _ = download_timeout => {
  636                            // Return existing binary and kick the existing work to the background.
  637                            cx.spawn(async move |_| downloader.await).detach();
  638                            Ok(existing_binary)
  639                        },
  640                        downloaded_or_existing_binary = downloader => {
  641                            // If download fails, this results in the existing binary.
  642                            downloaded_or_existing_binary
  643                        }
  644                    }?
  645                }
  646            };
  647            let mut shell_env = delegate.shell_env().await;
  648
  649            shell_env.extend(binary.env.unwrap_or_default());
  650
  651            if let Some(settings) = settings.binary.as_ref() {
  652                if let Some(arguments) = &settings.arguments {
  653                    binary.arguments = arguments.iter().map(Into::into).collect();
  654                }
  655                if let Some(env) = &settings.env {
  656                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  657                }
  658            }
  659
  660            binary.env = Some(shell_env);
  661            Ok(binary)
  662        })
  663    }
  664
  665    fn setup_lsp_messages(
  666        lsp_store: WeakEntity<LspStore>,
  667        language_server: &LanguageServer,
  668        delegate: Arc<dyn LspAdapterDelegate>,
  669        adapter: Arc<CachedLspAdapter>,
  670    ) {
  671        let name = language_server.name();
  672        let server_id = language_server.server_id();
  673        language_server
  674            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  675                let adapter = adapter.clone();
  676                let this = lsp_store.clone();
  677                move |mut params, cx| {
  678                    let adapter = adapter.clone();
  679                    if let Some(this) = this.upgrade() {
  680                        this.update(cx, |this, cx| {
  681                            {
  682                                let buffer = params
  683                                    .uri
  684                                    .to_file_path()
  685                                    .map(|file_path| this.get_buffer(&file_path, cx))
  686                                    .ok()
  687                                    .flatten();
  688                                adapter.process_diagnostics(&mut params, server_id, buffer);
  689                            }
  690
  691                            this.merge_lsp_diagnostics(
  692                                DiagnosticSourceKind::Pushed,
  693                                vec![DocumentDiagnosticsUpdate {
  694                                    server_id,
  695                                    diagnostics: params,
  696                                    result_id: None,
  697                                    disk_based_sources: Cow::Borrowed(
  698                                        &adapter.disk_based_diagnostic_sources,
  699                                    ),
  700                                    registration_id: None,
  701                                }],
  702                                |_, diagnostic, cx| match diagnostic.source_kind {
  703                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  704                                        adapter.retain_old_diagnostic(diagnostic, cx)
  705                                    }
  706                                    DiagnosticSourceKind::Pulled => true,
  707                                },
  708                                cx,
  709                            )
  710                            .log_err();
  711                        })
  712                        .ok();
  713                    }
  714                }
  715            })
  716            .detach();
  717        language_server
  718            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  719                let adapter = adapter.adapter.clone();
  720                let delegate = delegate.clone();
  721                let this = lsp_store.clone();
  722                move |params, cx| {
  723                    let adapter = adapter.clone();
  724                    let delegate = delegate.clone();
  725                    let this = this.clone();
  726                    let mut cx = cx.clone();
  727                    async move {
  728                        let toolchain_for_id = this
  729                            .update(&mut cx, |this, _| {
  730                                this.as_local()?.language_server_ids.iter().find_map(
  731                                    |(seed, value)| {
  732                                        (value.id == server_id).then(|| seed.toolchain.clone())
  733                                    },
  734                                )
  735                            })?
  736                            .context("Expected the LSP store to be in a local mode")?;
  737
  738                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  739                        for item in &params.items {
  740                            let scope_uri = item.scope_uri.clone();
  741                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  742                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  743                            else {
  744                                // We've already queried workspace configuration of this URI.
  745                                continue;
  746                            };
  747                            let workspace_config = Self::workspace_configuration_for_adapter(
  748                                adapter.clone(),
  749                                &delegate,
  750                                toolchain_for_id.clone(),
  751                                scope_uri,
  752                                &mut cx,
  753                            )
  754                            .await?;
  755                            new_scope_uri.insert(workspace_config);
  756                        }
  757
  758                        Ok(params
  759                            .items
  760                            .into_iter()
  761                            .filter_map(|item| {
  762                                let workspace_config =
  763                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  764                                if let Some(section) = &item.section {
  765                                    Some(
  766                                        workspace_config
  767                                            .get(section)
  768                                            .cloned()
  769                                            .unwrap_or(serde_json::Value::Null),
  770                                    )
  771                                } else {
  772                                    Some(workspace_config.clone())
  773                                }
  774                            })
  775                            .collect())
  776                    }
  777                }
  778            })
  779            .detach();
  780
  781        language_server
  782            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  783                let this = lsp_store.clone();
  784                move |_, cx| {
  785                    let this = this.clone();
  786                    let cx = cx.clone();
  787                    async move {
  788                        let Some(server) =
  789                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  790                        else {
  791                            return Ok(None);
  792                        };
  793                        let root = server.workspace_folders();
  794                        Ok(Some(
  795                            root.into_iter()
  796                                .map(|uri| WorkspaceFolder {
  797                                    uri,
  798                                    name: Default::default(),
  799                                })
  800                                .collect(),
  801                        ))
  802                    }
  803                }
  804            })
  805            .detach();
  806        // Even though we don't have handling for these requests, respond to them to
  807        // avoid stalling any language server like `gopls` which waits for a response
  808        // to these requests when initializing.
  809        language_server
  810            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  811                let this = lsp_store.clone();
  812                move |params, cx| {
  813                    let this = this.clone();
  814                    let mut cx = cx.clone();
  815                    async move {
  816                        this.update(&mut cx, |this, _| {
  817                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  818                            {
  819                                status
  820                                    .progress_tokens
  821                                    .insert(ProgressToken::from_lsp(params.token));
  822                            }
  823                        })?;
  824
  825                        Ok(())
  826                    }
  827                }
  828            })
  829            .detach();
  830
  831        language_server
  832            .on_request::<lsp::request::RegisterCapability, _, _>({
  833                let lsp_store = lsp_store.clone();
  834                move |params, cx| {
  835                    let lsp_store = lsp_store.clone();
  836                    let mut cx = cx.clone();
  837                    async move {
  838                        lsp_store
  839                            .update(&mut cx, |lsp_store, cx| {
  840                                if lsp_store.as_local().is_some() {
  841                                    match lsp_store
  842                                        .register_server_capabilities(server_id, params, cx)
  843                                    {
  844                                        Ok(()) => {}
  845                                        Err(e) => {
  846                                            log::error!(
  847                                                "Failed to register server capabilities: {e:#}"
  848                                            );
  849                                        }
  850                                    };
  851                                }
  852                            })
  853                            .ok();
  854                        Ok(())
  855                    }
  856                }
  857            })
  858            .detach();
  859
  860        language_server
  861            .on_request::<lsp::request::UnregisterCapability, _, _>({
  862                let lsp_store = lsp_store.clone();
  863                move |params, cx| {
  864                    let lsp_store = lsp_store.clone();
  865                    let mut cx = cx.clone();
  866                    async move {
  867                        lsp_store
  868                            .update(&mut cx, |lsp_store, cx| {
  869                                if lsp_store.as_local().is_some() {
  870                                    match lsp_store
  871                                        .unregister_server_capabilities(server_id, params, cx)
  872                                    {
  873                                        Ok(()) => {}
  874                                        Err(e) => {
  875                                            log::error!(
  876                                                "Failed to unregister server capabilities: {e:#}"
  877                                            );
  878                                        }
  879                                    }
  880                                }
  881                            })
  882                            .ok();
  883                        Ok(())
  884                    }
  885                }
  886            })
  887            .detach();
  888
  889        language_server
  890            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  891                let this = lsp_store.clone();
  892                move |params, cx| {
  893                    let mut cx = cx.clone();
  894                    let this = this.clone();
  895                    async move {
  896                        LocalLspStore::on_lsp_workspace_edit(
  897                            this.clone(),
  898                            params,
  899                            server_id,
  900                            &mut cx,
  901                        )
  902                        .await
  903                    }
  904                }
  905            })
  906            .detach();
  907
  908        language_server
  909            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  910                let lsp_store = lsp_store.clone();
  911                let request_id = Arc::new(AtomicUsize::new(0));
  912                move |(), cx| {
  913                    let lsp_store = lsp_store.clone();
  914                    let request_id = request_id.clone();
  915                    let mut cx = cx.clone();
  916                    async move {
  917                        lsp_store
  918                            .update(&mut cx, |lsp_store, cx| {
  919                                let request_id =
  920                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  921                                cx.emit(LspStoreEvent::RefreshInlayHints {
  922                                    server_id,
  923                                    request_id,
  924                                });
  925                                lsp_store
  926                                    .downstream_client
  927                                    .as_ref()
  928                                    .map(|(client, project_id)| {
  929                                        client.send(proto::RefreshInlayHints {
  930                                            project_id: *project_id,
  931                                            server_id: server_id.to_proto(),
  932                                            request_id: request_id.map(|id| id as u64),
  933                                        })
  934                                    })
  935                            })?
  936                            .transpose()?;
  937                        Ok(())
  938                    }
  939                }
  940            })
  941            .detach();
  942
  943        language_server
  944            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  945                let this = lsp_store.clone();
  946                move |(), cx| {
  947                    let this = this.clone();
  948                    let mut cx = cx.clone();
  949                    async move {
  950                        this.update(&mut cx, |this, cx| {
  951                            cx.emit(LspStoreEvent::RefreshCodeLens);
  952                            this.downstream_client.as_ref().map(|(client, project_id)| {
  953                                client.send(proto::RefreshCodeLens {
  954                                    project_id: *project_id,
  955                                })
  956                            })
  957                        })?
  958                        .transpose()?;
  959                        Ok(())
  960                    }
  961                }
  962            })
  963            .detach();
  964
  965        language_server
  966            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  967                let this = lsp_store.clone();
  968                move |(), cx| {
  969                    let this = this.clone();
  970                    let mut cx = cx.clone();
  971                    async move {
  972                        this.update(&mut cx, |lsp_store, _| {
  973                            lsp_store.pull_workspace_diagnostics(server_id);
  974                            lsp_store
  975                                .downstream_client
  976                                .as_ref()
  977                                .map(|(client, project_id)| {
  978                                    client.send(proto::PullWorkspaceDiagnostics {
  979                                        project_id: *project_id,
  980                                        server_id: server_id.to_proto(),
  981                                    })
  982                                })
  983                        })?
  984                        .transpose()?;
  985                        Ok(())
  986                    }
  987                }
  988            })
  989            .detach();
  990
  991        language_server
  992            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  993                let this = lsp_store.clone();
  994                let name = name.to_string();
  995                move |params, cx| {
  996                    let this = this.clone();
  997                    let name = name.to_string();
  998                    let mut cx = cx.clone();
  999                    async move {
 1000                        let actions = params.actions.unwrap_or_default();
 1001                        let (tx, rx) = smol::channel::bounded(1);
 1002                        let request = LanguageServerPromptRequest {
 1003                            level: match params.typ {
 1004                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1005                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1006                                _ => PromptLevel::Info,
 1007                            },
 1008                            message: params.message,
 1009                            actions,
 1010                            response_channel: tx,
 1011                            lsp_name: name.clone(),
 1012                        };
 1013
 1014                        let did_update = this
 1015                            .update(&mut cx, |_, cx| {
 1016                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1017                            })
 1018                            .is_ok();
 1019                        if did_update {
 1020                            let response = rx.recv().await.ok();
 1021                            Ok(response)
 1022                        } else {
 1023                            Ok(None)
 1024                        }
 1025                    }
 1026                }
 1027            })
 1028            .detach();
 1029        language_server
 1030            .on_notification::<lsp::notification::ShowMessage, _>({
 1031                let this = lsp_store.clone();
 1032                let name = name.to_string();
 1033                move |params, cx| {
 1034                    let this = this.clone();
 1035                    let name = name.to_string();
 1036                    let mut cx = cx.clone();
 1037
 1038                    let (tx, _) = smol::channel::bounded(1);
 1039                    let request = LanguageServerPromptRequest {
 1040                        level: match params.typ {
 1041                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1042                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1043                            _ => PromptLevel::Info,
 1044                        },
 1045                        message: params.message,
 1046                        actions: vec![],
 1047                        response_channel: tx,
 1048                        lsp_name: name,
 1049                    };
 1050
 1051                    let _ = this.update(&mut cx, |_, cx| {
 1052                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1053                    });
 1054                }
 1055            })
 1056            .detach();
 1057
 1058        let disk_based_diagnostics_progress_token =
 1059            adapter.disk_based_diagnostics_progress_token.clone();
 1060
 1061        language_server
 1062            .on_notification::<lsp::notification::Progress, _>({
 1063                let this = lsp_store.clone();
 1064                move |params, cx| {
 1065                    if let Some(this) = this.upgrade() {
 1066                        this.update(cx, |this, cx| {
 1067                            this.on_lsp_progress(
 1068                                params,
 1069                                server_id,
 1070                                disk_based_diagnostics_progress_token.clone(),
 1071                                cx,
 1072                            );
 1073                        })
 1074                        .ok();
 1075                    }
 1076                }
 1077            })
 1078            .detach();
 1079
 1080        language_server
 1081            .on_notification::<lsp::notification::LogMessage, _>({
 1082                let this = lsp_store.clone();
 1083                move |params, cx| {
 1084                    if let Some(this) = this.upgrade() {
 1085                        this.update(cx, |_, cx| {
 1086                            cx.emit(LspStoreEvent::LanguageServerLog(
 1087                                server_id,
 1088                                LanguageServerLogType::Log(params.typ),
 1089                                params.message,
 1090                            ));
 1091                        })
 1092                        .ok();
 1093                    }
 1094                }
 1095            })
 1096            .detach();
 1097
 1098        language_server
 1099            .on_notification::<lsp::notification::LogTrace, _>({
 1100                let this = lsp_store.clone();
 1101                move |params, cx| {
 1102                    let mut cx = cx.clone();
 1103                    if let Some(this) = this.upgrade() {
 1104                        this.update(&mut cx, |_, cx| {
 1105                            cx.emit(LspStoreEvent::LanguageServerLog(
 1106                                server_id,
 1107                                LanguageServerLogType::Trace {
 1108                                    verbose_info: params.verbose,
 1109                                },
 1110                                params.message,
 1111                            ));
 1112                        })
 1113                        .ok();
 1114                    }
 1115                }
 1116            })
 1117            .detach();
 1118
 1119        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1120        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1121        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1122        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1123    }
 1124
 1125    fn shutdown_language_servers_on_quit(
 1126        &mut self,
 1127        _: &mut Context<LspStore>,
 1128    ) -> impl Future<Output = ()> + use<> {
 1129        let shutdown_futures = self
 1130            .language_servers
 1131            .drain()
 1132            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1133            .collect::<Vec<_>>();
 1134
 1135        async move {
 1136            join_all(shutdown_futures).await;
 1137        }
 1138    }
 1139
 1140    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1141        match server_state {
 1142            LanguageServerState::Running { server, .. } => {
 1143                if let Some(shutdown) = server.shutdown() {
 1144                    shutdown.await;
 1145                }
 1146            }
 1147            LanguageServerState::Starting { startup, .. } => {
 1148                if let Some(server) = startup.await
 1149                    && let Some(shutdown) = server.shutdown()
 1150                {
 1151                    shutdown.await;
 1152                }
 1153            }
 1154        }
 1155        Ok(())
 1156    }
 1157
 1158    fn language_servers_for_worktree(
 1159        &self,
 1160        worktree_id: WorktreeId,
 1161    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1162        self.language_server_ids
 1163            .iter()
 1164            .filter_map(move |(seed, state)| {
 1165                if seed.worktree_id != worktree_id {
 1166                    return None;
 1167                }
 1168
 1169                if let Some(LanguageServerState::Running { server, .. }) =
 1170                    self.language_servers.get(&state.id)
 1171                {
 1172                    Some(server)
 1173                } else {
 1174                    None
 1175                }
 1176            })
 1177    }
 1178
 1179    fn language_server_ids_for_project_path(
 1180        &self,
 1181        project_path: ProjectPath,
 1182        language: &Language,
 1183        cx: &mut App,
 1184    ) -> Vec<LanguageServerId> {
 1185        let Some(worktree) = self
 1186            .worktree_store
 1187            .read(cx)
 1188            .worktree_for_id(project_path.worktree_id, cx)
 1189        else {
 1190            return Vec::new();
 1191        };
 1192        let delegate: Arc<dyn ManifestDelegate> =
 1193            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1194
 1195        self.lsp_tree
 1196            .get(
 1197                project_path,
 1198                language.name(),
 1199                language.manifest(),
 1200                &delegate,
 1201                cx,
 1202            )
 1203            .collect::<Vec<_>>()
 1204    }
 1205
 1206    fn language_server_ids_for_buffer(
 1207        &self,
 1208        buffer: &Buffer,
 1209        cx: &mut App,
 1210    ) -> Vec<LanguageServerId> {
 1211        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1212            let worktree_id = file.worktree_id(cx);
 1213
 1214            let path: Arc<RelPath> = file
 1215                .path()
 1216                .parent()
 1217                .map(Arc::from)
 1218                .unwrap_or_else(|| file.path().clone());
 1219            let worktree_path = ProjectPath { worktree_id, path };
 1220            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1221        } else {
 1222            Vec::new()
 1223        }
 1224    }
 1225
 1226    fn language_servers_for_buffer<'a>(
 1227        &'a self,
 1228        buffer: &'a Buffer,
 1229        cx: &'a mut App,
 1230    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1231        self.language_server_ids_for_buffer(buffer, cx)
 1232            .into_iter()
 1233            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1234                LanguageServerState::Running {
 1235                    adapter, server, ..
 1236                } => Some((adapter, server)),
 1237                _ => None,
 1238            })
 1239    }
 1240
 1241    async fn execute_code_action_kind_locally(
 1242        lsp_store: WeakEntity<LspStore>,
 1243        mut buffers: Vec<Entity<Buffer>>,
 1244        kind: CodeActionKind,
 1245        push_to_history: bool,
 1246        cx: &mut AsyncApp,
 1247    ) -> anyhow::Result<ProjectTransaction> {
 1248        // Do not allow multiple concurrent code actions requests for the
 1249        // same buffer.
 1250        lsp_store.update(cx, |this, cx| {
 1251            let this = this.as_local_mut().unwrap();
 1252            buffers.retain(|buffer| {
 1253                this.buffers_being_formatted
 1254                    .insert(buffer.read(cx).remote_id())
 1255            });
 1256        })?;
 1257        let _cleanup = defer({
 1258            let this = lsp_store.clone();
 1259            let mut cx = cx.clone();
 1260            let buffers = &buffers;
 1261            move || {
 1262                this.update(&mut cx, |this, cx| {
 1263                    let this = this.as_local_mut().unwrap();
 1264                    for buffer in buffers {
 1265                        this.buffers_being_formatted
 1266                            .remove(&buffer.read(cx).remote_id());
 1267                    }
 1268                })
 1269                .ok();
 1270            }
 1271        });
 1272        let mut project_transaction = ProjectTransaction::default();
 1273
 1274        for buffer in &buffers {
 1275            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1276                buffer.update(cx, |buffer, cx| {
 1277                    lsp_store
 1278                        .as_local()
 1279                        .unwrap()
 1280                        .language_servers_for_buffer(buffer, cx)
 1281                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1282                        .collect::<Vec<_>>()
 1283                })
 1284            })?;
 1285            for (_, language_server) in adapters_and_servers.iter() {
 1286                let actions = Self::get_server_code_actions_from_action_kinds(
 1287                    &lsp_store,
 1288                    language_server.server_id(),
 1289                    vec![kind.clone()],
 1290                    buffer,
 1291                    cx,
 1292                )
 1293                .await?;
 1294                Self::execute_code_actions_on_server(
 1295                    &lsp_store,
 1296                    language_server,
 1297                    actions,
 1298                    push_to_history,
 1299                    &mut project_transaction,
 1300                    cx,
 1301                )
 1302                .await?;
 1303            }
 1304        }
 1305        Ok(project_transaction)
 1306    }
 1307
 1308    async fn format_locally(
 1309        lsp_store: WeakEntity<LspStore>,
 1310        mut buffers: Vec<FormattableBuffer>,
 1311        push_to_history: bool,
 1312        trigger: FormatTrigger,
 1313        logger: zlog::Logger,
 1314        cx: &mut AsyncApp,
 1315    ) -> anyhow::Result<ProjectTransaction> {
 1316        // Do not allow multiple concurrent formatting requests for the
 1317        // same buffer.
 1318        lsp_store.update(cx, |this, cx| {
 1319            let this = this.as_local_mut().unwrap();
 1320            buffers.retain(|buffer| {
 1321                this.buffers_being_formatted
 1322                    .insert(buffer.handle.read(cx).remote_id())
 1323            });
 1324        })?;
 1325
 1326        let _cleanup = defer({
 1327            let this = lsp_store.clone();
 1328            let mut cx = cx.clone();
 1329            let buffers = &buffers;
 1330            move || {
 1331                this.update(&mut cx, |this, cx| {
 1332                    let this = this.as_local_mut().unwrap();
 1333                    for buffer in buffers {
 1334                        this.buffers_being_formatted
 1335                            .remove(&buffer.handle.read(cx).remote_id());
 1336                    }
 1337                })
 1338                .ok();
 1339            }
 1340        });
 1341
 1342        let mut project_transaction = ProjectTransaction::default();
 1343
 1344        for buffer in &buffers {
 1345            zlog::debug!(
 1346                logger =>
 1347                "formatting buffer '{:?}'",
 1348                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1349            );
 1350            // Create an empty transaction to hold all of the formatting edits.
 1351            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1352                // ensure no transactions created while formatting are
 1353                // grouped with the previous transaction in the history
 1354                // based on the transaction group interval
 1355                buffer.finalize_last_transaction();
 1356                buffer
 1357                    .start_transaction()
 1358                    .context("transaction already open")?;
 1359                buffer.end_transaction(cx);
 1360                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1361                buffer.finalize_last_transaction();
 1362                anyhow::Ok(transaction_id)
 1363            })??;
 1364
 1365            let result = Self::format_buffer_locally(
 1366                lsp_store.clone(),
 1367                buffer,
 1368                formatting_transaction_id,
 1369                trigger,
 1370                logger,
 1371                cx,
 1372            )
 1373            .await;
 1374
 1375            buffer.handle.update(cx, |buffer, cx| {
 1376                let Some(formatting_transaction) =
 1377                    buffer.get_transaction(formatting_transaction_id).cloned()
 1378                else {
 1379                    zlog::warn!(logger => "no formatting transaction");
 1380                    return;
 1381                };
 1382                if formatting_transaction.edit_ids.is_empty() {
 1383                    zlog::debug!(logger => "no changes made while formatting");
 1384                    buffer.forget_transaction(formatting_transaction_id);
 1385                    return;
 1386                }
 1387                if !push_to_history {
 1388                    zlog::trace!(logger => "forgetting format transaction");
 1389                    buffer.forget_transaction(formatting_transaction.id);
 1390                }
 1391                project_transaction
 1392                    .0
 1393                    .insert(cx.entity(), formatting_transaction);
 1394            })?;
 1395
 1396            result?;
 1397        }
 1398
 1399        Ok(project_transaction)
 1400    }
 1401
 1402    async fn format_buffer_locally(
 1403        lsp_store: WeakEntity<LspStore>,
 1404        buffer: &FormattableBuffer,
 1405        formatting_transaction_id: clock::Lamport,
 1406        trigger: FormatTrigger,
 1407        logger: zlog::Logger,
 1408        cx: &mut AsyncApp,
 1409    ) -> Result<()> {
 1410        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1411            buffer.handle.update(cx, |buffer, cx| {
 1412                let adapters_and_servers = lsp_store
 1413                    .as_local()
 1414                    .unwrap()
 1415                    .language_servers_for_buffer(buffer, cx)
 1416                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1417                    .collect::<Vec<_>>();
 1418                let settings =
 1419                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1420                        .into_owned();
 1421                (adapters_and_servers, settings)
 1422            })
 1423        })?;
 1424
 1425        /// Apply edits to the buffer that will become part of the formatting transaction.
 1426        /// Fails if the buffer has been edited since the start of that transaction.
 1427        fn extend_formatting_transaction(
 1428            buffer: &FormattableBuffer,
 1429            formatting_transaction_id: text::TransactionId,
 1430            cx: &mut AsyncApp,
 1431            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1432        ) -> anyhow::Result<()> {
 1433            buffer.handle.update(cx, |buffer, cx| {
 1434                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1435                if last_transaction_id != Some(formatting_transaction_id) {
 1436                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1437                }
 1438                buffer.start_transaction();
 1439                operation(buffer, cx);
 1440                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1441                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1442                }
 1443                Ok(())
 1444            })?
 1445        }
 1446
 1447        // handle whitespace formatting
 1448        if settings.remove_trailing_whitespace_on_save {
 1449            zlog::trace!(logger => "removing trailing whitespace");
 1450            let diff = buffer
 1451                .handle
 1452                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1453                .await;
 1454            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1455                buffer.apply_diff(diff, cx);
 1456            })?;
 1457        }
 1458
 1459        if settings.ensure_final_newline_on_save {
 1460            zlog::trace!(logger => "ensuring final newline");
 1461            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1462                buffer.ensure_final_newline(cx);
 1463            })?;
 1464        }
 1465
 1466        // Formatter for `code_actions_on_format` that runs before
 1467        // the rest of the formatters
 1468        let mut code_actions_on_format_formatters = None;
 1469        let should_run_code_actions_on_format = !matches!(
 1470            (trigger, &settings.format_on_save),
 1471            (FormatTrigger::Save, &FormatOnSave::Off)
 1472        );
 1473        if should_run_code_actions_on_format {
 1474            let have_code_actions_to_run_on_format = settings
 1475                .code_actions_on_format
 1476                .values()
 1477                .any(|enabled| *enabled);
 1478            if have_code_actions_to_run_on_format {
 1479                zlog::trace!(logger => "going to run code actions on format");
 1480                code_actions_on_format_formatters = Some(
 1481                    settings
 1482                        .code_actions_on_format
 1483                        .iter()
 1484                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1485                        .cloned()
 1486                        .map(Formatter::CodeAction)
 1487                        .collect::<Vec<_>>(),
 1488                );
 1489            }
 1490        }
 1491
 1492        let formatters = match (trigger, &settings.format_on_save) {
 1493            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1494            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1495                settings.formatter.as_ref()
 1496            }
 1497        };
 1498
 1499        let formatters = code_actions_on_format_formatters
 1500            .iter()
 1501            .flatten()
 1502            .chain(formatters);
 1503
 1504        for formatter in formatters {
 1505            let formatter = if formatter == &Formatter::Auto {
 1506                if settings.prettier.allowed {
 1507                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1508                    &Formatter::Prettier
 1509                } else {
 1510                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1511                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1512                }
 1513            } else {
 1514                formatter
 1515            };
 1516            match formatter {
 1517                Formatter::Auto => unreachable!("Auto resolved above"),
 1518                Formatter::Prettier => {
 1519                    let logger = zlog::scoped!(logger => "prettier");
 1520                    zlog::trace!(logger => "formatting");
 1521                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1522
 1523                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1524                        lsp_store.prettier_store().unwrap().downgrade()
 1525                    })?;
 1526                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1527                        .await
 1528                        .transpose()?;
 1529                    let Some(diff) = diff else {
 1530                        zlog::trace!(logger => "No changes");
 1531                        continue;
 1532                    };
 1533
 1534                    extend_formatting_transaction(
 1535                        buffer,
 1536                        formatting_transaction_id,
 1537                        cx,
 1538                        |buffer, cx| {
 1539                            buffer.apply_diff(diff, cx);
 1540                        },
 1541                    )?;
 1542                }
 1543                Formatter::External { command, arguments } => {
 1544                    let logger = zlog::scoped!(logger => "command");
 1545                    zlog::trace!(logger => "formatting");
 1546                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1547
 1548                    let diff = Self::format_via_external_command(
 1549                        buffer,
 1550                        command.as_ref(),
 1551                        arguments.as_deref(),
 1552                        cx,
 1553                    )
 1554                    .await
 1555                    .with_context(|| {
 1556                        format!("Failed to format buffer via external command: {}", command)
 1557                    })?;
 1558                    let Some(diff) = diff else {
 1559                        zlog::trace!(logger => "No changes");
 1560                        continue;
 1561                    };
 1562
 1563                    extend_formatting_transaction(
 1564                        buffer,
 1565                        formatting_transaction_id,
 1566                        cx,
 1567                        |buffer, cx| {
 1568                            buffer.apply_diff(diff, cx);
 1569                        },
 1570                    )?;
 1571                }
 1572                Formatter::LanguageServer(specifier) => {
 1573                    let logger = zlog::scoped!(logger => "language-server");
 1574                    zlog::trace!(logger => "formatting");
 1575                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1576
 1577                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1578                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1579                        continue;
 1580                    };
 1581
 1582                    let language_server = match specifier {
 1583                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1584                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1585                                if adapter.name.0.as_ref() == name {
 1586                                    Some(server.clone())
 1587                                } else {
 1588                                    None
 1589                                }
 1590                            })
 1591                        }
 1592                        settings::LanguageServerFormatterSpecifier::Current => {
 1593                            adapters_and_servers.first().map(|e| e.1.clone())
 1594                        }
 1595                    };
 1596
 1597                    let Some(language_server) = language_server else {
 1598                        log::debug!(
 1599                            "No language server found to format buffer '{:?}'. Skipping",
 1600                            buffer_path_abs.as_path().to_string_lossy()
 1601                        );
 1602                        continue;
 1603                    };
 1604
 1605                    zlog::trace!(
 1606                        logger =>
 1607                        "Formatting buffer '{:?}' using language server '{:?}'",
 1608                        buffer_path_abs.as_path().to_string_lossy(),
 1609                        language_server.name()
 1610                    );
 1611
 1612                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1613                        zlog::trace!(logger => "formatting ranges");
 1614                        Self::format_ranges_via_lsp(
 1615                            &lsp_store,
 1616                            &buffer.handle,
 1617                            ranges,
 1618                            buffer_path_abs,
 1619                            &language_server,
 1620                            &settings,
 1621                            cx,
 1622                        )
 1623                        .await
 1624                        .context("Failed to format ranges via language server")?
 1625                    } else {
 1626                        zlog::trace!(logger => "formatting full");
 1627                        Self::format_via_lsp(
 1628                            &lsp_store,
 1629                            &buffer.handle,
 1630                            buffer_path_abs,
 1631                            &language_server,
 1632                            &settings,
 1633                            cx,
 1634                        )
 1635                        .await
 1636                        .context("failed to format via language server")?
 1637                    };
 1638
 1639                    if edits.is_empty() {
 1640                        zlog::trace!(logger => "No changes");
 1641                        continue;
 1642                    }
 1643                    extend_formatting_transaction(
 1644                        buffer,
 1645                        formatting_transaction_id,
 1646                        cx,
 1647                        |buffer, cx| {
 1648                            buffer.edit(edits, None, cx);
 1649                        },
 1650                    )?;
 1651                }
 1652                Formatter::CodeAction(code_action_name) => {
 1653                    let logger = zlog::scoped!(logger => "code-actions");
 1654                    zlog::trace!(logger => "formatting");
 1655                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1656
 1657                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1658                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1659                        continue;
 1660                    };
 1661
 1662                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1663                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1664
 1665                    let mut actions_and_servers = Vec::new();
 1666
 1667                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1668                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1669                            &lsp_store,
 1670                            language_server.server_id(),
 1671                            vec![code_action_kind.clone()],
 1672                            &buffer.handle,
 1673                            cx,
 1674                        )
 1675                        .await
 1676                        .with_context(|| {
 1677                            format!(
 1678                                "Failed to resolve code action {:?} with language server {}",
 1679                                code_action_kind,
 1680                                language_server.name()
 1681                            )
 1682                        });
 1683                        let Ok(actions) = actions_result else {
 1684                            // note: it may be better to set result to the error and break formatters here
 1685                            // but for now we try to execute the actions that we can resolve and skip the rest
 1686                            zlog::error!(
 1687                                logger =>
 1688                                "Failed to resolve code action {:?} with language server {}",
 1689                                code_action_kind,
 1690                                language_server.name()
 1691                            );
 1692                            continue;
 1693                        };
 1694                        for action in actions {
 1695                            actions_and_servers.push((action, index));
 1696                        }
 1697                    }
 1698
 1699                    if actions_and_servers.is_empty() {
 1700                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1701                        continue;
 1702                    }
 1703
 1704                    'actions: for (mut action, server_index) in actions_and_servers {
 1705                        let server = &adapters_and_servers[server_index].1;
 1706
 1707                        let describe_code_action = |action: &CodeAction| {
 1708                            format!(
 1709                                "code action '{}' with title \"{}\" on server {}",
 1710                                action
 1711                                    .lsp_action
 1712                                    .action_kind()
 1713                                    .unwrap_or("unknown".into())
 1714                                    .as_str(),
 1715                                action.lsp_action.title(),
 1716                                server.name(),
 1717                            )
 1718                        };
 1719
 1720                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1721
 1722                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1723                            zlog::error!(
 1724                                logger =>
 1725                                "Failed to resolve {}. Error: {}",
 1726                                describe_code_action(&action),
 1727                                err
 1728                            );
 1729                            continue;
 1730                        }
 1731
 1732                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1733                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1734                            // but filters out and logs warnings for code actions that require unreasonably
 1735                            // difficult handling on our part, such as:
 1736                            // - applying edits that call commands
 1737                            //   which can result in arbitrary workspace edits being sent from the server that
 1738                            //   have no way of being tied back to the command that initiated them (i.e. we
 1739                            //   can't know which edits are part of the format request, or if the server is done sending
 1740                            //   actions in response to the command)
 1741                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1742                            //   as we then would need to handle such changes correctly in the local history as well
 1743                            //   as the remote history through the ProjectTransaction
 1744                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1745                            // Supporting these actions is not impossible, but not supported as of yet.
 1746                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1747                                zlog::trace!(
 1748                                    logger =>
 1749                                    "No changes for code action. Skipping {}",
 1750                                    describe_code_action(&action),
 1751                                );
 1752                                continue;
 1753                            }
 1754
 1755                            let mut operations = Vec::new();
 1756                            if let Some(document_changes) = edit.document_changes {
 1757                                match document_changes {
 1758                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1759                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1760                                    ),
 1761                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1762                                }
 1763                            } else if let Some(changes) = edit.changes {
 1764                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1765                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1766                                        text_document:
 1767                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1768                                                uri,
 1769                                                version: None,
 1770                                            },
 1771                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1772                                    })
 1773                                }));
 1774                            }
 1775
 1776                            let mut edits = Vec::with_capacity(operations.len());
 1777
 1778                            if operations.is_empty() {
 1779                                zlog::trace!(
 1780                                    logger =>
 1781                                    "No changes for code action. Skipping {}",
 1782                                    describe_code_action(&action),
 1783                                );
 1784                                continue;
 1785                            }
 1786                            for operation in operations {
 1787                                let op = match operation {
 1788                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1789                                    lsp::DocumentChangeOperation::Op(_) => {
 1790                                        zlog::warn!(
 1791                                            logger =>
 1792                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1793                                            describe_code_action(&action),
 1794                                        );
 1795                                        continue 'actions;
 1796                                    }
 1797                                };
 1798                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1799                                    zlog::warn!(
 1800                                        logger =>
 1801                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1802                                        &op.text_document.uri,
 1803                                        describe_code_action(&action),
 1804                                    );
 1805                                    continue 'actions;
 1806                                };
 1807                                if &file_path != buffer_path_abs {
 1808                                    zlog::warn!(
 1809                                        logger =>
 1810                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1811                                        file_path,
 1812                                        buffer_path_abs,
 1813                                        describe_code_action(&action),
 1814                                    );
 1815                                    continue 'actions;
 1816                                }
 1817
 1818                                let mut lsp_edits = Vec::new();
 1819                                for edit in op.edits {
 1820                                    match edit {
 1821                                        Edit::Plain(edit) => {
 1822                                            if !lsp_edits.contains(&edit) {
 1823                                                lsp_edits.push(edit);
 1824                                            }
 1825                                        }
 1826                                        Edit::Annotated(edit) => {
 1827                                            if !lsp_edits.contains(&edit.text_edit) {
 1828                                                lsp_edits.push(edit.text_edit);
 1829                                            }
 1830                                        }
 1831                                        Edit::Snippet(_) => {
 1832                                            zlog::warn!(
 1833                                                logger =>
 1834                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1835                                                describe_code_action(&action),
 1836                                            );
 1837                                            continue 'actions;
 1838                                        }
 1839                                    }
 1840                                }
 1841                                let edits_result = lsp_store
 1842                                    .update(cx, |lsp_store, cx| {
 1843                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1844                                            &buffer.handle,
 1845                                            lsp_edits,
 1846                                            server.server_id(),
 1847                                            op.text_document.version,
 1848                                            cx,
 1849                                        )
 1850                                    })?
 1851                                    .await;
 1852                                let Ok(resolved_edits) = edits_result else {
 1853                                    zlog::warn!(
 1854                                        logger =>
 1855                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1856                                        buffer_path_abs.as_path(),
 1857                                        describe_code_action(&action),
 1858                                    );
 1859                                    continue 'actions;
 1860                                };
 1861                                edits.extend(resolved_edits);
 1862                            }
 1863
 1864                            if edits.is_empty() {
 1865                                zlog::warn!(logger => "No edits resolved from LSP");
 1866                                continue;
 1867                            }
 1868
 1869                            extend_formatting_transaction(
 1870                                buffer,
 1871                                formatting_transaction_id,
 1872                                cx,
 1873                                |buffer, cx| {
 1874                                    zlog::info!(
 1875                                        "Applying edits {edits:?}. Content: {:?}",
 1876                                        buffer.text()
 1877                                    );
 1878                                    buffer.edit(edits, None, cx);
 1879                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1880                                },
 1881                            )?;
 1882                        }
 1883
 1884                        if let Some(command) = action.lsp_action.command() {
 1885                            zlog::warn!(
 1886                                logger =>
 1887                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1888                                &command.command,
 1889                            );
 1890
 1891                            // bail early if command is invalid
 1892                            let server_capabilities = server.capabilities();
 1893                            let available_commands = server_capabilities
 1894                                .execute_command_provider
 1895                                .as_ref()
 1896                                .map(|options| options.commands.as_slice())
 1897                                .unwrap_or_default();
 1898                            if !available_commands.contains(&command.command) {
 1899                                zlog::warn!(
 1900                                    logger =>
 1901                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1902                                    command.command,
 1903                                    server.name(),
 1904                                );
 1905                                continue;
 1906                            }
 1907
 1908                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1909                            extend_formatting_transaction(
 1910                                buffer,
 1911                                formatting_transaction_id,
 1912                                cx,
 1913                                |_, _| {},
 1914                            )?;
 1915                            zlog::info!(logger => "Executing command {}", &command.command);
 1916
 1917                            lsp_store.update(cx, |this, _| {
 1918                                this.as_local_mut()
 1919                                    .unwrap()
 1920                                    .last_workspace_edits_by_language_server
 1921                                    .remove(&server.server_id());
 1922                            })?;
 1923
 1924                            let execute_command_result = server
 1925                                .request::<lsp::request::ExecuteCommand>(
 1926                                    lsp::ExecuteCommandParams {
 1927                                        command: command.command.clone(),
 1928                                        arguments: command.arguments.clone().unwrap_or_default(),
 1929                                        ..Default::default()
 1930                                    },
 1931                                )
 1932                                .await
 1933                                .into_response();
 1934
 1935                            if execute_command_result.is_err() {
 1936                                zlog::error!(
 1937                                    logger =>
 1938                                    "Failed to execute command '{}' as part of {}",
 1939                                    &command.command,
 1940                                    describe_code_action(&action),
 1941                                );
 1942                                continue 'actions;
 1943                            }
 1944
 1945                            let mut project_transaction_command =
 1946                                lsp_store.update(cx, |this, _| {
 1947                                    this.as_local_mut()
 1948                                        .unwrap()
 1949                                        .last_workspace_edits_by_language_server
 1950                                        .remove(&server.server_id())
 1951                                        .unwrap_or_default()
 1952                                })?;
 1953
 1954                            if let Some(transaction) =
 1955                                project_transaction_command.0.remove(&buffer.handle)
 1956                            {
 1957                                zlog::trace!(
 1958                                    logger =>
 1959                                    "Successfully captured {} edits that resulted from command {}",
 1960                                    transaction.edit_ids.len(),
 1961                                    &command.command,
 1962                                );
 1963                                let transaction_id_project_transaction = transaction.id;
 1964                                buffer.handle.update(cx, |buffer, _| {
 1965                                    // it may have been removed from history if push_to_history was
 1966                                    // false in deserialize_workspace_edit. If so push it so we
 1967                                    // can merge it with the format transaction
 1968                                    // and pop the combined transaction off the history stack
 1969                                    // later if push_to_history is false
 1970                                    if buffer.get_transaction(transaction.id).is_none() {
 1971                                        buffer.push_transaction(transaction, Instant::now());
 1972                                    }
 1973                                    buffer.merge_transactions(
 1974                                        transaction_id_project_transaction,
 1975                                        formatting_transaction_id,
 1976                                    );
 1977                                })?;
 1978                            }
 1979
 1980                            if !project_transaction_command.0.is_empty() {
 1981                                let mut extra_buffers = String::new();
 1982                                for buffer in project_transaction_command.0.keys() {
 1983                                    buffer
 1984                                        .read_with(cx, |b, cx| {
 1985                                            if let Some(path) = b.project_path(cx) {
 1986                                                if !extra_buffers.is_empty() {
 1987                                                    extra_buffers.push_str(", ");
 1988                                                }
 1989                                                extra_buffers.push_str(path.path.as_unix_str());
 1990                                            }
 1991                                        })
 1992                                        .ok();
 1993                                }
 1994                                zlog::warn!(
 1995                                    logger =>
 1996                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1997                                    &command.command,
 1998                                    extra_buffers,
 1999                                );
 2000                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2001                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2002                                // add it so it's included, and merge it into the format transaction when its created later
 2003                            }
 2004                        }
 2005                    }
 2006                }
 2007            }
 2008        }
 2009
 2010        Ok(())
 2011    }
 2012
 2013    pub async fn format_ranges_via_lsp(
 2014        this: &WeakEntity<LspStore>,
 2015        buffer_handle: &Entity<Buffer>,
 2016        ranges: &[Range<Anchor>],
 2017        abs_path: &Path,
 2018        language_server: &Arc<LanguageServer>,
 2019        settings: &LanguageSettings,
 2020        cx: &mut AsyncApp,
 2021    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2022        let capabilities = &language_server.capabilities();
 2023        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2024        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2025            anyhow::bail!(
 2026                "{} language server does not support range formatting",
 2027                language_server.name()
 2028            );
 2029        }
 2030
 2031        let uri = file_path_to_lsp_url(abs_path)?;
 2032        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2033
 2034        let lsp_edits = {
 2035            let mut lsp_ranges = Vec::new();
 2036            this.update(cx, |_this, cx| {
 2037                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2038                // not have been sent to the language server. This seems like a fairly systemic
 2039                // issue, though, the resolution probably is not specific to formatting.
 2040                //
 2041                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2042                // LSP.
 2043                let snapshot = buffer_handle.read(cx).snapshot();
 2044                for range in ranges {
 2045                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2046                }
 2047                anyhow::Ok(())
 2048            })??;
 2049
 2050            let mut edits = None;
 2051            for range in lsp_ranges {
 2052                if let Some(mut edit) = language_server
 2053                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2054                        text_document: text_document.clone(),
 2055                        range,
 2056                        options: lsp_command::lsp_formatting_options(settings),
 2057                        work_done_progress_params: Default::default(),
 2058                    })
 2059                    .await
 2060                    .into_response()?
 2061                {
 2062                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2063                }
 2064            }
 2065            edits
 2066        };
 2067
 2068        if let Some(lsp_edits) = lsp_edits {
 2069            this.update(cx, |this, cx| {
 2070                this.as_local_mut().unwrap().edits_from_lsp(
 2071                    buffer_handle,
 2072                    lsp_edits,
 2073                    language_server.server_id(),
 2074                    None,
 2075                    cx,
 2076                )
 2077            })?
 2078            .await
 2079        } else {
 2080            Ok(Vec::with_capacity(0))
 2081        }
 2082    }
 2083
 2084    async fn format_via_lsp(
 2085        this: &WeakEntity<LspStore>,
 2086        buffer: &Entity<Buffer>,
 2087        abs_path: &Path,
 2088        language_server: &Arc<LanguageServer>,
 2089        settings: &LanguageSettings,
 2090        cx: &mut AsyncApp,
 2091    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2092        let logger = zlog::scoped!("lsp_format");
 2093        zlog::debug!(logger => "Formatting via LSP");
 2094
 2095        let uri = file_path_to_lsp_url(abs_path)?;
 2096        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2097        let capabilities = &language_server.capabilities();
 2098
 2099        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2100        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2101
 2102        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2103            let _timer = zlog::time!(logger => "format-full");
 2104            language_server
 2105                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2106                    text_document,
 2107                    options: lsp_command::lsp_formatting_options(settings),
 2108                    work_done_progress_params: Default::default(),
 2109                })
 2110                .await
 2111                .into_response()?
 2112        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2113            let _timer = zlog::time!(logger => "format-range");
 2114            let buffer_start = lsp::Position::new(0, 0);
 2115            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2116            language_server
 2117                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2118                    text_document: text_document.clone(),
 2119                    range: lsp::Range::new(buffer_start, buffer_end),
 2120                    options: lsp_command::lsp_formatting_options(settings),
 2121                    work_done_progress_params: Default::default(),
 2122                })
 2123                .await
 2124                .into_response()?
 2125        } else {
 2126            None
 2127        };
 2128
 2129        if let Some(lsp_edits) = lsp_edits {
 2130            this.update(cx, |this, cx| {
 2131                this.as_local_mut().unwrap().edits_from_lsp(
 2132                    buffer,
 2133                    lsp_edits,
 2134                    language_server.server_id(),
 2135                    None,
 2136                    cx,
 2137                )
 2138            })?
 2139            .await
 2140        } else {
 2141            Ok(Vec::with_capacity(0))
 2142        }
 2143    }
 2144
 2145    async fn format_via_external_command(
 2146        buffer: &FormattableBuffer,
 2147        command: &str,
 2148        arguments: Option<&[String]>,
 2149        cx: &mut AsyncApp,
 2150    ) -> Result<Option<Diff>> {
 2151        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2152            let file = File::from_dyn(buffer.file())?;
 2153            let worktree = file.worktree.read(cx);
 2154            let mut worktree_path = worktree.abs_path().to_path_buf();
 2155            if worktree.root_entry()?.is_file() {
 2156                worktree_path.pop();
 2157            }
 2158            Some(worktree_path)
 2159        })?;
 2160
 2161        let mut child = util::command::new_smol_command(command);
 2162
 2163        if let Some(buffer_env) = buffer.env.as_ref() {
 2164            child.envs(buffer_env);
 2165        }
 2166
 2167        if let Some(working_dir_path) = working_dir_path {
 2168            child.current_dir(working_dir_path);
 2169        }
 2170
 2171        if let Some(arguments) = arguments {
 2172            child.args(arguments.iter().map(|arg| {
 2173                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2174                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2175                } else {
 2176                    arg.replace("{buffer_path}", "Untitled")
 2177                }
 2178            }));
 2179        }
 2180
 2181        let mut child = child
 2182            .stdin(smol::process::Stdio::piped())
 2183            .stdout(smol::process::Stdio::piped())
 2184            .stderr(smol::process::Stdio::piped())
 2185            .spawn()?;
 2186
 2187        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2188        let text = buffer
 2189            .handle
 2190            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2191        for chunk in text.chunks() {
 2192            stdin.write_all(chunk.as_bytes()).await?;
 2193        }
 2194        stdin.flush().await?;
 2195
 2196        let output = child.output().await?;
 2197        anyhow::ensure!(
 2198            output.status.success(),
 2199            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2200            output.status.code(),
 2201            String::from_utf8_lossy(&output.stdout),
 2202            String::from_utf8_lossy(&output.stderr),
 2203        );
 2204
 2205        let stdout = String::from_utf8(output.stdout)?;
 2206        Ok(Some(
 2207            buffer
 2208                .handle
 2209                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2210                .await,
 2211        ))
 2212    }
 2213
 2214    async fn try_resolve_code_action(
 2215        lang_server: &LanguageServer,
 2216        action: &mut CodeAction,
 2217    ) -> anyhow::Result<()> {
 2218        match &mut action.lsp_action {
 2219            LspAction::Action(lsp_action) => {
 2220                if !action.resolved
 2221                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2222                    && lsp_action.data.is_some()
 2223                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2224                {
 2225                    *lsp_action = Box::new(
 2226                        lang_server
 2227                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2228                            .await
 2229                            .into_response()?,
 2230                    );
 2231                }
 2232            }
 2233            LspAction::CodeLens(lens) => {
 2234                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2235                    *lens = lang_server
 2236                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2237                        .await
 2238                        .into_response()?;
 2239                }
 2240            }
 2241            LspAction::Command(_) => {}
 2242        }
 2243
 2244        action.resolved = true;
 2245        anyhow::Ok(())
 2246    }
 2247
 2248    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2249        let buffer = buffer_handle.read(cx);
 2250
 2251        let file = buffer.file().cloned();
 2252
 2253        let Some(file) = File::from_dyn(file.as_ref()) else {
 2254            return;
 2255        };
 2256        if !file.is_local() {
 2257            return;
 2258        }
 2259        let path = ProjectPath::from_file(file, cx);
 2260        let worktree_id = file.worktree_id(cx);
 2261        let language = buffer.language().cloned();
 2262
 2263        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2264            for (server_id, diagnostics) in
 2265                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2266            {
 2267                self.update_buffer_diagnostics(
 2268                    buffer_handle,
 2269                    server_id,
 2270                    None,
 2271                    None,
 2272                    None,
 2273                    Vec::new(),
 2274                    diagnostics,
 2275                    cx,
 2276                )
 2277                .log_err();
 2278            }
 2279        }
 2280        let Some(language) = language else {
 2281            return;
 2282        };
 2283        let Some(snapshot) = self
 2284            .worktree_store
 2285            .read(cx)
 2286            .worktree_for_id(worktree_id, cx)
 2287            .map(|worktree| worktree.read(cx).snapshot())
 2288        else {
 2289            return;
 2290        };
 2291        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2292
 2293        for server_id in
 2294            self.lsp_tree
 2295                .get(path, language.name(), language.manifest(), &delegate, cx)
 2296        {
 2297            let server = self
 2298                .language_servers
 2299                .get(&server_id)
 2300                .and_then(|server_state| {
 2301                    if let LanguageServerState::Running { server, .. } = server_state {
 2302                        Some(server.clone())
 2303                    } else {
 2304                        None
 2305                    }
 2306                });
 2307            let server = match server {
 2308                Some(server) => server,
 2309                None => continue,
 2310            };
 2311
 2312            buffer_handle.update(cx, |buffer, cx| {
 2313                buffer.set_completion_triggers(
 2314                    server.server_id(),
 2315                    server
 2316                        .capabilities()
 2317                        .completion_provider
 2318                        .as_ref()
 2319                        .and_then(|provider| {
 2320                            provider
 2321                                .trigger_characters
 2322                                .as_ref()
 2323                                .map(|characters| characters.iter().cloned().collect())
 2324                        })
 2325                        .unwrap_or_default(),
 2326                    cx,
 2327                );
 2328            });
 2329        }
 2330    }
 2331
 2332    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2333        buffer.update(cx, |buffer, cx| {
 2334            let Some(language) = buffer.language() else {
 2335                return;
 2336            };
 2337            let path = ProjectPath {
 2338                worktree_id: old_file.worktree_id(cx),
 2339                path: old_file.path.clone(),
 2340            };
 2341            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2342                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2343                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2344            }
 2345        });
 2346    }
 2347
 2348    fn update_buffer_diagnostics(
 2349        &mut self,
 2350        buffer: &Entity<Buffer>,
 2351        server_id: LanguageServerId,
 2352        registration_id: Option<Option<SharedString>>,
 2353        result_id: Option<SharedString>,
 2354        version: Option<i32>,
 2355        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2356        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2357        cx: &mut Context<LspStore>,
 2358    ) -> Result<()> {
 2359        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2360            Ordering::Equal
 2361                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2362                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2363                .then_with(|| a.severity.cmp(&b.severity))
 2364                .then_with(|| a.message.cmp(&b.message))
 2365        }
 2366
 2367        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2368        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2369        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2370
 2371        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2372            Ordering::Equal
 2373                .then_with(|| a.range.start.cmp(&b.range.start))
 2374                .then_with(|| b.range.end.cmp(&a.range.end))
 2375                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2376        });
 2377
 2378        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2379
 2380        let edits_since_save = std::cell::LazyCell::new(|| {
 2381            let saved_version = buffer.read(cx).saved_version();
 2382            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2383        });
 2384
 2385        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2386
 2387        for (new_diagnostic, entry) in diagnostics {
 2388            let start;
 2389            let end;
 2390            if new_diagnostic && entry.diagnostic.is_disk_based {
 2391                // Some diagnostics are based on files on disk instead of buffers'
 2392                // current contents. Adjust these diagnostics' ranges to reflect
 2393                // any unsaved edits.
 2394                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2395                // and were properly adjusted on reuse.
 2396                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2397                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2398            } else {
 2399                start = entry.range.start;
 2400                end = entry.range.end;
 2401            }
 2402
 2403            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2404                ..snapshot.clip_point_utf16(end, Bias::Right);
 2405
 2406            // Expand empty ranges by one codepoint
 2407            if range.start == range.end {
 2408                // This will be go to the next boundary when being clipped
 2409                range.end.column += 1;
 2410                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2411                if range.start == range.end && range.end.column > 0 {
 2412                    range.start.column -= 1;
 2413                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2414                }
 2415            }
 2416
 2417            sanitized_diagnostics.push(DiagnosticEntry {
 2418                range,
 2419                diagnostic: entry.diagnostic,
 2420            });
 2421        }
 2422        drop(edits_since_save);
 2423
 2424        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2425        buffer.update(cx, |buffer, cx| {
 2426            if let Some(registration_id) = registration_id {
 2427                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2428                    self.buffer_pull_diagnostics_result_ids
 2429                        .entry(server_id)
 2430                        .or_default()
 2431                        .entry(registration_id)
 2432                        .or_default()
 2433                        .insert(abs_path, result_id);
 2434                }
 2435            }
 2436
 2437            buffer.update_diagnostics(server_id, set, cx)
 2438        });
 2439
 2440        Ok(())
 2441    }
 2442
 2443    fn register_language_server_for_invisible_worktree(
 2444        &mut self,
 2445        worktree: &Entity<Worktree>,
 2446        language_server_id: LanguageServerId,
 2447        cx: &mut App,
 2448    ) {
 2449        let worktree = worktree.read(cx);
 2450        let worktree_id = worktree.id();
 2451        debug_assert!(!worktree.is_visible());
 2452        let Some(mut origin_seed) = self
 2453            .language_server_ids
 2454            .iter()
 2455            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2456        else {
 2457            return;
 2458        };
 2459        origin_seed.worktree_id = worktree_id;
 2460        self.language_server_ids
 2461            .entry(origin_seed)
 2462            .or_insert_with(|| UnifiedLanguageServer {
 2463                id: language_server_id,
 2464                project_roots: Default::default(),
 2465            });
 2466    }
 2467
 2468    fn register_buffer_with_language_servers(
 2469        &mut self,
 2470        buffer_handle: &Entity<Buffer>,
 2471        only_register_servers: HashSet<LanguageServerSelector>,
 2472        cx: &mut Context<LspStore>,
 2473    ) {
 2474        let buffer = buffer_handle.read(cx);
 2475        let buffer_id = buffer.remote_id();
 2476
 2477        let Some(file) = File::from_dyn(buffer.file()) else {
 2478            return;
 2479        };
 2480        if !file.is_local() {
 2481            return;
 2482        }
 2483
 2484        let abs_path = file.abs_path(cx);
 2485        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2486            return;
 2487        };
 2488        let initial_snapshot = buffer.text_snapshot();
 2489        let worktree_id = file.worktree_id(cx);
 2490
 2491        let Some(language) = buffer.language().cloned() else {
 2492            return;
 2493        };
 2494        let path: Arc<RelPath> = file
 2495            .path()
 2496            .parent()
 2497            .map(Arc::from)
 2498            .unwrap_or_else(|| file.path().clone());
 2499        let Some(worktree) = self
 2500            .worktree_store
 2501            .read(cx)
 2502            .worktree_for_id(worktree_id, cx)
 2503        else {
 2504            return;
 2505        };
 2506        let language_name = language.name();
 2507        let (reused, delegate, servers) = self
 2508            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2509            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2510            .unwrap_or_else(|| {
 2511                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2512                let delegate: Arc<dyn ManifestDelegate> =
 2513                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2514
 2515                let servers = self
 2516                    .lsp_tree
 2517                    .walk(
 2518                        ProjectPath { worktree_id, path },
 2519                        language.name(),
 2520                        language.manifest(),
 2521                        &delegate,
 2522                        cx,
 2523                    )
 2524                    .collect::<Vec<_>>();
 2525                (false, lsp_delegate, servers)
 2526            });
 2527        let servers_and_adapters = servers
 2528            .into_iter()
 2529            .filter_map(|server_node| {
 2530                if reused && server_node.server_id().is_none() {
 2531                    return None;
 2532                }
 2533                if !only_register_servers.is_empty() {
 2534                    if let Some(server_id) = server_node.server_id()
 2535                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2536                    {
 2537                        return None;
 2538                    }
 2539                    if let Some(name) = server_node.name()
 2540                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2541                    {
 2542                        return None;
 2543                    }
 2544                }
 2545
 2546                let server_id = server_node.server_id_or_init(|disposition| {
 2547                    let path = &disposition.path;
 2548
 2549                    {
 2550                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2551
 2552                        let server_id = self.get_or_insert_language_server(
 2553                            &worktree,
 2554                            delegate.clone(),
 2555                            disposition,
 2556                            &language_name,
 2557                            cx,
 2558                        );
 2559
 2560                        if let Some(state) = self.language_servers.get(&server_id)
 2561                            && let Ok(uri) = uri
 2562                        {
 2563                            state.add_workspace_folder(uri);
 2564                        };
 2565                        server_id
 2566                    }
 2567                })?;
 2568                let server_state = self.language_servers.get(&server_id)?;
 2569                if let LanguageServerState::Running {
 2570                    server, adapter, ..
 2571                } = server_state
 2572                {
 2573                    Some((server.clone(), adapter.clone()))
 2574                } else {
 2575                    None
 2576                }
 2577            })
 2578            .collect::<Vec<_>>();
 2579        for (server, adapter) in servers_and_adapters {
 2580            buffer_handle.update(cx, |buffer, cx| {
 2581                buffer.set_completion_triggers(
 2582                    server.server_id(),
 2583                    server
 2584                        .capabilities()
 2585                        .completion_provider
 2586                        .as_ref()
 2587                        .and_then(|provider| {
 2588                            provider
 2589                                .trigger_characters
 2590                                .as_ref()
 2591                                .map(|characters| characters.iter().cloned().collect())
 2592                        })
 2593                        .unwrap_or_default(),
 2594                    cx,
 2595                );
 2596            });
 2597
 2598            let snapshot = LspBufferSnapshot {
 2599                version: 0,
 2600                snapshot: initial_snapshot.clone(),
 2601            };
 2602
 2603            let mut registered = false;
 2604            self.buffer_snapshots
 2605                .entry(buffer_id)
 2606                .or_default()
 2607                .entry(server.server_id())
 2608                .or_insert_with(|| {
 2609                    registered = true;
 2610                    server.register_buffer(
 2611                        uri.clone(),
 2612                        adapter.language_id(&language.name()),
 2613                        0,
 2614                        initial_snapshot.text(),
 2615                    );
 2616
 2617                    vec![snapshot]
 2618                });
 2619
 2620            self.buffers_opened_in_servers
 2621                .entry(buffer_id)
 2622                .or_default()
 2623                .insert(server.server_id());
 2624            if registered {
 2625                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2626                    language_server_id: server.server_id(),
 2627                    name: None,
 2628                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2629                        proto::RegisteredForBuffer {
 2630                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2631                            buffer_id: buffer_id.to_proto(),
 2632                        },
 2633                    ),
 2634                });
 2635            }
 2636        }
 2637    }
 2638
 2639    fn reuse_existing_language_server<'lang_name>(
 2640        &self,
 2641        server_tree: &LanguageServerTree,
 2642        worktree: &Entity<Worktree>,
 2643        language_name: &'lang_name LanguageName,
 2644        cx: &mut App,
 2645    ) -> Option<(
 2646        Arc<LocalLspAdapterDelegate>,
 2647        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2648    )> {
 2649        if worktree.read(cx).is_visible() {
 2650            return None;
 2651        }
 2652
 2653        let worktree_store = self.worktree_store.read(cx);
 2654        let servers = server_tree
 2655            .instances
 2656            .iter()
 2657            .filter(|(worktree_id, _)| {
 2658                worktree_store
 2659                    .worktree_for_id(**worktree_id, cx)
 2660                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2661            })
 2662            .flat_map(|(worktree_id, servers)| {
 2663                servers
 2664                    .roots
 2665                    .iter()
 2666                    .flat_map(|(_, language_servers)| language_servers)
 2667                    .map(move |(_, (server_node, server_languages))| {
 2668                        (worktree_id, server_node, server_languages)
 2669                    })
 2670                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2671                    .map(|(worktree_id, server_node, _)| {
 2672                        (
 2673                            *worktree_id,
 2674                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2675                        )
 2676                    })
 2677            })
 2678            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2679                acc.entry(worktree_id)
 2680                    .or_insert_with(Vec::new)
 2681                    .push(server_node);
 2682                acc
 2683            })
 2684            .into_values()
 2685            .max_by_key(|servers| servers.len())?;
 2686
 2687        let worktree_id = worktree.read(cx).id();
 2688        let apply = move |tree: &mut LanguageServerTree| {
 2689            for server_node in &servers {
 2690                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2691            }
 2692            servers
 2693        };
 2694
 2695        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2696        Some((delegate, apply))
 2697    }
 2698
 2699    pub(crate) fn unregister_old_buffer_from_language_servers(
 2700        &mut self,
 2701        buffer: &Entity<Buffer>,
 2702        old_file: &File,
 2703        cx: &mut App,
 2704    ) {
 2705        let old_path = match old_file.as_local() {
 2706            Some(local) => local.abs_path(cx),
 2707            None => return,
 2708        };
 2709
 2710        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2711            debug_panic!("{old_path:?} is not parseable as an URI");
 2712            return;
 2713        };
 2714        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2715    }
 2716
 2717    pub(crate) fn unregister_buffer_from_language_servers(
 2718        &mut self,
 2719        buffer: &Entity<Buffer>,
 2720        file_url: &lsp::Uri,
 2721        cx: &mut App,
 2722    ) {
 2723        buffer.update(cx, |buffer, cx| {
 2724            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2725
 2726            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2727                if snapshots
 2728                    .as_mut()
 2729                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2730                {
 2731                    language_server.unregister_buffer(file_url.clone());
 2732                }
 2733            }
 2734        });
 2735    }
 2736
 2737    fn buffer_snapshot_for_lsp_version(
 2738        &mut self,
 2739        buffer: &Entity<Buffer>,
 2740        server_id: LanguageServerId,
 2741        version: Option<i32>,
 2742        cx: &App,
 2743    ) -> Result<TextBufferSnapshot> {
 2744        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2745
 2746        if let Some(version) = version {
 2747            let buffer_id = buffer.read(cx).remote_id();
 2748            let snapshots = if let Some(snapshots) = self
 2749                .buffer_snapshots
 2750                .get_mut(&buffer_id)
 2751                .and_then(|m| m.get_mut(&server_id))
 2752            {
 2753                snapshots
 2754            } else if version == 0 {
 2755                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2756                // We detect this case and treat it as if the version was `None`.
 2757                return Ok(buffer.read(cx).text_snapshot());
 2758            } else {
 2759                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2760            };
 2761
 2762            let found_snapshot = snapshots
 2763                    .binary_search_by_key(&version, |e| e.version)
 2764                    .map(|ix| snapshots[ix].snapshot.clone())
 2765                    .map_err(|_| {
 2766                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2767                    })?;
 2768
 2769            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2770            Ok(found_snapshot)
 2771        } else {
 2772            Ok((buffer.read(cx)).text_snapshot())
 2773        }
 2774    }
 2775
 2776    async fn get_server_code_actions_from_action_kinds(
 2777        lsp_store: &WeakEntity<LspStore>,
 2778        language_server_id: LanguageServerId,
 2779        code_action_kinds: Vec<lsp::CodeActionKind>,
 2780        buffer: &Entity<Buffer>,
 2781        cx: &mut AsyncApp,
 2782    ) -> Result<Vec<CodeAction>> {
 2783        let actions = lsp_store
 2784            .update(cx, move |this, cx| {
 2785                let request = GetCodeActions {
 2786                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2787                    kinds: Some(code_action_kinds),
 2788                };
 2789                let server = LanguageServerToQuery::Other(language_server_id);
 2790                this.request_lsp(buffer.clone(), server, request, cx)
 2791            })?
 2792            .await?;
 2793        Ok(actions)
 2794    }
 2795
 2796    pub async fn execute_code_actions_on_server(
 2797        lsp_store: &WeakEntity<LspStore>,
 2798        language_server: &Arc<LanguageServer>,
 2799
 2800        actions: Vec<CodeAction>,
 2801        push_to_history: bool,
 2802        project_transaction: &mut ProjectTransaction,
 2803        cx: &mut AsyncApp,
 2804    ) -> anyhow::Result<()> {
 2805        for mut action in actions {
 2806            Self::try_resolve_code_action(language_server, &mut action)
 2807                .await
 2808                .context("resolving a formatting code action")?;
 2809
 2810            if let Some(edit) = action.lsp_action.edit() {
 2811                if edit.changes.is_none() && edit.document_changes.is_none() {
 2812                    continue;
 2813                }
 2814
 2815                let new = Self::deserialize_workspace_edit(
 2816                    lsp_store.upgrade().context("project dropped")?,
 2817                    edit.clone(),
 2818                    push_to_history,
 2819                    language_server.clone(),
 2820                    cx,
 2821                )
 2822                .await?;
 2823                project_transaction.0.extend(new.0);
 2824            }
 2825
 2826            if let Some(command) = action.lsp_action.command() {
 2827                let server_capabilities = language_server.capabilities();
 2828                let available_commands = server_capabilities
 2829                    .execute_command_provider
 2830                    .as_ref()
 2831                    .map(|options| options.commands.as_slice())
 2832                    .unwrap_or_default();
 2833                if available_commands.contains(&command.command) {
 2834                    lsp_store.update(cx, |lsp_store, _| {
 2835                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2836                            mode.last_workspace_edits_by_language_server
 2837                                .remove(&language_server.server_id());
 2838                        }
 2839                    })?;
 2840
 2841                    language_server
 2842                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2843                            command: command.command.clone(),
 2844                            arguments: command.arguments.clone().unwrap_or_default(),
 2845                            ..Default::default()
 2846                        })
 2847                        .await
 2848                        .into_response()
 2849                        .context("execute command")?;
 2850
 2851                    lsp_store.update(cx, |this, _| {
 2852                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2853                            project_transaction.0.extend(
 2854                                mode.last_workspace_edits_by_language_server
 2855                                    .remove(&language_server.server_id())
 2856                                    .unwrap_or_default()
 2857                                    .0,
 2858                            )
 2859                        }
 2860                    })?;
 2861                } else {
 2862                    log::warn!(
 2863                        "Cannot execute a command {} not listed in the language server capabilities",
 2864                        command.command
 2865                    )
 2866                }
 2867            }
 2868        }
 2869        Ok(())
 2870    }
 2871
 2872    pub async fn deserialize_text_edits(
 2873        this: Entity<LspStore>,
 2874        buffer_to_edit: Entity<Buffer>,
 2875        edits: Vec<lsp::TextEdit>,
 2876        push_to_history: bool,
 2877        _: Arc<CachedLspAdapter>,
 2878        language_server: Arc<LanguageServer>,
 2879        cx: &mut AsyncApp,
 2880    ) -> Result<Option<Transaction>> {
 2881        let edits = this
 2882            .update(cx, |this, cx| {
 2883                this.as_local_mut().unwrap().edits_from_lsp(
 2884                    &buffer_to_edit,
 2885                    edits,
 2886                    language_server.server_id(),
 2887                    None,
 2888                    cx,
 2889                )
 2890            })?
 2891            .await?;
 2892
 2893        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2894            buffer.finalize_last_transaction();
 2895            buffer.start_transaction();
 2896            for (range, text) in edits {
 2897                buffer.edit([(range, text)], None, cx);
 2898            }
 2899
 2900            if buffer.end_transaction(cx).is_some() {
 2901                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2902                if !push_to_history {
 2903                    buffer.forget_transaction(transaction.id);
 2904                }
 2905                Some(transaction)
 2906            } else {
 2907                None
 2908            }
 2909        })?;
 2910
 2911        Ok(transaction)
 2912    }
 2913
 2914    #[allow(clippy::type_complexity)]
 2915    pub(crate) fn edits_from_lsp(
 2916        &mut self,
 2917        buffer: &Entity<Buffer>,
 2918        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2919        server_id: LanguageServerId,
 2920        version: Option<i32>,
 2921        cx: &mut Context<LspStore>,
 2922    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2923        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2924        cx.background_spawn(async move {
 2925            let snapshot = snapshot?;
 2926            let mut lsp_edits = lsp_edits
 2927                .into_iter()
 2928                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2929                .collect::<Vec<_>>();
 2930
 2931            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2932
 2933            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2934            let mut edits = Vec::new();
 2935            while let Some((range, mut new_text)) = lsp_edits.next() {
 2936                // Clip invalid ranges provided by the language server.
 2937                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2938                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2939
 2940                // Combine any LSP edits that are adjacent.
 2941                //
 2942                // Also, combine LSP edits that are separated from each other by only
 2943                // a newline. This is important because for some code actions,
 2944                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2945                // are separated by unchanged newline characters.
 2946                //
 2947                // In order for the diffing logic below to work properly, any edits that
 2948                // cancel each other out must be combined into one.
 2949                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2950                    if next_range.start.0 > range.end {
 2951                        if next_range.start.0.row > range.end.row + 1
 2952                            || next_range.start.0.column > 0
 2953                            || snapshot.clip_point_utf16(
 2954                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2955                                Bias::Left,
 2956                            ) > range.end
 2957                        {
 2958                            break;
 2959                        }
 2960                        new_text.push('\n');
 2961                    }
 2962                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2963                    new_text.push_str(next_text);
 2964                    lsp_edits.next();
 2965                }
 2966
 2967                // For multiline edits, perform a diff of the old and new text so that
 2968                // we can identify the changes more precisely, preserving the locations
 2969                // of any anchors positioned in the unchanged regions.
 2970                if range.end.row > range.start.row {
 2971                    let offset = range.start.to_offset(&snapshot);
 2972                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2973                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2974                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2975                        (
 2976                            snapshot.anchor_after(offset + range.start)
 2977                                ..snapshot.anchor_before(offset + range.end),
 2978                            replacement,
 2979                        )
 2980                    }));
 2981                } else if range.end == range.start {
 2982                    let anchor = snapshot.anchor_after(range.start);
 2983                    edits.push((anchor..anchor, new_text.into()));
 2984                } else {
 2985                    let edit_start = snapshot.anchor_after(range.start);
 2986                    let edit_end = snapshot.anchor_before(range.end);
 2987                    edits.push((edit_start..edit_end, new_text.into()));
 2988                }
 2989            }
 2990
 2991            Ok(edits)
 2992        })
 2993    }
 2994
 2995    pub(crate) async fn deserialize_workspace_edit(
 2996        this: Entity<LspStore>,
 2997        edit: lsp::WorkspaceEdit,
 2998        push_to_history: bool,
 2999        language_server: Arc<LanguageServer>,
 3000        cx: &mut AsyncApp,
 3001    ) -> Result<ProjectTransaction> {
 3002        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3003
 3004        let mut operations = Vec::new();
 3005        if let Some(document_changes) = edit.document_changes {
 3006            match document_changes {
 3007                lsp::DocumentChanges::Edits(edits) => {
 3008                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3009                }
 3010                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3011            }
 3012        } else if let Some(changes) = edit.changes {
 3013            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3014                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3015                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3016                        uri,
 3017                        version: None,
 3018                    },
 3019                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3020                })
 3021            }));
 3022        }
 3023
 3024        let mut project_transaction = ProjectTransaction::default();
 3025        for operation in operations {
 3026            match operation {
 3027                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3028                    let abs_path = op
 3029                        .uri
 3030                        .to_file_path()
 3031                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3032
 3033                    if let Some(parent_path) = abs_path.parent() {
 3034                        fs.create_dir(parent_path).await?;
 3035                    }
 3036                    if abs_path.ends_with("/") {
 3037                        fs.create_dir(&abs_path).await?;
 3038                    } else {
 3039                        fs.create_file(
 3040                            &abs_path,
 3041                            op.options
 3042                                .map(|options| fs::CreateOptions {
 3043                                    overwrite: options.overwrite.unwrap_or(false),
 3044                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3045                                })
 3046                                .unwrap_or_default(),
 3047                        )
 3048                        .await?;
 3049                    }
 3050                }
 3051
 3052                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3053                    let source_abs_path = op
 3054                        .old_uri
 3055                        .to_file_path()
 3056                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3057                    let target_abs_path = op
 3058                        .new_uri
 3059                        .to_file_path()
 3060                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3061
 3062                    let options = fs::RenameOptions {
 3063                        overwrite: op
 3064                            .options
 3065                            .as_ref()
 3066                            .and_then(|options| options.overwrite)
 3067                            .unwrap_or(false),
 3068                        ignore_if_exists: op
 3069                            .options
 3070                            .as_ref()
 3071                            .and_then(|options| options.ignore_if_exists)
 3072                            .unwrap_or(false),
 3073                        create_parents: true,
 3074                    };
 3075
 3076                    fs.rename(&source_abs_path, &target_abs_path, options)
 3077                        .await?;
 3078                }
 3079
 3080                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3081                    let abs_path = op
 3082                        .uri
 3083                        .to_file_path()
 3084                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3085                    let options = op
 3086                        .options
 3087                        .map(|options| fs::RemoveOptions {
 3088                            recursive: options.recursive.unwrap_or(false),
 3089                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3090                        })
 3091                        .unwrap_or_default();
 3092                    if abs_path.ends_with("/") {
 3093                        fs.remove_dir(&abs_path, options).await?;
 3094                    } else {
 3095                        fs.remove_file(&abs_path, options).await?;
 3096                    }
 3097                }
 3098
 3099                lsp::DocumentChangeOperation::Edit(op) => {
 3100                    let buffer_to_edit = this
 3101                        .update(cx, |this, cx| {
 3102                            this.open_local_buffer_via_lsp(
 3103                                op.text_document.uri.clone(),
 3104                                language_server.server_id(),
 3105                                cx,
 3106                            )
 3107                        })?
 3108                        .await?;
 3109
 3110                    let edits = this
 3111                        .update(cx, |this, cx| {
 3112                            let path = buffer_to_edit.read(cx).project_path(cx);
 3113                            let active_entry = this.active_entry;
 3114                            let is_active_entry = path.is_some_and(|project_path| {
 3115                                this.worktree_store
 3116                                    .read(cx)
 3117                                    .entry_for_path(&project_path, cx)
 3118                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3119                            });
 3120                            let local = this.as_local_mut().unwrap();
 3121
 3122                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3123                            for edit in op.edits {
 3124                                match edit {
 3125                                    Edit::Plain(edit) => {
 3126                                        if !edits.contains(&edit) {
 3127                                            edits.push(edit)
 3128                                        }
 3129                                    }
 3130                                    Edit::Annotated(edit) => {
 3131                                        if !edits.contains(&edit.text_edit) {
 3132                                            edits.push(edit.text_edit)
 3133                                        }
 3134                                    }
 3135                                    Edit::Snippet(edit) => {
 3136                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3137                                        else {
 3138                                            continue;
 3139                                        };
 3140
 3141                                        if is_active_entry {
 3142                                            snippet_edits.push((edit.range, snippet));
 3143                                        } else {
 3144                                            // Since this buffer is not focused, apply a normal edit.
 3145                                            let new_edit = TextEdit {
 3146                                                range: edit.range,
 3147                                                new_text: snippet.text,
 3148                                            };
 3149                                            if !edits.contains(&new_edit) {
 3150                                                edits.push(new_edit);
 3151                                            }
 3152                                        }
 3153                                    }
 3154                                }
 3155                            }
 3156                            if !snippet_edits.is_empty() {
 3157                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3158                                let version = if let Some(buffer_version) = op.text_document.version
 3159                                {
 3160                                    local
 3161                                        .buffer_snapshot_for_lsp_version(
 3162                                            &buffer_to_edit,
 3163                                            language_server.server_id(),
 3164                                            Some(buffer_version),
 3165                                            cx,
 3166                                        )
 3167                                        .ok()
 3168                                        .map(|snapshot| snapshot.version)
 3169                                } else {
 3170                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3171                                };
 3172
 3173                                let most_recent_edit =
 3174                                    version.and_then(|version| version.most_recent());
 3175                                // Check if the edit that triggered that edit has been made by this participant.
 3176
 3177                                if let Some(most_recent_edit) = most_recent_edit {
 3178                                    cx.emit(LspStoreEvent::SnippetEdit {
 3179                                        buffer_id,
 3180                                        edits: snippet_edits,
 3181                                        most_recent_edit,
 3182                                    });
 3183                                }
 3184                            }
 3185
 3186                            local.edits_from_lsp(
 3187                                &buffer_to_edit,
 3188                                edits,
 3189                                language_server.server_id(),
 3190                                op.text_document.version,
 3191                                cx,
 3192                            )
 3193                        })?
 3194                        .await?;
 3195
 3196                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3197                        buffer.finalize_last_transaction();
 3198                        buffer.start_transaction();
 3199                        for (range, text) in edits {
 3200                            buffer.edit([(range, text)], None, cx);
 3201                        }
 3202
 3203                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3204                            if push_to_history {
 3205                                buffer.finalize_last_transaction();
 3206                                buffer.get_transaction(transaction_id).cloned()
 3207                            } else {
 3208                                buffer.forget_transaction(transaction_id)
 3209                            }
 3210                        })
 3211                    })?;
 3212                    if let Some(transaction) = transaction {
 3213                        project_transaction.0.insert(buffer_to_edit, transaction);
 3214                    }
 3215                }
 3216            }
 3217        }
 3218
 3219        Ok(project_transaction)
 3220    }
 3221
 3222    async fn on_lsp_workspace_edit(
 3223        this: WeakEntity<LspStore>,
 3224        params: lsp::ApplyWorkspaceEditParams,
 3225        server_id: LanguageServerId,
 3226        cx: &mut AsyncApp,
 3227    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3228        let this = this.upgrade().context("project project closed")?;
 3229        let language_server = this
 3230            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3231            .context("language server not found")?;
 3232        let transaction = Self::deserialize_workspace_edit(
 3233            this.clone(),
 3234            params.edit,
 3235            true,
 3236            language_server.clone(),
 3237            cx,
 3238        )
 3239        .await
 3240        .log_err();
 3241        this.update(cx, |this, _| {
 3242            if let Some(transaction) = transaction {
 3243                this.as_local_mut()
 3244                    .unwrap()
 3245                    .last_workspace_edits_by_language_server
 3246                    .insert(server_id, transaction);
 3247            }
 3248        })?;
 3249        Ok(lsp::ApplyWorkspaceEditResponse {
 3250            applied: true,
 3251            failed_change: None,
 3252            failure_reason: None,
 3253        })
 3254    }
 3255
 3256    fn remove_worktree(
 3257        &mut self,
 3258        id_to_remove: WorktreeId,
 3259        cx: &mut Context<LspStore>,
 3260    ) -> Vec<LanguageServerId> {
 3261        self.diagnostics.remove(&id_to_remove);
 3262        self.prettier_store.update(cx, |prettier_store, cx| {
 3263            prettier_store.remove_worktree(id_to_remove, cx);
 3264        });
 3265
 3266        let mut servers_to_remove = BTreeSet::default();
 3267        let mut servers_to_preserve = HashSet::default();
 3268        for (seed, state) in &self.language_server_ids {
 3269            if seed.worktree_id == id_to_remove {
 3270                servers_to_remove.insert(state.id);
 3271            } else {
 3272                servers_to_preserve.insert(state.id);
 3273            }
 3274        }
 3275        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3276        self.language_server_ids
 3277            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3278        for server_id_to_remove in &servers_to_remove {
 3279            self.language_server_watched_paths
 3280                .remove(server_id_to_remove);
 3281            self.language_server_paths_watched_for_rename
 3282                .remove(server_id_to_remove);
 3283            self.last_workspace_edits_by_language_server
 3284                .remove(server_id_to_remove);
 3285            self.language_servers.remove(server_id_to_remove);
 3286            self.buffer_pull_diagnostics_result_ids
 3287                .remove(server_id_to_remove);
 3288            self.workspace_pull_diagnostics_result_ids
 3289                .remove(server_id_to_remove);
 3290            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3291                buffer_servers.remove(server_id_to_remove);
 3292            }
 3293            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3294        }
 3295        servers_to_remove.into_iter().collect()
 3296    }
 3297
 3298    fn rebuild_watched_paths_inner<'a>(
 3299        &'a self,
 3300        language_server_id: LanguageServerId,
 3301        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3302        cx: &mut Context<LspStore>,
 3303    ) -> LanguageServerWatchedPathsBuilder {
 3304        let worktrees = self
 3305            .worktree_store
 3306            .read(cx)
 3307            .worktrees()
 3308            .filter_map(|worktree| {
 3309                self.language_servers_for_worktree(worktree.read(cx).id())
 3310                    .find(|server| server.server_id() == language_server_id)
 3311                    .map(|_| worktree)
 3312            })
 3313            .collect::<Vec<_>>();
 3314
 3315        let mut worktree_globs = HashMap::default();
 3316        let mut abs_globs = HashMap::default();
 3317        log::trace!(
 3318            "Processing new watcher paths for language server with id {}",
 3319            language_server_id
 3320        );
 3321
 3322        for watcher in watchers {
 3323            if let Some((worktree, literal_prefix, pattern)) =
 3324                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3325            {
 3326                worktree.update(cx, |worktree, _| {
 3327                    if let Some((tree, glob)) =
 3328                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3329                    {
 3330                        tree.add_path_prefix_to_scan(literal_prefix);
 3331                        worktree_globs
 3332                            .entry(tree.id())
 3333                            .or_insert_with(GlobSetBuilder::new)
 3334                            .add(glob);
 3335                    }
 3336                });
 3337            } else {
 3338                let (path, pattern) = match &watcher.glob_pattern {
 3339                    lsp::GlobPattern::String(s) => {
 3340                        let watcher_path = SanitizedPath::new(s);
 3341                        let path = glob_literal_prefix(watcher_path.as_path());
 3342                        let pattern = watcher_path
 3343                            .as_path()
 3344                            .strip_prefix(&path)
 3345                            .map(|p| p.to_string_lossy().into_owned())
 3346                            .unwrap_or_else(|e| {
 3347                                debug_panic!(
 3348                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3349                                    s,
 3350                                    path.display(),
 3351                                    e
 3352                                );
 3353                                watcher_path.as_path().to_string_lossy().into_owned()
 3354                            });
 3355                        (path, pattern)
 3356                    }
 3357                    lsp::GlobPattern::Relative(rp) => {
 3358                        let Ok(mut base_uri) = match &rp.base_uri {
 3359                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3360                            lsp::OneOf::Right(base_uri) => base_uri,
 3361                        }
 3362                        .to_file_path() else {
 3363                            continue;
 3364                        };
 3365
 3366                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3367                        let pattern = Path::new(&rp.pattern)
 3368                            .strip_prefix(&path)
 3369                            .map(|p| p.to_string_lossy().into_owned())
 3370                            .unwrap_or_else(|e| {
 3371                                debug_panic!(
 3372                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3373                                    rp.pattern,
 3374                                    path.display(),
 3375                                    e
 3376                                );
 3377                                rp.pattern.clone()
 3378                            });
 3379                        base_uri.push(path);
 3380                        (base_uri, pattern)
 3381                    }
 3382                };
 3383
 3384                if let Some(glob) = Glob::new(&pattern).log_err() {
 3385                    if !path
 3386                        .components()
 3387                        .any(|c| matches!(c, path::Component::Normal(_)))
 3388                    {
 3389                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3390                        // rather than adding a new watcher for `/`.
 3391                        for worktree in &worktrees {
 3392                            worktree_globs
 3393                                .entry(worktree.read(cx).id())
 3394                                .or_insert_with(GlobSetBuilder::new)
 3395                                .add(glob.clone());
 3396                        }
 3397                    } else {
 3398                        abs_globs
 3399                            .entry(path.into())
 3400                            .or_insert_with(GlobSetBuilder::new)
 3401                            .add(glob);
 3402                    }
 3403                }
 3404            }
 3405        }
 3406
 3407        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3408        for (worktree_id, builder) in worktree_globs {
 3409            if let Ok(globset) = builder.build() {
 3410                watch_builder.watch_worktree(worktree_id, globset);
 3411            }
 3412        }
 3413        for (abs_path, builder) in abs_globs {
 3414            if let Ok(globset) = builder.build() {
 3415                watch_builder.watch_abs_path(abs_path, globset);
 3416            }
 3417        }
 3418        watch_builder
 3419    }
 3420
 3421    fn worktree_and_path_for_file_watcher(
 3422        worktrees: &[Entity<Worktree>],
 3423        watcher: &FileSystemWatcher,
 3424        cx: &App,
 3425    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3426        worktrees.iter().find_map(|worktree| {
 3427            let tree = worktree.read(cx);
 3428            let worktree_root_path = tree.abs_path();
 3429            let path_style = tree.path_style();
 3430            match &watcher.glob_pattern {
 3431                lsp::GlobPattern::String(s) => {
 3432                    let watcher_path = SanitizedPath::new(s);
 3433                    let relative = watcher_path
 3434                        .as_path()
 3435                        .strip_prefix(&worktree_root_path)
 3436                        .ok()?;
 3437                    let literal_prefix = glob_literal_prefix(relative);
 3438                    Some((
 3439                        worktree.clone(),
 3440                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3441                        relative.to_string_lossy().into_owned(),
 3442                    ))
 3443                }
 3444                lsp::GlobPattern::Relative(rp) => {
 3445                    let base_uri = match &rp.base_uri {
 3446                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3447                        lsp::OneOf::Right(base_uri) => base_uri,
 3448                    }
 3449                    .to_file_path()
 3450                    .ok()?;
 3451                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3452                    let mut literal_prefix = relative.to_owned();
 3453                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3454                    Some((
 3455                        worktree.clone(),
 3456                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3457                        rp.pattern.clone(),
 3458                    ))
 3459                }
 3460            }
 3461        })
 3462    }
 3463
 3464    fn rebuild_watched_paths(
 3465        &mut self,
 3466        language_server_id: LanguageServerId,
 3467        cx: &mut Context<LspStore>,
 3468    ) {
 3469        let Some(registrations) = self
 3470            .language_server_dynamic_registrations
 3471            .get(&language_server_id)
 3472        else {
 3473            return;
 3474        };
 3475
 3476        let watch_builder = self.rebuild_watched_paths_inner(
 3477            language_server_id,
 3478            registrations.did_change_watched_files.values().flatten(),
 3479            cx,
 3480        );
 3481        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3482        self.language_server_watched_paths
 3483            .insert(language_server_id, watcher);
 3484
 3485        cx.notify();
 3486    }
 3487
 3488    fn on_lsp_did_change_watched_files(
 3489        &mut self,
 3490        language_server_id: LanguageServerId,
 3491        registration_id: &str,
 3492        params: DidChangeWatchedFilesRegistrationOptions,
 3493        cx: &mut Context<LspStore>,
 3494    ) {
 3495        let registrations = self
 3496            .language_server_dynamic_registrations
 3497            .entry(language_server_id)
 3498            .or_default();
 3499
 3500        registrations
 3501            .did_change_watched_files
 3502            .insert(registration_id.to_string(), params.watchers);
 3503
 3504        self.rebuild_watched_paths(language_server_id, cx);
 3505    }
 3506
 3507    fn on_lsp_unregister_did_change_watched_files(
 3508        &mut self,
 3509        language_server_id: LanguageServerId,
 3510        registration_id: &str,
 3511        cx: &mut Context<LspStore>,
 3512    ) {
 3513        let registrations = self
 3514            .language_server_dynamic_registrations
 3515            .entry(language_server_id)
 3516            .or_default();
 3517
 3518        if registrations
 3519            .did_change_watched_files
 3520            .remove(registration_id)
 3521            .is_some()
 3522        {
 3523            log::info!(
 3524                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3525                language_server_id,
 3526                registration_id
 3527            );
 3528        } else {
 3529            log::warn!(
 3530                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3531                language_server_id,
 3532                registration_id
 3533            );
 3534        }
 3535
 3536        self.rebuild_watched_paths(language_server_id, cx);
 3537    }
 3538
 3539    async fn initialization_options_for_adapter(
 3540        adapter: Arc<dyn LspAdapter>,
 3541        delegate: &Arc<dyn LspAdapterDelegate>,
 3542    ) -> Result<Option<serde_json::Value>> {
 3543        let Some(mut initialization_config) =
 3544            adapter.clone().initialization_options(delegate).await?
 3545        else {
 3546            return Ok(None);
 3547        };
 3548
 3549        for other_adapter in delegate.registered_lsp_adapters() {
 3550            if other_adapter.name() == adapter.name() {
 3551                continue;
 3552            }
 3553            if let Ok(Some(target_config)) = other_adapter
 3554                .clone()
 3555                .additional_initialization_options(adapter.name(), delegate)
 3556                .await
 3557            {
 3558                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3559            }
 3560        }
 3561
 3562        Ok(Some(initialization_config))
 3563    }
 3564
 3565    async fn workspace_configuration_for_adapter(
 3566        adapter: Arc<dyn LspAdapter>,
 3567        delegate: &Arc<dyn LspAdapterDelegate>,
 3568        toolchain: Option<Toolchain>,
 3569        requested_uri: Option<Uri>,
 3570        cx: &mut AsyncApp,
 3571    ) -> Result<serde_json::Value> {
 3572        let mut workspace_config = adapter
 3573            .clone()
 3574            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3575            .await?;
 3576
 3577        for other_adapter in delegate.registered_lsp_adapters() {
 3578            if other_adapter.name() == adapter.name() {
 3579                continue;
 3580            }
 3581            if let Ok(Some(target_config)) = other_adapter
 3582                .clone()
 3583                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3584                .await
 3585            {
 3586                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3587            }
 3588        }
 3589
 3590        Ok(workspace_config)
 3591    }
 3592
 3593    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3594        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3595            Some(server.clone())
 3596        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3597            Some(Arc::clone(server))
 3598        } else {
 3599            None
 3600        }
 3601    }
 3602}
 3603
 3604fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3605    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3606        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3607            language_server_id: server.server_id(),
 3608            name: Some(server.name()),
 3609            message: proto::update_language_server::Variant::MetadataUpdated(
 3610                proto::ServerMetadataUpdated {
 3611                    capabilities: Some(capabilities),
 3612                    binary: Some(proto::LanguageServerBinaryInfo {
 3613                        path: server.binary().path.to_string_lossy().into_owned(),
 3614                        arguments: server
 3615                            .binary()
 3616                            .arguments
 3617                            .iter()
 3618                            .map(|arg| arg.to_string_lossy().into_owned())
 3619                            .collect(),
 3620                    }),
 3621                    configuration: serde_json::to_string(server.configuration()).ok(),
 3622                    workspace_folders: server
 3623                        .workspace_folders()
 3624                        .iter()
 3625                        .map(|uri| uri.to_string())
 3626                        .collect(),
 3627                },
 3628            ),
 3629        });
 3630    }
 3631}
 3632
 3633#[derive(Debug)]
 3634pub struct FormattableBuffer {
 3635    handle: Entity<Buffer>,
 3636    abs_path: Option<PathBuf>,
 3637    env: Option<HashMap<String, String>>,
 3638    ranges: Option<Vec<Range<Anchor>>>,
 3639}
 3640
 3641pub struct RemoteLspStore {
 3642    upstream_client: Option<AnyProtoClient>,
 3643    upstream_project_id: u64,
 3644}
 3645
 3646pub(crate) enum LspStoreMode {
 3647    Local(LocalLspStore),   // ssh host and collab host
 3648    Remote(RemoteLspStore), // collab guest
 3649}
 3650
 3651impl LspStoreMode {
 3652    fn is_local(&self) -> bool {
 3653        matches!(self, LspStoreMode::Local(_))
 3654    }
 3655}
 3656
 3657pub struct LspStore {
 3658    mode: LspStoreMode,
 3659    last_formatting_failure: Option<String>,
 3660    downstream_client: Option<(AnyProtoClient, u64)>,
 3661    nonce: u128,
 3662    buffer_store: Entity<BufferStore>,
 3663    worktree_store: Entity<WorktreeStore>,
 3664    pub languages: Arc<LanguageRegistry>,
 3665    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3666    active_entry: Option<ProjectEntryId>,
 3667    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3668    _maintain_buffer_languages: Task<()>,
 3669    diagnostic_summaries:
 3670        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3671    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3672    lsp_data: HashMap<BufferId, BufferLspData>,
 3673    next_hint_id: Arc<AtomicUsize>,
 3674}
 3675
 3676#[derive(Debug)]
 3677pub struct BufferLspData {
 3678    buffer_version: Global,
 3679    document_colors: Option<DocumentColorData>,
 3680    code_lens: Option<CodeLensData>,
 3681    inlay_hints: BufferInlayHints,
 3682    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3683    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3684}
 3685
 3686#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3687struct LspKey {
 3688    request_type: TypeId,
 3689    server_queried: Option<LanguageServerId>,
 3690}
 3691
 3692impl BufferLspData {
 3693    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3694        Self {
 3695            buffer_version: buffer.read(cx).version(),
 3696            document_colors: None,
 3697            code_lens: None,
 3698            inlay_hints: BufferInlayHints::new(buffer, cx),
 3699            lsp_requests: HashMap::default(),
 3700            chunk_lsp_requests: HashMap::default(),
 3701        }
 3702    }
 3703
 3704    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3705        if let Some(document_colors) = &mut self.document_colors {
 3706            document_colors.colors.remove(&for_server);
 3707            document_colors.cache_version += 1;
 3708        }
 3709
 3710        if let Some(code_lens) = &mut self.code_lens {
 3711            code_lens.lens.remove(&for_server);
 3712        }
 3713
 3714        self.inlay_hints.remove_server_data(for_server);
 3715    }
 3716
 3717    #[cfg(any(test, feature = "test-support"))]
 3718    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3719        &self.inlay_hints
 3720    }
 3721}
 3722
 3723#[derive(Debug, Default, Clone)]
 3724pub struct DocumentColors {
 3725    pub colors: HashSet<DocumentColor>,
 3726    pub cache_version: Option<usize>,
 3727}
 3728
 3729type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3730type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3731
 3732#[derive(Debug, Default)]
 3733struct DocumentColorData {
 3734    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3735    cache_version: usize,
 3736    colors_update: Option<(Global, DocumentColorTask)>,
 3737}
 3738
 3739#[derive(Debug, Default)]
 3740struct CodeLensData {
 3741    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3742    update: Option<(Global, CodeLensTask)>,
 3743}
 3744
 3745#[derive(Debug)]
 3746pub enum LspStoreEvent {
 3747    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3748    LanguageServerRemoved(LanguageServerId),
 3749    LanguageServerUpdate {
 3750        language_server_id: LanguageServerId,
 3751        name: Option<LanguageServerName>,
 3752        message: proto::update_language_server::Variant,
 3753    },
 3754    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3755    LanguageServerPrompt(LanguageServerPromptRequest),
 3756    LanguageDetected {
 3757        buffer: Entity<Buffer>,
 3758        new_language: Option<Arc<Language>>,
 3759    },
 3760    Notification(String),
 3761    RefreshInlayHints {
 3762        server_id: LanguageServerId,
 3763        request_id: Option<usize>,
 3764    },
 3765    RefreshCodeLens,
 3766    DiagnosticsUpdated {
 3767        server_id: LanguageServerId,
 3768        paths: Vec<ProjectPath>,
 3769    },
 3770    DiskBasedDiagnosticsStarted {
 3771        language_server_id: LanguageServerId,
 3772    },
 3773    DiskBasedDiagnosticsFinished {
 3774        language_server_id: LanguageServerId,
 3775    },
 3776    SnippetEdit {
 3777        buffer_id: BufferId,
 3778        edits: Vec<(lsp::Range, Snippet)>,
 3779        most_recent_edit: clock::Lamport,
 3780    },
 3781}
 3782
 3783#[derive(Clone, Debug, Serialize)]
 3784pub struct LanguageServerStatus {
 3785    pub name: LanguageServerName,
 3786    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3787    pub has_pending_diagnostic_updates: bool,
 3788    pub progress_tokens: HashSet<ProgressToken>,
 3789    pub worktree: Option<WorktreeId>,
 3790    pub binary: Option<LanguageServerBinary>,
 3791    pub configuration: Option<Value>,
 3792    pub workspace_folders: BTreeSet<Uri>,
 3793}
 3794
 3795#[derive(Clone, Debug)]
 3796struct CoreSymbol {
 3797    pub language_server_name: LanguageServerName,
 3798    pub source_worktree_id: WorktreeId,
 3799    pub source_language_server_id: LanguageServerId,
 3800    pub path: SymbolLocation,
 3801    pub name: String,
 3802    pub kind: lsp::SymbolKind,
 3803    pub range: Range<Unclipped<PointUtf16>>,
 3804}
 3805
 3806#[derive(Clone, Debug, PartialEq, Eq)]
 3807pub enum SymbolLocation {
 3808    InProject(ProjectPath),
 3809    OutsideProject {
 3810        abs_path: Arc<Path>,
 3811        signature: [u8; 32],
 3812    },
 3813}
 3814
 3815impl SymbolLocation {
 3816    fn file_name(&self) -> Option<&str> {
 3817        match self {
 3818            Self::InProject(path) => path.path.file_name(),
 3819            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3820        }
 3821    }
 3822}
 3823
 3824impl LspStore {
 3825    pub fn init(client: &AnyProtoClient) {
 3826        client.add_entity_request_handler(Self::handle_lsp_query);
 3827        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3828        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3829        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3830        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3831        client.add_entity_message_handler(Self::handle_start_language_server);
 3832        client.add_entity_message_handler(Self::handle_update_language_server);
 3833        client.add_entity_message_handler(Self::handle_language_server_log);
 3834        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3835        client.add_entity_request_handler(Self::handle_format_buffers);
 3836        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3837        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3838        client.add_entity_request_handler(Self::handle_apply_code_action);
 3839        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3840        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3841        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3842        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3843        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3844        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3845        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3846        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3847        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3848        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3849        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3850        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3851        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3852        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3853        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3854        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3855        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3856
 3857        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3858        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3859        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3860        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3861        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3862        client.add_entity_request_handler(
 3863            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3864        );
 3865        client.add_entity_request_handler(
 3866            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3867        );
 3868        client.add_entity_request_handler(
 3869            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3870        );
 3871    }
 3872
 3873    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3874        match &self.mode {
 3875            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3876            _ => None,
 3877        }
 3878    }
 3879
 3880    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3881        match &self.mode {
 3882            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3883            _ => None,
 3884        }
 3885    }
 3886
 3887    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3888        match &mut self.mode {
 3889            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3890            _ => None,
 3891        }
 3892    }
 3893
 3894    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3895        match &self.mode {
 3896            LspStoreMode::Remote(RemoteLspStore {
 3897                upstream_client: Some(upstream_client),
 3898                upstream_project_id,
 3899                ..
 3900            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3901
 3902            LspStoreMode::Remote(RemoteLspStore {
 3903                upstream_client: None,
 3904                ..
 3905            }) => None,
 3906            LspStoreMode::Local(_) => None,
 3907        }
 3908    }
 3909
 3910    pub fn new_local(
 3911        buffer_store: Entity<BufferStore>,
 3912        worktree_store: Entity<WorktreeStore>,
 3913        prettier_store: Entity<PrettierStore>,
 3914        toolchain_store: Entity<LocalToolchainStore>,
 3915        environment: Entity<ProjectEnvironment>,
 3916        manifest_tree: Entity<ManifestTree>,
 3917        languages: Arc<LanguageRegistry>,
 3918        http_client: Arc<dyn HttpClient>,
 3919        fs: Arc<dyn Fs>,
 3920        cx: &mut Context<Self>,
 3921    ) -> Self {
 3922        let yarn = YarnPathStore::new(fs.clone(), cx);
 3923        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3924            .detach();
 3925        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3926            .detach();
 3927        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3928            .detach();
 3929        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3930            .detach();
 3931        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3932            .detach();
 3933        subscribe_to_binary_statuses(&languages, cx).detach();
 3934
 3935        let _maintain_workspace_config = {
 3936            let (sender, receiver) = watch::channel();
 3937            (Self::maintain_workspace_config(receiver, cx), sender)
 3938        };
 3939
 3940        Self {
 3941            mode: LspStoreMode::Local(LocalLspStore {
 3942                weak: cx.weak_entity(),
 3943                worktree_store: worktree_store.clone(),
 3944
 3945                supplementary_language_servers: Default::default(),
 3946                languages: languages.clone(),
 3947                language_server_ids: Default::default(),
 3948                language_servers: Default::default(),
 3949                last_workspace_edits_by_language_server: Default::default(),
 3950                language_server_watched_paths: Default::default(),
 3951                language_server_paths_watched_for_rename: Default::default(),
 3952                language_server_dynamic_registrations: Default::default(),
 3953                buffers_being_formatted: Default::default(),
 3954                buffer_snapshots: Default::default(),
 3955                prettier_store,
 3956                environment,
 3957                http_client,
 3958                fs,
 3959                yarn,
 3960                next_diagnostic_group_id: Default::default(),
 3961                diagnostics: Default::default(),
 3962                _subscription: cx.on_app_quit(|this, cx| {
 3963                    this.as_local_mut()
 3964                        .unwrap()
 3965                        .shutdown_language_servers_on_quit(cx)
 3966                }),
 3967                lsp_tree: LanguageServerTree::new(
 3968                    manifest_tree,
 3969                    languages.clone(),
 3970                    toolchain_store.clone(),
 3971                ),
 3972                toolchain_store,
 3973                registered_buffers: HashMap::default(),
 3974                buffers_opened_in_servers: HashMap::default(),
 3975                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3976                workspace_pull_diagnostics_result_ids: HashMap::default(),
 3977                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3978                    .manifest_file_names(),
 3979            }),
 3980            last_formatting_failure: None,
 3981            downstream_client: None,
 3982            buffer_store,
 3983            worktree_store,
 3984            languages: languages.clone(),
 3985            language_server_statuses: Default::default(),
 3986            nonce: StdRng::from_os_rng().random(),
 3987            diagnostic_summaries: HashMap::default(),
 3988            lsp_server_capabilities: HashMap::default(),
 3989            lsp_data: HashMap::default(),
 3990            next_hint_id: Arc::default(),
 3991            active_entry: None,
 3992            _maintain_workspace_config,
 3993            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3994        }
 3995    }
 3996
 3997    fn send_lsp_proto_request<R: LspCommand>(
 3998        &self,
 3999        buffer: Entity<Buffer>,
 4000        client: AnyProtoClient,
 4001        upstream_project_id: u64,
 4002        request: R,
 4003        cx: &mut Context<LspStore>,
 4004    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4005        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4006            return Task::ready(Ok(R::Response::default()));
 4007        }
 4008        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4009        cx.spawn(async move |this, cx| {
 4010            let response = client.request(message).await?;
 4011            let this = this.upgrade().context("project dropped")?;
 4012            request
 4013                .response_from_proto(response, this, buffer, cx.clone())
 4014                .await
 4015        })
 4016    }
 4017
 4018    pub(super) fn new_remote(
 4019        buffer_store: Entity<BufferStore>,
 4020        worktree_store: Entity<WorktreeStore>,
 4021        languages: Arc<LanguageRegistry>,
 4022        upstream_client: AnyProtoClient,
 4023        project_id: u64,
 4024        cx: &mut Context<Self>,
 4025    ) -> Self {
 4026        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4027            .detach();
 4028        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4029            .detach();
 4030        subscribe_to_binary_statuses(&languages, cx).detach();
 4031        let _maintain_workspace_config = {
 4032            let (sender, receiver) = watch::channel();
 4033            (Self::maintain_workspace_config(receiver, cx), sender)
 4034        };
 4035        Self {
 4036            mode: LspStoreMode::Remote(RemoteLspStore {
 4037                upstream_client: Some(upstream_client),
 4038                upstream_project_id: project_id,
 4039            }),
 4040            downstream_client: None,
 4041            last_formatting_failure: None,
 4042            buffer_store,
 4043            worktree_store,
 4044            languages: languages.clone(),
 4045            language_server_statuses: Default::default(),
 4046            nonce: StdRng::from_os_rng().random(),
 4047            diagnostic_summaries: HashMap::default(),
 4048            lsp_server_capabilities: HashMap::default(),
 4049            next_hint_id: Arc::default(),
 4050            lsp_data: HashMap::default(),
 4051            active_entry: None,
 4052
 4053            _maintain_workspace_config,
 4054            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4055        }
 4056    }
 4057
 4058    fn on_buffer_store_event(
 4059        &mut self,
 4060        _: Entity<BufferStore>,
 4061        event: &BufferStoreEvent,
 4062        cx: &mut Context<Self>,
 4063    ) {
 4064        match event {
 4065            BufferStoreEvent::BufferAdded(buffer) => {
 4066                self.on_buffer_added(buffer, cx).log_err();
 4067            }
 4068            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4069                let buffer_id = buffer.read(cx).remote_id();
 4070                if let Some(local) = self.as_local_mut()
 4071                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4072                {
 4073                    local.reset_buffer(buffer, old_file, cx);
 4074
 4075                    if local.registered_buffers.contains_key(&buffer_id) {
 4076                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4077                    }
 4078                }
 4079
 4080                self.detect_language_for_buffer(buffer, cx);
 4081                if let Some(local) = self.as_local_mut() {
 4082                    local.initialize_buffer(buffer, cx);
 4083                    if local.registered_buffers.contains_key(&buffer_id) {
 4084                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4085                    }
 4086                }
 4087            }
 4088            _ => {}
 4089        }
 4090    }
 4091
 4092    fn on_worktree_store_event(
 4093        &mut self,
 4094        _: Entity<WorktreeStore>,
 4095        event: &WorktreeStoreEvent,
 4096        cx: &mut Context<Self>,
 4097    ) {
 4098        match event {
 4099            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4100                if !worktree.read(cx).is_local() {
 4101                    return;
 4102                }
 4103                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4104                    worktree::Event::UpdatedEntries(changes) => {
 4105                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4106                    }
 4107                    worktree::Event::UpdatedGitRepositories(_)
 4108                    | worktree::Event::DeletedEntry(_) => {}
 4109                })
 4110                .detach()
 4111            }
 4112            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4113            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4114                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4115            }
 4116            WorktreeStoreEvent::WorktreeReleased(..)
 4117            | WorktreeStoreEvent::WorktreeOrderChanged
 4118            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4119            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4120            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4121        }
 4122    }
 4123
 4124    fn on_prettier_store_event(
 4125        &mut self,
 4126        _: Entity<PrettierStore>,
 4127        event: &PrettierStoreEvent,
 4128        cx: &mut Context<Self>,
 4129    ) {
 4130        match event {
 4131            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4132                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4133            }
 4134            PrettierStoreEvent::LanguageServerAdded {
 4135                new_server_id,
 4136                name,
 4137                prettier_server,
 4138            } => {
 4139                self.register_supplementary_language_server(
 4140                    *new_server_id,
 4141                    name.clone(),
 4142                    prettier_server.clone(),
 4143                    cx,
 4144                );
 4145            }
 4146        }
 4147    }
 4148
 4149    fn on_toolchain_store_event(
 4150        &mut self,
 4151        _: Entity<LocalToolchainStore>,
 4152        event: &ToolchainStoreEvent,
 4153        _: &mut Context<Self>,
 4154    ) {
 4155        if let ToolchainStoreEvent::ToolchainActivated = event {
 4156            self.request_workspace_config_refresh()
 4157        }
 4158    }
 4159
 4160    fn request_workspace_config_refresh(&mut self) {
 4161        *self._maintain_workspace_config.1.borrow_mut() = ();
 4162    }
 4163
 4164    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4165        self.as_local().map(|local| local.prettier_store.clone())
 4166    }
 4167
 4168    fn on_buffer_event(
 4169        &mut self,
 4170        buffer: Entity<Buffer>,
 4171        event: &language::BufferEvent,
 4172        cx: &mut Context<Self>,
 4173    ) {
 4174        match event {
 4175            language::BufferEvent::Edited => {
 4176                self.on_buffer_edited(buffer, cx);
 4177            }
 4178
 4179            language::BufferEvent::Saved => {
 4180                self.on_buffer_saved(buffer, cx);
 4181            }
 4182
 4183            _ => {}
 4184        }
 4185    }
 4186
 4187    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4188        buffer
 4189            .read(cx)
 4190            .set_language_registry(self.languages.clone());
 4191
 4192        cx.subscribe(buffer, |this, buffer, event, cx| {
 4193            this.on_buffer_event(buffer, event, cx);
 4194        })
 4195        .detach();
 4196
 4197        self.detect_language_for_buffer(buffer, cx);
 4198        if let Some(local) = self.as_local_mut() {
 4199            local.initialize_buffer(buffer, cx);
 4200        }
 4201
 4202        Ok(())
 4203    }
 4204
 4205    pub(crate) fn register_buffer_with_language_servers(
 4206        &mut self,
 4207        buffer: &Entity<Buffer>,
 4208        only_register_servers: HashSet<LanguageServerSelector>,
 4209        ignore_refcounts: bool,
 4210        cx: &mut Context<Self>,
 4211    ) -> OpenLspBufferHandle {
 4212        let buffer_id = buffer.read(cx).remote_id();
 4213        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4214        if let Some(local) = self.as_local_mut() {
 4215            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4216            if !ignore_refcounts {
 4217                *refcount += 1;
 4218            }
 4219
 4220            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4221            // 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
 4222            // 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
 4223            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4224            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4225                return handle;
 4226            };
 4227            if !file.is_local() {
 4228                return handle;
 4229            }
 4230
 4231            if ignore_refcounts || *refcount == 1 {
 4232                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4233            }
 4234            if !ignore_refcounts {
 4235                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4236                    let refcount = {
 4237                        let local = lsp_store.as_local_mut().unwrap();
 4238                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4239                            debug_panic!("bad refcounting");
 4240                            return;
 4241                        };
 4242
 4243                        *refcount -= 1;
 4244                        *refcount
 4245                    };
 4246                    if refcount == 0 {
 4247                        lsp_store.lsp_data.remove(&buffer_id);
 4248                        let local = lsp_store.as_local_mut().unwrap();
 4249                        local.registered_buffers.remove(&buffer_id);
 4250
 4251                        local.buffers_opened_in_servers.remove(&buffer_id);
 4252                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4253                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4254
 4255                            let buffer_abs_path = file.abs_path(cx);
 4256                            for (_, buffer_pull_diagnostics_result_ids) in
 4257                                &mut local.buffer_pull_diagnostics_result_ids
 4258                            {
 4259                                buffer_pull_diagnostics_result_ids.retain(
 4260                                    |_, buffer_result_ids| {
 4261                                        buffer_result_ids.remove(&buffer_abs_path);
 4262                                        !buffer_result_ids.is_empty()
 4263                                    },
 4264                                );
 4265                            }
 4266
 4267                            let diagnostic_updates = local
 4268                                .language_servers
 4269                                .keys()
 4270                                .cloned()
 4271                                .map(|server_id| DocumentDiagnosticsUpdate {
 4272                                    diagnostics: DocumentDiagnostics {
 4273                                        document_abs_path: buffer_abs_path.clone(),
 4274                                        version: None,
 4275                                        diagnostics: Vec::new(),
 4276                                    },
 4277                                    result_id: None,
 4278                                    registration_id: None,
 4279                                    server_id: server_id,
 4280                                    disk_based_sources: Cow::Borrowed(&[]),
 4281                                })
 4282                                .collect::<Vec<_>>();
 4283
 4284                            lsp_store
 4285                                .merge_diagnostic_entries(
 4286                                    diagnostic_updates,
 4287                                    |_, diagnostic, _| {
 4288                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4289                                    },
 4290                                    cx,
 4291                                )
 4292                                .context("Clearing diagnostics for the closed buffer")
 4293                                .log_err();
 4294                        }
 4295                    }
 4296                })
 4297                .detach();
 4298            }
 4299        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4300            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4301            cx.background_spawn(async move {
 4302                upstream_client
 4303                    .request(proto::RegisterBufferWithLanguageServers {
 4304                        project_id: upstream_project_id,
 4305                        buffer_id,
 4306                        only_servers: only_register_servers
 4307                            .into_iter()
 4308                            .map(|selector| {
 4309                                let selector = match selector {
 4310                                    LanguageServerSelector::Id(language_server_id) => {
 4311                                        proto::language_server_selector::Selector::ServerId(
 4312                                            language_server_id.to_proto(),
 4313                                        )
 4314                                    }
 4315                                    LanguageServerSelector::Name(language_server_name) => {
 4316                                        proto::language_server_selector::Selector::Name(
 4317                                            language_server_name.to_string(),
 4318                                        )
 4319                                    }
 4320                                };
 4321                                proto::LanguageServerSelector {
 4322                                    selector: Some(selector),
 4323                                }
 4324                            })
 4325                            .collect(),
 4326                    })
 4327                    .await
 4328            })
 4329            .detach();
 4330        } else {
 4331            // Our remote connection got closed
 4332        }
 4333        handle
 4334    }
 4335
 4336    fn maintain_buffer_languages(
 4337        languages: Arc<LanguageRegistry>,
 4338        cx: &mut Context<Self>,
 4339    ) -> Task<()> {
 4340        let mut subscription = languages.subscribe();
 4341        let mut prev_reload_count = languages.reload_count();
 4342        cx.spawn(async move |this, cx| {
 4343            while let Some(()) = subscription.next().await {
 4344                if let Some(this) = this.upgrade() {
 4345                    // If the language registry has been reloaded, then remove and
 4346                    // re-assign the languages on all open buffers.
 4347                    let reload_count = languages.reload_count();
 4348                    if reload_count > prev_reload_count {
 4349                        prev_reload_count = reload_count;
 4350                        this.update(cx, |this, cx| {
 4351                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4352                                for buffer in buffer_store.buffers() {
 4353                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4354                                    {
 4355                                        buffer.update(cx, |buffer, cx| {
 4356                                            buffer.set_language_async(None, cx)
 4357                                        });
 4358                                        if let Some(local) = this.as_local_mut() {
 4359                                            local.reset_buffer(&buffer, &f, cx);
 4360
 4361                                            if local
 4362                                                .registered_buffers
 4363                                                .contains_key(&buffer.read(cx).remote_id())
 4364                                                && let Some(file_url) =
 4365                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4366                                            {
 4367                                                local.unregister_buffer_from_language_servers(
 4368                                                    &buffer, &file_url, cx,
 4369                                                );
 4370                                            }
 4371                                        }
 4372                                    }
 4373                                }
 4374                            });
 4375                        })
 4376                        .ok();
 4377                    }
 4378
 4379                    this.update(cx, |this, cx| {
 4380                        let mut plain_text_buffers = Vec::new();
 4381                        let mut buffers_with_unknown_injections = Vec::new();
 4382                        for handle in this.buffer_store.read(cx).buffers() {
 4383                            let buffer = handle.read(cx);
 4384                            if buffer.language().is_none()
 4385                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4386                            {
 4387                                plain_text_buffers.push(handle);
 4388                            } else if buffer.contains_unknown_injections() {
 4389                                buffers_with_unknown_injections.push(handle);
 4390                            }
 4391                        }
 4392
 4393                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4394                        // and reused later in the invisible worktrees.
 4395                        plain_text_buffers.sort_by_key(|buffer| {
 4396                            Reverse(
 4397                                File::from_dyn(buffer.read(cx).file())
 4398                                    .map(|file| file.worktree.read(cx).is_visible()),
 4399                            )
 4400                        });
 4401
 4402                        for buffer in plain_text_buffers {
 4403                            this.detect_language_for_buffer(&buffer, cx);
 4404                            if let Some(local) = this.as_local_mut() {
 4405                                local.initialize_buffer(&buffer, cx);
 4406                                if local
 4407                                    .registered_buffers
 4408                                    .contains_key(&buffer.read(cx).remote_id())
 4409                                {
 4410                                    local.register_buffer_with_language_servers(
 4411                                        &buffer,
 4412                                        HashSet::default(),
 4413                                        cx,
 4414                                    );
 4415                                }
 4416                            }
 4417                        }
 4418
 4419                        for buffer in buffers_with_unknown_injections {
 4420                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4421                        }
 4422                    })
 4423                    .ok();
 4424                }
 4425            }
 4426        })
 4427    }
 4428
 4429    fn detect_language_for_buffer(
 4430        &mut self,
 4431        buffer_handle: &Entity<Buffer>,
 4432        cx: &mut Context<Self>,
 4433    ) -> Option<language::AvailableLanguage> {
 4434        // If the buffer has a language, set it and start the language server if we haven't already.
 4435        let buffer = buffer_handle.read(cx);
 4436        let file = buffer.file()?;
 4437
 4438        let content = buffer.as_rope();
 4439        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4440        if let Some(available_language) = &available_language {
 4441            if let Some(Ok(Ok(new_language))) = self
 4442                .languages
 4443                .load_language(available_language)
 4444                .now_or_never()
 4445            {
 4446                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4447            }
 4448        } else {
 4449            cx.emit(LspStoreEvent::LanguageDetected {
 4450                buffer: buffer_handle.clone(),
 4451                new_language: None,
 4452            });
 4453        }
 4454
 4455        available_language
 4456    }
 4457
 4458    pub(crate) fn set_language_for_buffer(
 4459        &mut self,
 4460        buffer_entity: &Entity<Buffer>,
 4461        new_language: Arc<Language>,
 4462        cx: &mut Context<Self>,
 4463    ) {
 4464        let buffer = buffer_entity.read(cx);
 4465        let buffer_file = buffer.file().cloned();
 4466        let buffer_id = buffer.remote_id();
 4467        if let Some(local_store) = self.as_local_mut()
 4468            && local_store.registered_buffers.contains_key(&buffer_id)
 4469            && let Some(abs_path) =
 4470                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4471            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4472        {
 4473            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4474        }
 4475        buffer_entity.update(cx, |buffer, cx| {
 4476            if buffer
 4477                .language()
 4478                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4479            {
 4480                buffer.set_language_async(Some(new_language.clone()), cx);
 4481            }
 4482        });
 4483
 4484        let settings =
 4485            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4486        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4487
 4488        let worktree_id = if let Some(file) = buffer_file {
 4489            let worktree = file.worktree.clone();
 4490
 4491            if let Some(local) = self.as_local_mut()
 4492                && local.registered_buffers.contains_key(&buffer_id)
 4493            {
 4494                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4495            }
 4496            Some(worktree.read(cx).id())
 4497        } else {
 4498            None
 4499        };
 4500
 4501        if settings.prettier.allowed
 4502            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4503        {
 4504            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4505            if let Some(prettier_store) = prettier_store {
 4506                prettier_store.update(cx, |prettier_store, cx| {
 4507                    prettier_store.install_default_prettier(
 4508                        worktree_id,
 4509                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4510                        cx,
 4511                    )
 4512                })
 4513            }
 4514        }
 4515
 4516        cx.emit(LspStoreEvent::LanguageDetected {
 4517            buffer: buffer_entity.clone(),
 4518            new_language: Some(new_language),
 4519        })
 4520    }
 4521
 4522    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4523        self.buffer_store.clone()
 4524    }
 4525
 4526    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4527        self.active_entry = active_entry;
 4528    }
 4529
 4530    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4531        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4532            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4533        {
 4534            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4535                summaries
 4536                    .iter()
 4537                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4538            });
 4539            if let Some(summary) = summaries.next() {
 4540                client
 4541                    .send(proto::UpdateDiagnosticSummary {
 4542                        project_id: downstream_project_id,
 4543                        worktree_id: worktree.id().to_proto(),
 4544                        summary: Some(summary),
 4545                        more_summaries: summaries.collect(),
 4546                    })
 4547                    .log_err();
 4548            }
 4549        }
 4550    }
 4551
 4552    fn is_capable_for_proto_request<R>(
 4553        &self,
 4554        buffer: &Entity<Buffer>,
 4555        request: &R,
 4556        cx: &App,
 4557    ) -> bool
 4558    where
 4559        R: LspCommand,
 4560    {
 4561        self.check_if_capable_for_proto_request(
 4562            buffer,
 4563            |capabilities| {
 4564                request.check_capabilities(AdapterServerCapabilities {
 4565                    server_capabilities: capabilities.clone(),
 4566                    code_action_kinds: None,
 4567                })
 4568            },
 4569            cx,
 4570        )
 4571    }
 4572
 4573    fn check_if_capable_for_proto_request<F>(
 4574        &self,
 4575        buffer: &Entity<Buffer>,
 4576        check: F,
 4577        cx: &App,
 4578    ) -> bool
 4579    where
 4580        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4581    {
 4582        let Some(language) = buffer.read(cx).language().cloned() else {
 4583            return false;
 4584        };
 4585        let relevant_language_servers = self
 4586            .languages
 4587            .lsp_adapters(&language.name())
 4588            .into_iter()
 4589            .map(|lsp_adapter| lsp_adapter.name())
 4590            .collect::<HashSet<_>>();
 4591        self.language_server_statuses
 4592            .iter()
 4593            .filter_map(|(server_id, server_status)| {
 4594                relevant_language_servers
 4595                    .contains(&server_status.name)
 4596                    .then_some(server_id)
 4597            })
 4598            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4599            .any(check)
 4600    }
 4601
 4602    fn all_capable_for_proto_request<F>(
 4603        &self,
 4604        buffer: &Entity<Buffer>,
 4605        mut check: F,
 4606        cx: &App,
 4607    ) -> Vec<lsp::LanguageServerId>
 4608    where
 4609        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4610    {
 4611        let Some(language) = buffer.read(cx).language().cloned() else {
 4612            return Vec::default();
 4613        };
 4614        let relevant_language_servers = self
 4615            .languages
 4616            .lsp_adapters(&language.name())
 4617            .into_iter()
 4618            .map(|lsp_adapter| lsp_adapter.name())
 4619            .collect::<HashSet<_>>();
 4620        self.language_server_statuses
 4621            .iter()
 4622            .filter_map(|(server_id, server_status)| {
 4623                relevant_language_servers
 4624                    .contains(&server_status.name)
 4625                    .then_some((server_id, &server_status.name))
 4626            })
 4627            .filter_map(|(server_id, server_name)| {
 4628                self.lsp_server_capabilities
 4629                    .get(server_id)
 4630                    .map(|c| (server_id, server_name, c))
 4631            })
 4632            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4633            .map(|(server_id, _, _)| *server_id)
 4634            .collect()
 4635    }
 4636
 4637    pub fn request_lsp<R>(
 4638        &mut self,
 4639        buffer: Entity<Buffer>,
 4640        server: LanguageServerToQuery,
 4641        request: R,
 4642        cx: &mut Context<Self>,
 4643    ) -> Task<Result<R::Response>>
 4644    where
 4645        R: LspCommand,
 4646        <R::LspRequest as lsp::request::Request>::Result: Send,
 4647        <R::LspRequest as lsp::request::Request>::Params: Send,
 4648    {
 4649        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4650            return self.send_lsp_proto_request(
 4651                buffer,
 4652                upstream_client,
 4653                upstream_project_id,
 4654                request,
 4655                cx,
 4656            );
 4657        }
 4658
 4659        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4660            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4661                local
 4662                    .language_servers_for_buffer(buffer, cx)
 4663                    .find(|(_, server)| {
 4664                        request.check_capabilities(server.adapter_server_capabilities())
 4665                    })
 4666                    .map(|(_, server)| server.clone())
 4667            }),
 4668            LanguageServerToQuery::Other(id) => self
 4669                .language_server_for_local_buffer(buffer, id, cx)
 4670                .and_then(|(_, server)| {
 4671                    request
 4672                        .check_capabilities(server.adapter_server_capabilities())
 4673                        .then(|| Arc::clone(server))
 4674                }),
 4675        }) else {
 4676            return Task::ready(Ok(Default::default()));
 4677        };
 4678
 4679        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4680
 4681        let Some(file) = file else {
 4682            return Task::ready(Ok(Default::default()));
 4683        };
 4684
 4685        let lsp_params = match request.to_lsp_params_or_response(
 4686            &file.abs_path(cx),
 4687            buffer.read(cx),
 4688            &language_server,
 4689            cx,
 4690        ) {
 4691            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4692            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4693            Err(err) => {
 4694                let message = format!(
 4695                    "{} via {} failed: {}",
 4696                    request.display_name(),
 4697                    language_server.name(),
 4698                    err
 4699                );
 4700                // rust-analyzer likes to error with this when its still loading up
 4701                if !message.ends_with("content modified") {
 4702                    log::warn!("{message}");
 4703                }
 4704                return Task::ready(Err(anyhow!(message)));
 4705            }
 4706        };
 4707
 4708        let status = request.status();
 4709        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4710            return Task::ready(Ok(Default::default()));
 4711        }
 4712        cx.spawn(async move |this, cx| {
 4713            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4714
 4715            let id = lsp_request.id();
 4716            let _cleanup = if status.is_some() {
 4717                cx.update(|cx| {
 4718                    this.update(cx, |this, cx| {
 4719                        this.on_lsp_work_start(
 4720                            language_server.server_id(),
 4721                            ProgressToken::Number(id),
 4722                            LanguageServerProgress {
 4723                                is_disk_based_diagnostics_progress: false,
 4724                                is_cancellable: false,
 4725                                title: None,
 4726                                message: status.clone(),
 4727                                percentage: None,
 4728                                last_update_at: cx.background_executor().now(),
 4729                            },
 4730                            cx,
 4731                        );
 4732                    })
 4733                })
 4734                .log_err();
 4735
 4736                Some(defer(|| {
 4737                    cx.update(|cx| {
 4738                        this.update(cx, |this, cx| {
 4739                            this.on_lsp_work_end(
 4740                                language_server.server_id(),
 4741                                ProgressToken::Number(id),
 4742                                cx,
 4743                            );
 4744                        })
 4745                    })
 4746                    .log_err();
 4747                }))
 4748            } else {
 4749                None
 4750            };
 4751
 4752            let result = lsp_request.await.into_response();
 4753
 4754            let response = result.map_err(|err| {
 4755                let message = format!(
 4756                    "{} via {} failed: {}",
 4757                    request.display_name(),
 4758                    language_server.name(),
 4759                    err
 4760                );
 4761                // rust-analyzer likes to error with this when its still loading up
 4762                if !message.ends_with("content modified") {
 4763                    log::warn!("{message}");
 4764                }
 4765                anyhow::anyhow!(message)
 4766            })?;
 4767
 4768            request
 4769                .response_from_lsp(
 4770                    response,
 4771                    this.upgrade().context("no app context")?,
 4772                    buffer,
 4773                    language_server.server_id(),
 4774                    cx.clone(),
 4775                )
 4776                .await
 4777        })
 4778    }
 4779
 4780    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4781        let mut language_formatters_to_check = Vec::new();
 4782        for buffer in self.buffer_store.read(cx).buffers() {
 4783            let buffer = buffer.read(cx);
 4784            let buffer_file = File::from_dyn(buffer.file());
 4785            let buffer_language = buffer.language();
 4786            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4787            if buffer_language.is_some() {
 4788                language_formatters_to_check.push((
 4789                    buffer_file.map(|f| f.worktree_id(cx)),
 4790                    settings.into_owned(),
 4791                ));
 4792            }
 4793        }
 4794
 4795        self.request_workspace_config_refresh();
 4796
 4797        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4798            prettier_store.update(cx, |prettier_store, cx| {
 4799                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4800            })
 4801        }
 4802
 4803        cx.notify();
 4804    }
 4805
 4806    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4807        let buffer_store = self.buffer_store.clone();
 4808        let Some(local) = self.as_local_mut() else {
 4809            return;
 4810        };
 4811        let mut adapters = BTreeMap::default();
 4812        let get_adapter = {
 4813            let languages = local.languages.clone();
 4814            let environment = local.environment.clone();
 4815            let weak = local.weak.clone();
 4816            let worktree_store = local.worktree_store.clone();
 4817            let http_client = local.http_client.clone();
 4818            let fs = local.fs.clone();
 4819            move |worktree_id, cx: &mut App| {
 4820                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4821                Some(LocalLspAdapterDelegate::new(
 4822                    languages.clone(),
 4823                    &environment,
 4824                    weak.clone(),
 4825                    &worktree,
 4826                    http_client.clone(),
 4827                    fs.clone(),
 4828                    cx,
 4829                ))
 4830            }
 4831        };
 4832
 4833        let mut messages_to_report = Vec::new();
 4834        let (new_tree, to_stop) = {
 4835            let mut rebase = local.lsp_tree.rebase();
 4836            let buffers = buffer_store
 4837                .read(cx)
 4838                .buffers()
 4839                .filter_map(|buffer| {
 4840                    let raw_buffer = buffer.read(cx);
 4841                    if !local
 4842                        .registered_buffers
 4843                        .contains_key(&raw_buffer.remote_id())
 4844                    {
 4845                        return None;
 4846                    }
 4847                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4848                    let language = raw_buffer.language().cloned()?;
 4849                    Some((file, language, raw_buffer.remote_id()))
 4850                })
 4851                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4852            for (file, language, buffer_id) in buffers {
 4853                let worktree_id = file.worktree_id(cx);
 4854                let Some(worktree) = local
 4855                    .worktree_store
 4856                    .read(cx)
 4857                    .worktree_for_id(worktree_id, cx)
 4858                else {
 4859                    continue;
 4860                };
 4861
 4862                if let Some((_, apply)) = local.reuse_existing_language_server(
 4863                    rebase.server_tree(),
 4864                    &worktree,
 4865                    &language.name(),
 4866                    cx,
 4867                ) {
 4868                    (apply)(rebase.server_tree());
 4869                } else if let Some(lsp_delegate) = adapters
 4870                    .entry(worktree_id)
 4871                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4872                    .clone()
 4873                {
 4874                    let delegate =
 4875                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4876                    let path = file
 4877                        .path()
 4878                        .parent()
 4879                        .map(Arc::from)
 4880                        .unwrap_or_else(|| file.path().clone());
 4881                    let worktree_path = ProjectPath { worktree_id, path };
 4882                    let abs_path = file.abs_path(cx);
 4883                    let nodes = rebase
 4884                        .walk(
 4885                            worktree_path,
 4886                            language.name(),
 4887                            language.manifest(),
 4888                            delegate.clone(),
 4889                            cx,
 4890                        )
 4891                        .collect::<Vec<_>>();
 4892                    for node in nodes {
 4893                        let server_id = node.server_id_or_init(|disposition| {
 4894                            let path = &disposition.path;
 4895                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4896                            let key = LanguageServerSeed {
 4897                                worktree_id,
 4898                                name: disposition.server_name.clone(),
 4899                                settings: disposition.settings.clone(),
 4900                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4901                                    path.worktree_id,
 4902                                    &path.path,
 4903                                    language.name(),
 4904                                ),
 4905                            };
 4906                            local.language_server_ids.remove(&key);
 4907
 4908                            let server_id = local.get_or_insert_language_server(
 4909                                &worktree,
 4910                                lsp_delegate.clone(),
 4911                                disposition,
 4912                                &language.name(),
 4913                                cx,
 4914                            );
 4915                            if let Some(state) = local.language_servers.get(&server_id)
 4916                                && let Ok(uri) = uri
 4917                            {
 4918                                state.add_workspace_folder(uri);
 4919                            };
 4920                            server_id
 4921                        });
 4922
 4923                        if let Some(language_server_id) = server_id {
 4924                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4925                                language_server_id,
 4926                                name: node.name(),
 4927                                message:
 4928                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4929                                        proto::RegisteredForBuffer {
 4930                                            buffer_abs_path: abs_path
 4931                                                .to_string_lossy()
 4932                                                .into_owned(),
 4933                                            buffer_id: buffer_id.to_proto(),
 4934                                        },
 4935                                    ),
 4936                            });
 4937                        }
 4938                    }
 4939                } else {
 4940                    continue;
 4941                }
 4942            }
 4943            rebase.finish()
 4944        };
 4945        for message in messages_to_report {
 4946            cx.emit(message);
 4947        }
 4948        local.lsp_tree = new_tree;
 4949        for (id, _) in to_stop {
 4950            self.stop_local_language_server(id, cx).detach();
 4951        }
 4952    }
 4953
 4954    pub fn apply_code_action(
 4955        &self,
 4956        buffer_handle: Entity<Buffer>,
 4957        mut action: CodeAction,
 4958        push_to_history: bool,
 4959        cx: &mut Context<Self>,
 4960    ) -> Task<Result<ProjectTransaction>> {
 4961        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4962            let request = proto::ApplyCodeAction {
 4963                project_id,
 4964                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4965                action: Some(Self::serialize_code_action(&action)),
 4966            };
 4967            let buffer_store = self.buffer_store();
 4968            cx.spawn(async move |_, cx| {
 4969                let response = upstream_client
 4970                    .request(request)
 4971                    .await?
 4972                    .transaction
 4973                    .context("missing transaction")?;
 4974
 4975                buffer_store
 4976                    .update(cx, |buffer_store, cx| {
 4977                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4978                    })?
 4979                    .await
 4980            })
 4981        } else if self.mode.is_local() {
 4982            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4983                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4984                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4985            }) else {
 4986                return Task::ready(Ok(ProjectTransaction::default()));
 4987            };
 4988            cx.spawn(async move |this,  cx| {
 4989                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4990                    .await
 4991                    .context("resolving a code action")?;
 4992                if let Some(edit) = action.lsp_action.edit()
 4993                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4994                        return LocalLspStore::deserialize_workspace_edit(
 4995                            this.upgrade().context("no app present")?,
 4996                            edit.clone(),
 4997                            push_to_history,
 4998
 4999                            lang_server.clone(),
 5000                            cx,
 5001                        )
 5002                        .await;
 5003                    }
 5004
 5005                if let Some(command) = action.lsp_action.command() {
 5006                    let server_capabilities = lang_server.capabilities();
 5007                    let available_commands = server_capabilities
 5008                        .execute_command_provider
 5009                        .as_ref()
 5010                        .map(|options| options.commands.as_slice())
 5011                        .unwrap_or_default();
 5012                    if available_commands.contains(&command.command) {
 5013                        this.update(cx, |this, _| {
 5014                            this.as_local_mut()
 5015                                .unwrap()
 5016                                .last_workspace_edits_by_language_server
 5017                                .remove(&lang_server.server_id());
 5018                        })?;
 5019
 5020                        let _result = lang_server
 5021                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5022                                command: command.command.clone(),
 5023                                arguments: command.arguments.clone().unwrap_or_default(),
 5024                                ..lsp::ExecuteCommandParams::default()
 5025                            })
 5026                            .await.into_response()
 5027                            .context("execute command")?;
 5028
 5029                        return this.update(cx, |this, _| {
 5030                            this.as_local_mut()
 5031                                .unwrap()
 5032                                .last_workspace_edits_by_language_server
 5033                                .remove(&lang_server.server_id())
 5034                                .unwrap_or_default()
 5035                        });
 5036                    } else {
 5037                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5038                    }
 5039                }
 5040
 5041                Ok(ProjectTransaction::default())
 5042            })
 5043        } else {
 5044            Task::ready(Err(anyhow!("no upstream client and not local")))
 5045        }
 5046    }
 5047
 5048    pub fn apply_code_action_kind(
 5049        &mut self,
 5050        buffers: HashSet<Entity<Buffer>>,
 5051        kind: CodeActionKind,
 5052        push_to_history: bool,
 5053        cx: &mut Context<Self>,
 5054    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5055        if self.as_local().is_some() {
 5056            cx.spawn(async move |lsp_store, cx| {
 5057                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5058                let result = LocalLspStore::execute_code_action_kind_locally(
 5059                    lsp_store.clone(),
 5060                    buffers,
 5061                    kind,
 5062                    push_to_history,
 5063                    cx,
 5064                )
 5065                .await;
 5066                lsp_store.update(cx, |lsp_store, _| {
 5067                    lsp_store.update_last_formatting_failure(&result);
 5068                })?;
 5069                result
 5070            })
 5071        } else if let Some((client, project_id)) = self.upstream_client() {
 5072            let buffer_store = self.buffer_store();
 5073            cx.spawn(async move |lsp_store, cx| {
 5074                let result = client
 5075                    .request(proto::ApplyCodeActionKind {
 5076                        project_id,
 5077                        kind: kind.as_str().to_owned(),
 5078                        buffer_ids: buffers
 5079                            .iter()
 5080                            .map(|buffer| {
 5081                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5082                            })
 5083                            .collect::<Result<_>>()?,
 5084                    })
 5085                    .await
 5086                    .and_then(|result| result.transaction.context("missing transaction"));
 5087                lsp_store.update(cx, |lsp_store, _| {
 5088                    lsp_store.update_last_formatting_failure(&result);
 5089                })?;
 5090
 5091                let transaction_response = result?;
 5092                buffer_store
 5093                    .update(cx, |buffer_store, cx| {
 5094                        buffer_store.deserialize_project_transaction(
 5095                            transaction_response,
 5096                            push_to_history,
 5097                            cx,
 5098                        )
 5099                    })?
 5100                    .await
 5101            })
 5102        } else {
 5103            Task::ready(Ok(ProjectTransaction::default()))
 5104        }
 5105    }
 5106
 5107    pub fn resolved_hint(
 5108        &mut self,
 5109        buffer_id: BufferId,
 5110        id: InlayId,
 5111        cx: &mut Context<Self>,
 5112    ) -> Option<ResolvedHint> {
 5113        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5114
 5115        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5116        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5117        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5118        let (server_id, resolve_data) = match &hint.resolve_state {
 5119            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5120            ResolveState::Resolving => {
 5121                return Some(ResolvedHint::Resolving(
 5122                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5123                ));
 5124            }
 5125            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5126        };
 5127
 5128        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5129        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5130        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5131            id,
 5132            cx.spawn(async move |lsp_store, cx| {
 5133                let resolved_hint = resolve_task.await;
 5134                lsp_store
 5135                    .update(cx, |lsp_store, _| {
 5136                        if let Some(old_inlay_hint) = lsp_store
 5137                            .lsp_data
 5138                            .get_mut(&buffer_id)
 5139                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5140                        {
 5141                            match resolved_hint {
 5142                                Ok(resolved_hint) => {
 5143                                    *old_inlay_hint = resolved_hint;
 5144                                }
 5145                                Err(e) => {
 5146                                    old_inlay_hint.resolve_state =
 5147                                        ResolveState::CanResolve(server_id, resolve_data);
 5148                                    log::error!("Inlay hint resolve failed: {e:#}");
 5149                                }
 5150                            }
 5151                        }
 5152                    })
 5153                    .ok();
 5154            })
 5155            .shared(),
 5156        );
 5157        debug_assert!(
 5158            previous_task.is_none(),
 5159            "Did not change hint's resolve state after spawning its resolve"
 5160        );
 5161        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5162        None
 5163    }
 5164
 5165    fn resolve_inlay_hint(
 5166        &self,
 5167        mut hint: InlayHint,
 5168        buffer: Entity<Buffer>,
 5169        server_id: LanguageServerId,
 5170        cx: &mut Context<Self>,
 5171    ) -> Task<anyhow::Result<InlayHint>> {
 5172        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5173            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5174            {
 5175                hint.resolve_state = ResolveState::Resolved;
 5176                return Task::ready(Ok(hint));
 5177            }
 5178            let request = proto::ResolveInlayHint {
 5179                project_id,
 5180                buffer_id: buffer.read(cx).remote_id().into(),
 5181                language_server_id: server_id.0 as u64,
 5182                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5183            };
 5184            cx.background_spawn(async move {
 5185                let response = upstream_client
 5186                    .request(request)
 5187                    .await
 5188                    .context("inlay hints proto request")?;
 5189                match response.hint {
 5190                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5191                        .context("inlay hints proto resolve response conversion"),
 5192                    None => Ok(hint),
 5193                }
 5194            })
 5195        } else {
 5196            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5197                self.language_server_for_local_buffer(buffer, server_id, cx)
 5198                    .map(|(_, server)| server.clone())
 5199            }) else {
 5200                return Task::ready(Ok(hint));
 5201            };
 5202            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5203                return Task::ready(Ok(hint));
 5204            }
 5205            let buffer_snapshot = buffer.read(cx).snapshot();
 5206            cx.spawn(async move |_, cx| {
 5207                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5208                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5209                );
 5210                let resolved_hint = resolve_task
 5211                    .await
 5212                    .into_response()
 5213                    .context("inlay hint resolve LSP request")?;
 5214                let resolved_hint = InlayHints::lsp_to_project_hint(
 5215                    resolved_hint,
 5216                    &buffer,
 5217                    server_id,
 5218                    ResolveState::Resolved,
 5219                    false,
 5220                    cx,
 5221                )
 5222                .await?;
 5223                Ok(resolved_hint)
 5224            })
 5225        }
 5226    }
 5227
 5228    pub fn resolve_color_presentation(
 5229        &mut self,
 5230        mut color: DocumentColor,
 5231        buffer: Entity<Buffer>,
 5232        server_id: LanguageServerId,
 5233        cx: &mut Context<Self>,
 5234    ) -> Task<Result<DocumentColor>> {
 5235        if color.resolved {
 5236            return Task::ready(Ok(color));
 5237        }
 5238
 5239        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5240            let start = color.lsp_range.start;
 5241            let end = color.lsp_range.end;
 5242            let request = proto::GetColorPresentation {
 5243                project_id,
 5244                server_id: server_id.to_proto(),
 5245                buffer_id: buffer.read(cx).remote_id().into(),
 5246                color: Some(proto::ColorInformation {
 5247                    red: color.color.red,
 5248                    green: color.color.green,
 5249                    blue: color.color.blue,
 5250                    alpha: color.color.alpha,
 5251                    lsp_range_start: Some(proto::PointUtf16 {
 5252                        row: start.line,
 5253                        column: start.character,
 5254                    }),
 5255                    lsp_range_end: Some(proto::PointUtf16 {
 5256                        row: end.line,
 5257                        column: end.character,
 5258                    }),
 5259                }),
 5260            };
 5261            cx.background_spawn(async move {
 5262                let response = upstream_client
 5263                    .request(request)
 5264                    .await
 5265                    .context("color presentation proto request")?;
 5266                color.resolved = true;
 5267                color.color_presentations = response
 5268                    .presentations
 5269                    .into_iter()
 5270                    .map(|presentation| ColorPresentation {
 5271                        label: SharedString::from(presentation.label),
 5272                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5273                        additional_text_edits: presentation
 5274                            .additional_text_edits
 5275                            .into_iter()
 5276                            .filter_map(deserialize_lsp_edit)
 5277                            .collect(),
 5278                    })
 5279                    .collect();
 5280                Ok(color)
 5281            })
 5282        } else {
 5283            let path = match buffer
 5284                .update(cx, |buffer, cx| {
 5285                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5286                })
 5287                .context("buffer with the missing path")
 5288            {
 5289                Ok(path) => path,
 5290                Err(e) => return Task::ready(Err(e)),
 5291            };
 5292            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5293                self.language_server_for_local_buffer(buffer, server_id, cx)
 5294                    .map(|(_, server)| server.clone())
 5295            }) else {
 5296                return Task::ready(Ok(color));
 5297            };
 5298            cx.background_spawn(async move {
 5299                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5300                    lsp::ColorPresentationParams {
 5301                        text_document: make_text_document_identifier(&path)?,
 5302                        color: color.color,
 5303                        range: color.lsp_range,
 5304                        work_done_progress_params: Default::default(),
 5305                        partial_result_params: Default::default(),
 5306                    },
 5307                );
 5308                color.color_presentations = resolve_task
 5309                    .await
 5310                    .into_response()
 5311                    .context("color presentation resolve LSP request")?
 5312                    .into_iter()
 5313                    .map(|presentation| ColorPresentation {
 5314                        label: SharedString::from(presentation.label),
 5315                        text_edit: presentation.text_edit,
 5316                        additional_text_edits: presentation
 5317                            .additional_text_edits
 5318                            .unwrap_or_default(),
 5319                    })
 5320                    .collect();
 5321                color.resolved = true;
 5322                Ok(color)
 5323            })
 5324        }
 5325    }
 5326
 5327    pub(crate) fn linked_edits(
 5328        &mut self,
 5329        buffer: &Entity<Buffer>,
 5330        position: Anchor,
 5331        cx: &mut Context<Self>,
 5332    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5333        let snapshot = buffer.read(cx).snapshot();
 5334        let scope = snapshot.language_scope_at(position);
 5335        let Some(server_id) = self
 5336            .as_local()
 5337            .and_then(|local| {
 5338                buffer.update(cx, |buffer, cx| {
 5339                    local
 5340                        .language_servers_for_buffer(buffer, cx)
 5341                        .filter(|(_, server)| {
 5342                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5343                        })
 5344                        .filter(|(adapter, _)| {
 5345                            scope
 5346                                .as_ref()
 5347                                .map(|scope| scope.language_allowed(&adapter.name))
 5348                                .unwrap_or(true)
 5349                        })
 5350                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5351                        .next()
 5352                })
 5353            })
 5354            .or_else(|| {
 5355                self.upstream_client()
 5356                    .is_some()
 5357                    .then_some(LanguageServerToQuery::FirstCapable)
 5358            })
 5359            .filter(|_| {
 5360                maybe!({
 5361                    let language = buffer.read(cx).language_at(position)?;
 5362                    Some(
 5363                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5364                            .linked_edits,
 5365                    )
 5366                }) == Some(true)
 5367            })
 5368        else {
 5369            return Task::ready(Ok(Vec::new()));
 5370        };
 5371
 5372        self.request_lsp(
 5373            buffer.clone(),
 5374            server_id,
 5375            LinkedEditingRange { position },
 5376            cx,
 5377        )
 5378    }
 5379
 5380    fn apply_on_type_formatting(
 5381        &mut self,
 5382        buffer: Entity<Buffer>,
 5383        position: Anchor,
 5384        trigger: String,
 5385        cx: &mut Context<Self>,
 5386    ) -> Task<Result<Option<Transaction>>> {
 5387        if let Some((client, project_id)) = self.upstream_client() {
 5388            if !self.check_if_capable_for_proto_request(
 5389                &buffer,
 5390                |capabilities| {
 5391                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5392                },
 5393                cx,
 5394            ) {
 5395                return Task::ready(Ok(None));
 5396            }
 5397            let request = proto::OnTypeFormatting {
 5398                project_id,
 5399                buffer_id: buffer.read(cx).remote_id().into(),
 5400                position: Some(serialize_anchor(&position)),
 5401                trigger,
 5402                version: serialize_version(&buffer.read(cx).version()),
 5403            };
 5404            cx.background_spawn(async move {
 5405                client
 5406                    .request(request)
 5407                    .await?
 5408                    .transaction
 5409                    .map(language::proto::deserialize_transaction)
 5410                    .transpose()
 5411            })
 5412        } else if let Some(local) = self.as_local_mut() {
 5413            let buffer_id = buffer.read(cx).remote_id();
 5414            local.buffers_being_formatted.insert(buffer_id);
 5415            cx.spawn(async move |this, cx| {
 5416                let _cleanup = defer({
 5417                    let this = this.clone();
 5418                    let mut cx = cx.clone();
 5419                    move || {
 5420                        this.update(&mut cx, |this, _| {
 5421                            if let Some(local) = this.as_local_mut() {
 5422                                local.buffers_being_formatted.remove(&buffer_id);
 5423                            }
 5424                        })
 5425                        .ok();
 5426                    }
 5427                });
 5428
 5429                buffer
 5430                    .update(cx, |buffer, _| {
 5431                        buffer.wait_for_edits(Some(position.timestamp))
 5432                    })?
 5433                    .await?;
 5434                this.update(cx, |this, cx| {
 5435                    let position = position.to_point_utf16(buffer.read(cx));
 5436                    this.on_type_format(buffer, position, trigger, false, cx)
 5437                })?
 5438                .await
 5439            })
 5440        } else {
 5441            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5442        }
 5443    }
 5444
 5445    pub fn on_type_format<T: ToPointUtf16>(
 5446        &mut self,
 5447        buffer: Entity<Buffer>,
 5448        position: T,
 5449        trigger: String,
 5450        push_to_history: bool,
 5451        cx: &mut Context<Self>,
 5452    ) -> Task<Result<Option<Transaction>>> {
 5453        let position = position.to_point_utf16(buffer.read(cx));
 5454        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5455    }
 5456
 5457    fn on_type_format_impl(
 5458        &mut self,
 5459        buffer: Entity<Buffer>,
 5460        position: PointUtf16,
 5461        trigger: String,
 5462        push_to_history: bool,
 5463        cx: &mut Context<Self>,
 5464    ) -> Task<Result<Option<Transaction>>> {
 5465        let options = buffer.update(cx, |buffer, cx| {
 5466            lsp_command::lsp_formatting_options(
 5467                language_settings(
 5468                    buffer.language_at(position).map(|l| l.name()),
 5469                    buffer.file(),
 5470                    cx,
 5471                )
 5472                .as_ref(),
 5473            )
 5474        });
 5475
 5476        cx.spawn(async move |this, cx| {
 5477            if let Some(waiter) =
 5478                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5479            {
 5480                waiter.await?;
 5481            }
 5482            cx.update(|cx| {
 5483                this.update(cx, |this, cx| {
 5484                    this.request_lsp(
 5485                        buffer.clone(),
 5486                        LanguageServerToQuery::FirstCapable,
 5487                        OnTypeFormatting {
 5488                            position,
 5489                            trigger,
 5490                            options,
 5491                            push_to_history,
 5492                        },
 5493                        cx,
 5494                    )
 5495                })
 5496            })??
 5497            .await
 5498        })
 5499    }
 5500
 5501    pub fn definitions(
 5502        &mut self,
 5503        buffer: &Entity<Buffer>,
 5504        position: PointUtf16,
 5505        cx: &mut Context<Self>,
 5506    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5507        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5508            let request = GetDefinitions { position };
 5509            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5510                return Task::ready(Ok(None));
 5511            }
 5512            let request_task = upstream_client.request_lsp(
 5513                project_id,
 5514                None,
 5515                LSP_REQUEST_TIMEOUT,
 5516                cx.background_executor().clone(),
 5517                request.to_proto(project_id, buffer.read(cx)),
 5518            );
 5519            let buffer = buffer.clone();
 5520            cx.spawn(async move |weak_lsp_store, cx| {
 5521                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5522                    return Ok(None);
 5523                };
 5524                let Some(responses) = request_task.await? else {
 5525                    return Ok(None);
 5526                };
 5527                let actions = join_all(responses.payload.into_iter().map(|response| {
 5528                    GetDefinitions { position }.response_from_proto(
 5529                        response.response,
 5530                        lsp_store.clone(),
 5531                        buffer.clone(),
 5532                        cx.clone(),
 5533                    )
 5534                }))
 5535                .await;
 5536
 5537                Ok(Some(
 5538                    actions
 5539                        .into_iter()
 5540                        .collect::<Result<Vec<Vec<_>>>>()?
 5541                        .into_iter()
 5542                        .flatten()
 5543                        .dedup()
 5544                        .collect(),
 5545                ))
 5546            })
 5547        } else {
 5548            let definitions_task = self.request_multiple_lsp_locally(
 5549                buffer,
 5550                Some(position),
 5551                GetDefinitions { position },
 5552                cx,
 5553            );
 5554            cx.background_spawn(async move {
 5555                Ok(Some(
 5556                    definitions_task
 5557                        .await
 5558                        .into_iter()
 5559                        .flat_map(|(_, definitions)| definitions)
 5560                        .dedup()
 5561                        .collect(),
 5562                ))
 5563            })
 5564        }
 5565    }
 5566
 5567    pub fn declarations(
 5568        &mut self,
 5569        buffer: &Entity<Buffer>,
 5570        position: PointUtf16,
 5571        cx: &mut Context<Self>,
 5572    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5573        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5574            let request = GetDeclarations { position };
 5575            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5576                return Task::ready(Ok(None));
 5577            }
 5578            let request_task = upstream_client.request_lsp(
 5579                project_id,
 5580                None,
 5581                LSP_REQUEST_TIMEOUT,
 5582                cx.background_executor().clone(),
 5583                request.to_proto(project_id, buffer.read(cx)),
 5584            );
 5585            let buffer = buffer.clone();
 5586            cx.spawn(async move |weak_lsp_store, cx| {
 5587                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5588                    return Ok(None);
 5589                };
 5590                let Some(responses) = request_task.await? else {
 5591                    return Ok(None);
 5592                };
 5593                let actions = join_all(responses.payload.into_iter().map(|response| {
 5594                    GetDeclarations { position }.response_from_proto(
 5595                        response.response,
 5596                        lsp_store.clone(),
 5597                        buffer.clone(),
 5598                        cx.clone(),
 5599                    )
 5600                }))
 5601                .await;
 5602
 5603                Ok(Some(
 5604                    actions
 5605                        .into_iter()
 5606                        .collect::<Result<Vec<Vec<_>>>>()?
 5607                        .into_iter()
 5608                        .flatten()
 5609                        .dedup()
 5610                        .collect(),
 5611                ))
 5612            })
 5613        } else {
 5614            let declarations_task = self.request_multiple_lsp_locally(
 5615                buffer,
 5616                Some(position),
 5617                GetDeclarations { position },
 5618                cx,
 5619            );
 5620            cx.background_spawn(async move {
 5621                Ok(Some(
 5622                    declarations_task
 5623                        .await
 5624                        .into_iter()
 5625                        .flat_map(|(_, declarations)| declarations)
 5626                        .dedup()
 5627                        .collect(),
 5628                ))
 5629            })
 5630        }
 5631    }
 5632
 5633    pub fn type_definitions(
 5634        &mut self,
 5635        buffer: &Entity<Buffer>,
 5636        position: PointUtf16,
 5637        cx: &mut Context<Self>,
 5638    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5639        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5640            let request = GetTypeDefinitions { position };
 5641            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5642                return Task::ready(Ok(None));
 5643            }
 5644            let request_task = upstream_client.request_lsp(
 5645                project_id,
 5646                None,
 5647                LSP_REQUEST_TIMEOUT,
 5648                cx.background_executor().clone(),
 5649                request.to_proto(project_id, buffer.read(cx)),
 5650            );
 5651            let buffer = buffer.clone();
 5652            cx.spawn(async move |weak_lsp_store, cx| {
 5653                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5654                    return Ok(None);
 5655                };
 5656                let Some(responses) = request_task.await? else {
 5657                    return Ok(None);
 5658                };
 5659                let actions = join_all(responses.payload.into_iter().map(|response| {
 5660                    GetTypeDefinitions { position }.response_from_proto(
 5661                        response.response,
 5662                        lsp_store.clone(),
 5663                        buffer.clone(),
 5664                        cx.clone(),
 5665                    )
 5666                }))
 5667                .await;
 5668
 5669                Ok(Some(
 5670                    actions
 5671                        .into_iter()
 5672                        .collect::<Result<Vec<Vec<_>>>>()?
 5673                        .into_iter()
 5674                        .flatten()
 5675                        .dedup()
 5676                        .collect(),
 5677                ))
 5678            })
 5679        } else {
 5680            let type_definitions_task = self.request_multiple_lsp_locally(
 5681                buffer,
 5682                Some(position),
 5683                GetTypeDefinitions { position },
 5684                cx,
 5685            );
 5686            cx.background_spawn(async move {
 5687                Ok(Some(
 5688                    type_definitions_task
 5689                        .await
 5690                        .into_iter()
 5691                        .flat_map(|(_, type_definitions)| type_definitions)
 5692                        .dedup()
 5693                        .collect(),
 5694                ))
 5695            })
 5696        }
 5697    }
 5698
 5699    pub fn implementations(
 5700        &mut self,
 5701        buffer: &Entity<Buffer>,
 5702        position: PointUtf16,
 5703        cx: &mut Context<Self>,
 5704    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5705        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5706            let request = GetImplementations { position };
 5707            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5708                return Task::ready(Ok(None));
 5709            }
 5710            let request_task = upstream_client.request_lsp(
 5711                project_id,
 5712                None,
 5713                LSP_REQUEST_TIMEOUT,
 5714                cx.background_executor().clone(),
 5715                request.to_proto(project_id, buffer.read(cx)),
 5716            );
 5717            let buffer = buffer.clone();
 5718            cx.spawn(async move |weak_lsp_store, cx| {
 5719                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5720                    return Ok(None);
 5721                };
 5722                let Some(responses) = request_task.await? else {
 5723                    return Ok(None);
 5724                };
 5725                let actions = join_all(responses.payload.into_iter().map(|response| {
 5726                    GetImplementations { position }.response_from_proto(
 5727                        response.response,
 5728                        lsp_store.clone(),
 5729                        buffer.clone(),
 5730                        cx.clone(),
 5731                    )
 5732                }))
 5733                .await;
 5734
 5735                Ok(Some(
 5736                    actions
 5737                        .into_iter()
 5738                        .collect::<Result<Vec<Vec<_>>>>()?
 5739                        .into_iter()
 5740                        .flatten()
 5741                        .dedup()
 5742                        .collect(),
 5743                ))
 5744            })
 5745        } else {
 5746            let implementations_task = self.request_multiple_lsp_locally(
 5747                buffer,
 5748                Some(position),
 5749                GetImplementations { position },
 5750                cx,
 5751            );
 5752            cx.background_spawn(async move {
 5753                Ok(Some(
 5754                    implementations_task
 5755                        .await
 5756                        .into_iter()
 5757                        .flat_map(|(_, implementations)| implementations)
 5758                        .dedup()
 5759                        .collect(),
 5760                ))
 5761            })
 5762        }
 5763    }
 5764
 5765    pub fn references(
 5766        &mut self,
 5767        buffer: &Entity<Buffer>,
 5768        position: PointUtf16,
 5769        cx: &mut Context<Self>,
 5770    ) -> Task<Result<Option<Vec<Location>>>> {
 5771        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5772            let request = GetReferences { position };
 5773            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5774                return Task::ready(Ok(None));
 5775            }
 5776
 5777            let request_task = upstream_client.request_lsp(
 5778                project_id,
 5779                None,
 5780                LSP_REQUEST_TIMEOUT,
 5781                cx.background_executor().clone(),
 5782                request.to_proto(project_id, buffer.read(cx)),
 5783            );
 5784            let buffer = buffer.clone();
 5785            cx.spawn(async move |weak_lsp_store, cx| {
 5786                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5787                    return Ok(None);
 5788                };
 5789                let Some(responses) = request_task.await? else {
 5790                    return Ok(None);
 5791                };
 5792
 5793                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5794                    GetReferences { position }.response_from_proto(
 5795                        lsp_response.response,
 5796                        lsp_store.clone(),
 5797                        buffer.clone(),
 5798                        cx.clone(),
 5799                    )
 5800                }))
 5801                .await
 5802                .into_iter()
 5803                .collect::<Result<Vec<Vec<_>>>>()?
 5804                .into_iter()
 5805                .flatten()
 5806                .dedup()
 5807                .collect();
 5808                Ok(Some(locations))
 5809            })
 5810        } else {
 5811            let references_task = self.request_multiple_lsp_locally(
 5812                buffer,
 5813                Some(position),
 5814                GetReferences { position },
 5815                cx,
 5816            );
 5817            cx.background_spawn(async move {
 5818                Ok(Some(
 5819                    references_task
 5820                        .await
 5821                        .into_iter()
 5822                        .flat_map(|(_, references)| references)
 5823                        .dedup()
 5824                        .collect(),
 5825                ))
 5826            })
 5827        }
 5828    }
 5829
 5830    pub fn code_actions(
 5831        &mut self,
 5832        buffer: &Entity<Buffer>,
 5833        range: Range<Anchor>,
 5834        kinds: Option<Vec<CodeActionKind>>,
 5835        cx: &mut Context<Self>,
 5836    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5837        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5838            let request = GetCodeActions {
 5839                range: range.clone(),
 5840                kinds: kinds.clone(),
 5841            };
 5842            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5843                return Task::ready(Ok(None));
 5844            }
 5845            let request_task = upstream_client.request_lsp(
 5846                project_id,
 5847                None,
 5848                LSP_REQUEST_TIMEOUT,
 5849                cx.background_executor().clone(),
 5850                request.to_proto(project_id, buffer.read(cx)),
 5851            );
 5852            let buffer = buffer.clone();
 5853            cx.spawn(async move |weak_lsp_store, cx| {
 5854                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5855                    return Ok(None);
 5856                };
 5857                let Some(responses) = request_task.await? else {
 5858                    return Ok(None);
 5859                };
 5860                let actions = join_all(responses.payload.into_iter().map(|response| {
 5861                    GetCodeActions {
 5862                        range: range.clone(),
 5863                        kinds: kinds.clone(),
 5864                    }
 5865                    .response_from_proto(
 5866                        response.response,
 5867                        lsp_store.clone(),
 5868                        buffer.clone(),
 5869                        cx.clone(),
 5870                    )
 5871                }))
 5872                .await;
 5873
 5874                Ok(Some(
 5875                    actions
 5876                        .into_iter()
 5877                        .collect::<Result<Vec<Vec<_>>>>()?
 5878                        .into_iter()
 5879                        .flatten()
 5880                        .collect(),
 5881                ))
 5882            })
 5883        } else {
 5884            let all_actions_task = self.request_multiple_lsp_locally(
 5885                buffer,
 5886                Some(range.start),
 5887                GetCodeActions { range, kinds },
 5888                cx,
 5889            );
 5890            cx.background_spawn(async move {
 5891                Ok(Some(
 5892                    all_actions_task
 5893                        .await
 5894                        .into_iter()
 5895                        .flat_map(|(_, actions)| actions)
 5896                        .collect(),
 5897                ))
 5898            })
 5899        }
 5900    }
 5901
 5902    pub fn code_lens_actions(
 5903        &mut self,
 5904        buffer: &Entity<Buffer>,
 5905        cx: &mut Context<Self>,
 5906    ) -> CodeLensTask {
 5907        let version_queried_for = buffer.read(cx).version();
 5908        let buffer_id = buffer.read(cx).remote_id();
 5909        let existing_servers = self.as_local().map(|local| {
 5910            local
 5911                .buffers_opened_in_servers
 5912                .get(&buffer_id)
 5913                .cloned()
 5914                .unwrap_or_default()
 5915        });
 5916
 5917        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5918            if let Some(cached_lens) = &lsp_data.code_lens {
 5919                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5920                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5921                        existing_servers != cached_lens.lens.keys().copied().collect()
 5922                    });
 5923                    if !has_different_servers {
 5924                        return Task::ready(Ok(Some(
 5925                            cached_lens.lens.values().flatten().cloned().collect(),
 5926                        )))
 5927                        .shared();
 5928                    }
 5929                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5930                    if !version_queried_for.changed_since(updating_for) {
 5931                        return running_update.clone();
 5932                    }
 5933                }
 5934            }
 5935        }
 5936
 5937        let lens_lsp_data = self
 5938            .latest_lsp_data(buffer, cx)
 5939            .code_lens
 5940            .get_or_insert_default();
 5941        let buffer = buffer.clone();
 5942        let query_version_queried_for = version_queried_for.clone();
 5943        let new_task = cx
 5944            .spawn(async move |lsp_store, cx| {
 5945                cx.background_executor()
 5946                    .timer(Duration::from_millis(30))
 5947                    .await;
 5948                let fetched_lens = lsp_store
 5949                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5950                    .map_err(Arc::new)?
 5951                    .await
 5952                    .context("fetching code lens")
 5953                    .map_err(Arc::new);
 5954                let fetched_lens = match fetched_lens {
 5955                    Ok(fetched_lens) => fetched_lens,
 5956                    Err(e) => {
 5957                        lsp_store
 5958                            .update(cx, |lsp_store, _| {
 5959                                if let Some(lens_lsp_data) = lsp_store
 5960                                    .lsp_data
 5961                                    .get_mut(&buffer_id)
 5962                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5963                                {
 5964                                    lens_lsp_data.update = None;
 5965                                }
 5966                            })
 5967                            .ok();
 5968                        return Err(e);
 5969                    }
 5970                };
 5971
 5972                lsp_store
 5973                    .update(cx, |lsp_store, _| {
 5974                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5975                        let code_lens = lsp_data.code_lens.as_mut()?;
 5976                        if let Some(fetched_lens) = fetched_lens {
 5977                            if lsp_data.buffer_version == query_version_queried_for {
 5978                                code_lens.lens.extend(fetched_lens);
 5979                            } else if !lsp_data
 5980                                .buffer_version
 5981                                .changed_since(&query_version_queried_for)
 5982                            {
 5983                                lsp_data.buffer_version = query_version_queried_for;
 5984                                code_lens.lens = fetched_lens;
 5985                            }
 5986                        }
 5987                        code_lens.update = None;
 5988                        Some(code_lens.lens.values().flatten().cloned().collect())
 5989                    })
 5990                    .map_err(Arc::new)
 5991            })
 5992            .shared();
 5993        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5994        new_task
 5995    }
 5996
 5997    fn fetch_code_lens(
 5998        &mut self,
 5999        buffer: &Entity<Buffer>,
 6000        cx: &mut Context<Self>,
 6001    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6002        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6003            let request = GetCodeLens;
 6004            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6005                return Task::ready(Ok(None));
 6006            }
 6007            let request_task = upstream_client.request_lsp(
 6008                project_id,
 6009                None,
 6010                LSP_REQUEST_TIMEOUT,
 6011                cx.background_executor().clone(),
 6012                request.to_proto(project_id, buffer.read(cx)),
 6013            );
 6014            let buffer = buffer.clone();
 6015            cx.spawn(async move |weak_lsp_store, cx| {
 6016                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6017                    return Ok(None);
 6018                };
 6019                let Some(responses) = request_task.await? else {
 6020                    return Ok(None);
 6021                };
 6022
 6023                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6024                    let lsp_store = lsp_store.clone();
 6025                    let buffer = buffer.clone();
 6026                    let cx = cx.clone();
 6027                    async move {
 6028                        (
 6029                            LanguageServerId::from_proto(response.server_id),
 6030                            GetCodeLens
 6031                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6032                                .await,
 6033                        )
 6034                    }
 6035                }))
 6036                .await;
 6037
 6038                let mut has_errors = false;
 6039                let code_lens_actions = code_lens_actions
 6040                    .into_iter()
 6041                    .filter_map(|(server_id, code_lens)| match code_lens {
 6042                        Ok(code_lens) => Some((server_id, code_lens)),
 6043                        Err(e) => {
 6044                            has_errors = true;
 6045                            log::error!("{e:#}");
 6046                            None
 6047                        }
 6048                    })
 6049                    .collect::<HashMap<_, _>>();
 6050                anyhow::ensure!(
 6051                    !has_errors || !code_lens_actions.is_empty(),
 6052                    "Failed to fetch code lens"
 6053                );
 6054                Ok(Some(code_lens_actions))
 6055            })
 6056        } else {
 6057            let code_lens_actions_task =
 6058                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6059            cx.background_spawn(async move {
 6060                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6061            })
 6062        }
 6063    }
 6064
 6065    #[inline(never)]
 6066    pub fn completions(
 6067        &self,
 6068        buffer: &Entity<Buffer>,
 6069        position: PointUtf16,
 6070        context: CompletionContext,
 6071        cx: &mut Context<Self>,
 6072    ) -> Task<Result<Vec<CompletionResponse>>> {
 6073        let language_registry = self.languages.clone();
 6074
 6075        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6076            let snapshot = buffer.read(cx).snapshot();
 6077            let offset = position.to_offset(&snapshot);
 6078            let scope = snapshot.language_scope_at(offset);
 6079            let capable_lsps = self.all_capable_for_proto_request(
 6080                buffer,
 6081                |server_name, capabilities| {
 6082                    capabilities.completion_provider.is_some()
 6083                        && scope
 6084                            .as_ref()
 6085                            .map(|scope| scope.language_allowed(server_name))
 6086                            .unwrap_or(true)
 6087                },
 6088                cx,
 6089            );
 6090            if capable_lsps.is_empty() {
 6091                return Task::ready(Ok(Vec::new()));
 6092            }
 6093
 6094            let language = buffer.read(cx).language().cloned();
 6095
 6096            // In the future, we should provide project guests with the names of LSP adapters,
 6097            // so that they can use the correct LSP adapter when computing labels. For now,
 6098            // guests just use the first LSP adapter associated with the buffer's language.
 6099            let lsp_adapter = language.as_ref().and_then(|language| {
 6100                language_registry
 6101                    .lsp_adapters(&language.name())
 6102                    .first()
 6103                    .cloned()
 6104            });
 6105
 6106            let buffer = buffer.clone();
 6107
 6108            cx.spawn(async move |this, cx| {
 6109                let requests = join_all(
 6110                    capable_lsps
 6111                        .into_iter()
 6112                        .map(|id| {
 6113                            let request = GetCompletions {
 6114                                position,
 6115                                context: context.clone(),
 6116                                server_id: Some(id),
 6117                            };
 6118                            let buffer = buffer.clone();
 6119                            let language = language.clone();
 6120                            let lsp_adapter = lsp_adapter.clone();
 6121                            let upstream_client = upstream_client.clone();
 6122                            let response = this
 6123                                .update(cx, |this, cx| {
 6124                                    this.send_lsp_proto_request(
 6125                                        buffer,
 6126                                        upstream_client,
 6127                                        project_id,
 6128                                        request,
 6129                                        cx,
 6130                                    )
 6131                                })
 6132                                .log_err();
 6133                            async move {
 6134                                let response = response?.await.log_err()?;
 6135
 6136                                let completions = populate_labels_for_completions(
 6137                                    response.completions,
 6138                                    language,
 6139                                    lsp_adapter,
 6140                                )
 6141                                .await;
 6142
 6143                                Some(CompletionResponse {
 6144                                    completions,
 6145                                    display_options: CompletionDisplayOptions::default(),
 6146                                    is_incomplete: response.is_incomplete,
 6147                                })
 6148                            }
 6149                        })
 6150                        .collect::<Vec<_>>(),
 6151                );
 6152                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6153            })
 6154        } else if let Some(local) = self.as_local() {
 6155            let snapshot = buffer.read(cx).snapshot();
 6156            let offset = position.to_offset(&snapshot);
 6157            let scope = snapshot.language_scope_at(offset);
 6158            let language = snapshot.language().cloned();
 6159            let completion_settings = language_settings(
 6160                language.as_ref().map(|language| language.name()),
 6161                buffer.read(cx).file(),
 6162                cx,
 6163            )
 6164            .completions
 6165            .clone();
 6166            if !completion_settings.lsp {
 6167                return Task::ready(Ok(Vec::new()));
 6168            }
 6169
 6170            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6171                local
 6172                    .language_servers_for_buffer(buffer, cx)
 6173                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6174                    .filter(|(adapter, _)| {
 6175                        scope
 6176                            .as_ref()
 6177                            .map(|scope| scope.language_allowed(&adapter.name))
 6178                            .unwrap_or(true)
 6179                    })
 6180                    .map(|(_, server)| server.server_id())
 6181                    .collect()
 6182            });
 6183
 6184            let buffer = buffer.clone();
 6185            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6186            let lsp_timeout = if lsp_timeout > 0 {
 6187                Some(Duration::from_millis(lsp_timeout))
 6188            } else {
 6189                None
 6190            };
 6191            cx.spawn(async move |this,  cx| {
 6192                let mut tasks = Vec::with_capacity(server_ids.len());
 6193                this.update(cx, |lsp_store, cx| {
 6194                    for server_id in server_ids {
 6195                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6196                        let lsp_timeout = lsp_timeout
 6197                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6198                        let mut timeout = cx.background_spawn(async move {
 6199                            match lsp_timeout {
 6200                                Some(lsp_timeout) => {
 6201                                    lsp_timeout.await;
 6202                                    true
 6203                                },
 6204                                None => false,
 6205                            }
 6206                        }).fuse();
 6207                        let mut lsp_request = lsp_store.request_lsp(
 6208                            buffer.clone(),
 6209                            LanguageServerToQuery::Other(server_id),
 6210                            GetCompletions {
 6211                                position,
 6212                                context: context.clone(),
 6213                                server_id: Some(server_id),
 6214                            },
 6215                            cx,
 6216                        ).fuse();
 6217                        let new_task = cx.background_spawn(async move {
 6218                            select_biased! {
 6219                                response = lsp_request => anyhow::Ok(Some(response?)),
 6220                                timeout_happened = timeout => {
 6221                                    if timeout_happened {
 6222                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6223                                        Ok(None)
 6224                                    } else {
 6225                                        let completions = lsp_request.await?;
 6226                                        Ok(Some(completions))
 6227                                    }
 6228                                },
 6229                            }
 6230                        });
 6231                        tasks.push((lsp_adapter, new_task));
 6232                    }
 6233                })?;
 6234
 6235                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6236                    let completion_response = task.await.ok()??;
 6237                    let completions = populate_labels_for_completions(
 6238                            completion_response.completions,
 6239                            language.clone(),
 6240                            lsp_adapter,
 6241                        )
 6242                        .await;
 6243                    Some(CompletionResponse {
 6244                        completions,
 6245                        display_options: CompletionDisplayOptions::default(),
 6246                        is_incomplete: completion_response.is_incomplete,
 6247                    })
 6248                });
 6249
 6250                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6251
 6252                Ok(responses.into_iter().flatten().collect())
 6253            })
 6254        } else {
 6255            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6256        }
 6257    }
 6258
 6259    pub fn resolve_completions(
 6260        &self,
 6261        buffer: Entity<Buffer>,
 6262        completion_indices: Vec<usize>,
 6263        completions: Rc<RefCell<Box<[Completion]>>>,
 6264        cx: &mut Context<Self>,
 6265    ) -> Task<Result<bool>> {
 6266        let client = self.upstream_client();
 6267        let buffer_id = buffer.read(cx).remote_id();
 6268        let buffer_snapshot = buffer.read(cx).snapshot();
 6269
 6270        if !self.check_if_capable_for_proto_request(
 6271            &buffer,
 6272            GetCompletions::can_resolve_completions,
 6273            cx,
 6274        ) {
 6275            return Task::ready(Ok(false));
 6276        }
 6277        cx.spawn(async move |lsp_store, cx| {
 6278            let mut did_resolve = false;
 6279            if let Some((client, project_id)) = client {
 6280                for completion_index in completion_indices {
 6281                    let server_id = {
 6282                        let completion = &completions.borrow()[completion_index];
 6283                        completion.source.server_id()
 6284                    };
 6285                    if let Some(server_id) = server_id {
 6286                        if Self::resolve_completion_remote(
 6287                            project_id,
 6288                            server_id,
 6289                            buffer_id,
 6290                            completions.clone(),
 6291                            completion_index,
 6292                            client.clone(),
 6293                        )
 6294                        .await
 6295                        .log_err()
 6296                        .is_some()
 6297                        {
 6298                            did_resolve = true;
 6299                        }
 6300                    } else {
 6301                        resolve_word_completion(
 6302                            &buffer_snapshot,
 6303                            &mut completions.borrow_mut()[completion_index],
 6304                        );
 6305                    }
 6306                }
 6307            } else {
 6308                for completion_index in completion_indices {
 6309                    let server_id = {
 6310                        let completion = &completions.borrow()[completion_index];
 6311                        completion.source.server_id()
 6312                    };
 6313                    if let Some(server_id) = server_id {
 6314                        let server_and_adapter = lsp_store
 6315                            .read_with(cx, |lsp_store, _| {
 6316                                let server = lsp_store.language_server_for_id(server_id)?;
 6317                                let adapter =
 6318                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6319                                Some((server, adapter))
 6320                            })
 6321                            .ok()
 6322                            .flatten();
 6323                        let Some((server, adapter)) = server_and_adapter else {
 6324                            continue;
 6325                        };
 6326
 6327                        let resolved = Self::resolve_completion_local(
 6328                            server,
 6329                            completions.clone(),
 6330                            completion_index,
 6331                        )
 6332                        .await
 6333                        .log_err()
 6334                        .is_some();
 6335                        if resolved {
 6336                            Self::regenerate_completion_labels(
 6337                                adapter,
 6338                                &buffer_snapshot,
 6339                                completions.clone(),
 6340                                completion_index,
 6341                            )
 6342                            .await
 6343                            .log_err();
 6344                            did_resolve = true;
 6345                        }
 6346                    } else {
 6347                        resolve_word_completion(
 6348                            &buffer_snapshot,
 6349                            &mut completions.borrow_mut()[completion_index],
 6350                        );
 6351                    }
 6352                }
 6353            }
 6354
 6355            Ok(did_resolve)
 6356        })
 6357    }
 6358
 6359    async fn resolve_completion_local(
 6360        server: Arc<lsp::LanguageServer>,
 6361        completions: Rc<RefCell<Box<[Completion]>>>,
 6362        completion_index: usize,
 6363    ) -> Result<()> {
 6364        let server_id = server.server_id();
 6365        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6366            return Ok(());
 6367        }
 6368
 6369        let request = {
 6370            let completion = &completions.borrow()[completion_index];
 6371            match &completion.source {
 6372                CompletionSource::Lsp {
 6373                    lsp_completion,
 6374                    resolved,
 6375                    server_id: completion_server_id,
 6376                    ..
 6377                } => {
 6378                    if *resolved {
 6379                        return Ok(());
 6380                    }
 6381                    anyhow::ensure!(
 6382                        server_id == *completion_server_id,
 6383                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6384                    );
 6385                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6386                }
 6387                CompletionSource::BufferWord { .. }
 6388                | CompletionSource::Dap { .. }
 6389                | CompletionSource::Custom => {
 6390                    return Ok(());
 6391                }
 6392            }
 6393        };
 6394        let resolved_completion = request
 6395            .await
 6396            .into_response()
 6397            .context("resolve completion")?;
 6398
 6399        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6400        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6401
 6402        let mut completions = completions.borrow_mut();
 6403        let completion = &mut completions[completion_index];
 6404        if let CompletionSource::Lsp {
 6405            lsp_completion,
 6406            resolved,
 6407            server_id: completion_server_id,
 6408            ..
 6409        } = &mut completion.source
 6410        {
 6411            if *resolved {
 6412                return Ok(());
 6413            }
 6414            anyhow::ensure!(
 6415                server_id == *completion_server_id,
 6416                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6417            );
 6418            *lsp_completion = Box::new(resolved_completion);
 6419            *resolved = true;
 6420        }
 6421        Ok(())
 6422    }
 6423
 6424    async fn regenerate_completion_labels(
 6425        adapter: Arc<CachedLspAdapter>,
 6426        snapshot: &BufferSnapshot,
 6427        completions: Rc<RefCell<Box<[Completion]>>>,
 6428        completion_index: usize,
 6429    ) -> Result<()> {
 6430        let completion_item = completions.borrow()[completion_index]
 6431            .source
 6432            .lsp_completion(true)
 6433            .map(Cow::into_owned);
 6434        if let Some(lsp_documentation) = completion_item
 6435            .as_ref()
 6436            .and_then(|completion_item| completion_item.documentation.clone())
 6437        {
 6438            let mut completions = completions.borrow_mut();
 6439            let completion = &mut completions[completion_index];
 6440            completion.documentation = Some(lsp_documentation.into());
 6441        } else {
 6442            let mut completions = completions.borrow_mut();
 6443            let completion = &mut completions[completion_index];
 6444            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6445        }
 6446
 6447        let mut new_label = match completion_item {
 6448            Some(completion_item) => {
 6449                // 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
 6450                // So we have to update the label here anyway...
 6451                let language = snapshot.language();
 6452                match language {
 6453                    Some(language) => {
 6454                        adapter
 6455                            .labels_for_completions(
 6456                                std::slice::from_ref(&completion_item),
 6457                                language,
 6458                            )
 6459                            .await?
 6460                    }
 6461                    None => Vec::new(),
 6462                }
 6463                .pop()
 6464                .flatten()
 6465                .unwrap_or_else(|| {
 6466                    CodeLabel::fallback_for_completion(
 6467                        &completion_item,
 6468                        language.map(|language| language.as_ref()),
 6469                    )
 6470                })
 6471            }
 6472            None => CodeLabel::plain(
 6473                completions.borrow()[completion_index].new_text.clone(),
 6474                None,
 6475            ),
 6476        };
 6477        ensure_uniform_list_compatible_label(&mut new_label);
 6478
 6479        let mut completions = completions.borrow_mut();
 6480        let completion = &mut completions[completion_index];
 6481        if completion.label.filter_text() == new_label.filter_text() {
 6482            completion.label = new_label;
 6483        } else {
 6484            log::error!(
 6485                "Resolved completion changed display label from {} to {}. \
 6486                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6487                completion.label.text(),
 6488                new_label.text(),
 6489                completion.label.filter_text(),
 6490                new_label.filter_text()
 6491            );
 6492        }
 6493
 6494        Ok(())
 6495    }
 6496
 6497    async fn resolve_completion_remote(
 6498        project_id: u64,
 6499        server_id: LanguageServerId,
 6500        buffer_id: BufferId,
 6501        completions: Rc<RefCell<Box<[Completion]>>>,
 6502        completion_index: usize,
 6503        client: AnyProtoClient,
 6504    ) -> Result<()> {
 6505        let lsp_completion = {
 6506            let completion = &completions.borrow()[completion_index];
 6507            match &completion.source {
 6508                CompletionSource::Lsp {
 6509                    lsp_completion,
 6510                    resolved,
 6511                    server_id: completion_server_id,
 6512                    ..
 6513                } => {
 6514                    anyhow::ensure!(
 6515                        server_id == *completion_server_id,
 6516                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6517                    );
 6518                    if *resolved {
 6519                        return Ok(());
 6520                    }
 6521                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6522                }
 6523                CompletionSource::Custom
 6524                | CompletionSource::Dap { .. }
 6525                | CompletionSource::BufferWord { .. } => {
 6526                    return Ok(());
 6527                }
 6528            }
 6529        };
 6530        let request = proto::ResolveCompletionDocumentation {
 6531            project_id,
 6532            language_server_id: server_id.0 as u64,
 6533            lsp_completion,
 6534            buffer_id: buffer_id.into(),
 6535        };
 6536
 6537        let response = client
 6538            .request(request)
 6539            .await
 6540            .context("completion documentation resolve proto request")?;
 6541        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6542
 6543        let documentation = if response.documentation.is_empty() {
 6544            CompletionDocumentation::Undocumented
 6545        } else if response.documentation_is_markdown {
 6546            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6547        } else if response.documentation.lines().count() <= 1 {
 6548            CompletionDocumentation::SingleLine(response.documentation.into())
 6549        } else {
 6550            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6551        };
 6552
 6553        let mut completions = completions.borrow_mut();
 6554        let completion = &mut completions[completion_index];
 6555        completion.documentation = Some(documentation);
 6556        if let CompletionSource::Lsp {
 6557            insert_range,
 6558            lsp_completion,
 6559            resolved,
 6560            server_id: completion_server_id,
 6561            lsp_defaults: _,
 6562        } = &mut completion.source
 6563        {
 6564            let completion_insert_range = response
 6565                .old_insert_start
 6566                .and_then(deserialize_anchor)
 6567                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6568            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6569
 6570            if *resolved {
 6571                return Ok(());
 6572            }
 6573            anyhow::ensure!(
 6574                server_id == *completion_server_id,
 6575                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6576            );
 6577            *lsp_completion = Box::new(resolved_lsp_completion);
 6578            *resolved = true;
 6579        }
 6580
 6581        let replace_range = response
 6582            .old_replace_start
 6583            .and_then(deserialize_anchor)
 6584            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6585        if let Some((old_replace_start, old_replace_end)) = replace_range
 6586            && !response.new_text.is_empty()
 6587        {
 6588            completion.new_text = response.new_text;
 6589            completion.replace_range = old_replace_start..old_replace_end;
 6590        }
 6591
 6592        Ok(())
 6593    }
 6594
 6595    pub fn apply_additional_edits_for_completion(
 6596        &self,
 6597        buffer_handle: Entity<Buffer>,
 6598        completions: Rc<RefCell<Box<[Completion]>>>,
 6599        completion_index: usize,
 6600        push_to_history: bool,
 6601        cx: &mut Context<Self>,
 6602    ) -> Task<Result<Option<Transaction>>> {
 6603        if let Some((client, project_id)) = self.upstream_client() {
 6604            let buffer = buffer_handle.read(cx);
 6605            let buffer_id = buffer.remote_id();
 6606            cx.spawn(async move |_, cx| {
 6607                let request = {
 6608                    let completion = completions.borrow()[completion_index].clone();
 6609                    proto::ApplyCompletionAdditionalEdits {
 6610                        project_id,
 6611                        buffer_id: buffer_id.into(),
 6612                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6613                            replace_range: completion.replace_range,
 6614                            new_text: completion.new_text,
 6615                            source: completion.source,
 6616                        })),
 6617                    }
 6618                };
 6619
 6620                if let Some(transaction) = client.request(request).await?.transaction {
 6621                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6622                    buffer_handle
 6623                        .update(cx, |buffer, _| {
 6624                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6625                        })?
 6626                        .await?;
 6627                    if push_to_history {
 6628                        buffer_handle.update(cx, |buffer, _| {
 6629                            buffer.push_transaction(transaction.clone(), Instant::now());
 6630                            buffer.finalize_last_transaction();
 6631                        })?;
 6632                    }
 6633                    Ok(Some(transaction))
 6634                } else {
 6635                    Ok(None)
 6636                }
 6637            })
 6638        } else {
 6639            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6640                let completion = &completions.borrow()[completion_index];
 6641                let server_id = completion.source.server_id()?;
 6642                Some(
 6643                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6644                        .1
 6645                        .clone(),
 6646                )
 6647            }) else {
 6648                return Task::ready(Ok(None));
 6649            };
 6650
 6651            cx.spawn(async move |this, cx| {
 6652                Self::resolve_completion_local(
 6653                    server.clone(),
 6654                    completions.clone(),
 6655                    completion_index,
 6656                )
 6657                .await
 6658                .context("resolving completion")?;
 6659                let completion = completions.borrow()[completion_index].clone();
 6660                let additional_text_edits = completion
 6661                    .source
 6662                    .lsp_completion(true)
 6663                    .as_ref()
 6664                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6665                if let Some(edits) = additional_text_edits {
 6666                    let edits = this
 6667                        .update(cx, |this, cx| {
 6668                            this.as_local_mut().unwrap().edits_from_lsp(
 6669                                &buffer_handle,
 6670                                edits,
 6671                                server.server_id(),
 6672                                None,
 6673                                cx,
 6674                            )
 6675                        })?
 6676                        .await?;
 6677
 6678                    buffer_handle.update(cx, |buffer, cx| {
 6679                        buffer.finalize_last_transaction();
 6680                        buffer.start_transaction();
 6681
 6682                        for (range, text) in edits {
 6683                            let primary = &completion.replace_range;
 6684
 6685                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6686                            // and the primary completion is just an insertion (empty range), then this is likely
 6687                            // an auto-import scenario and should not be considered overlapping
 6688                            // https://github.com/zed-industries/zed/issues/26136
 6689                            let is_file_start_auto_import = {
 6690                                let snapshot = buffer.snapshot();
 6691                                let primary_start_point = primary.start.to_point(&snapshot);
 6692                                let range_start_point = range.start.to_point(&snapshot);
 6693
 6694                                let result = primary_start_point.row == 0
 6695                                    && primary_start_point.column == 0
 6696                                    && range_start_point.row == 0
 6697                                    && range_start_point.column == 0;
 6698
 6699                                result
 6700                            };
 6701
 6702                            let has_overlap = if is_file_start_auto_import {
 6703                                false
 6704                            } else {
 6705                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6706                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6707                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6708                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6709                                let result = start_within || end_within;
 6710                                result
 6711                            };
 6712
 6713                            //Skip additional edits which overlap with the primary completion edit
 6714                            //https://github.com/zed-industries/zed/pull/1871
 6715                            if !has_overlap {
 6716                                buffer.edit([(range, text)], None, cx);
 6717                            }
 6718                        }
 6719
 6720                        let transaction = if buffer.end_transaction(cx).is_some() {
 6721                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6722                            if !push_to_history {
 6723                                buffer.forget_transaction(transaction.id);
 6724                            }
 6725                            Some(transaction)
 6726                        } else {
 6727                            None
 6728                        };
 6729                        Ok(transaction)
 6730                    })?
 6731                } else {
 6732                    Ok(None)
 6733                }
 6734            })
 6735        }
 6736    }
 6737
 6738    pub fn pull_diagnostics(
 6739        &mut self,
 6740        buffer: Entity<Buffer>,
 6741        cx: &mut Context<Self>,
 6742    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6743        let buffer_id = buffer.read(cx).remote_id();
 6744
 6745        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6746            let mut suitable_capabilities = None;
 6747            // Are we capable for proto request?
 6748            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6749                &buffer,
 6750                |capabilities| {
 6751                    if let Some(caps) = &capabilities.diagnostic_provider {
 6752                        suitable_capabilities = Some(caps.clone());
 6753                        true
 6754                    } else {
 6755                        false
 6756                    }
 6757                },
 6758                cx,
 6759            );
 6760            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6761            let Some(dynamic_caps) = suitable_capabilities else {
 6762                return Task::ready(Ok(None));
 6763            };
 6764            assert!(any_server_has_diagnostics_provider);
 6765
 6766            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6767            let request = GetDocumentDiagnostics {
 6768                previous_result_id: None,
 6769                identifier,
 6770                registration_id: None,
 6771            };
 6772            let request_task = client.request_lsp(
 6773                upstream_project_id,
 6774                None,
 6775                LSP_REQUEST_TIMEOUT,
 6776                cx.background_executor().clone(),
 6777                request.to_proto(upstream_project_id, buffer.read(cx)),
 6778            );
 6779            cx.background_spawn(async move {
 6780                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6781                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6782                // Do not attempt to further process the dummy responses here.
 6783                let _response = request_task.await?;
 6784                Ok(None)
 6785            })
 6786        } else {
 6787            let servers = buffer.update(cx, |buffer, cx| {
 6788                self.running_language_servers_for_local_buffer(buffer, cx)
 6789                    .map(|(_, server)| server.clone())
 6790                    .collect::<Vec<_>>()
 6791            });
 6792
 6793            let pull_diagnostics = servers
 6794                .into_iter()
 6795                .flat_map(|server| {
 6796                    let result = maybe!({
 6797                        let local = self.as_local()?;
 6798                        let server_id = server.server_id();
 6799                        let providers_with_identifiers = local
 6800                            .language_server_dynamic_registrations
 6801                            .get(&server_id)
 6802                            .into_iter()
 6803                            .flat_map(|registrations| registrations.diagnostics.clone())
 6804                            .collect::<Vec<_>>();
 6805                        Some(
 6806                            providers_with_identifiers
 6807                                .into_iter()
 6808                                .map(|(registration_id, dynamic_caps)| {
 6809                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6810                                    let registration_id = registration_id.map(SharedString::from);
 6811                                    let result_id = self.result_id_for_buffer_pull(
 6812                                        server_id,
 6813                                        buffer_id,
 6814                                        &registration_id,
 6815                                        cx,
 6816                                    );
 6817                                    self.request_lsp(
 6818                                        buffer.clone(),
 6819                                        LanguageServerToQuery::Other(server_id),
 6820                                        GetDocumentDiagnostics {
 6821                                            previous_result_id: result_id,
 6822                                            registration_id,
 6823                                            identifier,
 6824                                        },
 6825                                        cx,
 6826                                    )
 6827                                })
 6828                                .collect::<Vec<_>>(),
 6829                        )
 6830                    });
 6831
 6832                    result.unwrap_or_default()
 6833                })
 6834                .collect::<Vec<_>>();
 6835
 6836            cx.background_spawn(async move {
 6837                let mut responses = Vec::new();
 6838                for diagnostics in join_all(pull_diagnostics).await {
 6839                    responses.extend(diagnostics?);
 6840                }
 6841                Ok(Some(responses))
 6842            })
 6843        }
 6844    }
 6845
 6846    pub fn applicable_inlay_chunks(
 6847        &mut self,
 6848        buffer: &Entity<Buffer>,
 6849        ranges: &[Range<text::Anchor>],
 6850        cx: &mut Context<Self>,
 6851    ) -> Vec<Range<BufferRow>> {
 6852        let buffer_snapshot = buffer.read(cx).snapshot();
 6853        let ranges = ranges
 6854            .iter()
 6855            .map(|range| range.to_point(&buffer_snapshot))
 6856            .collect::<Vec<_>>();
 6857
 6858        self.latest_lsp_data(buffer, cx)
 6859            .inlay_hints
 6860            .applicable_chunks(ranges.as_slice())
 6861            .map(|chunk| chunk.row_range())
 6862            .collect()
 6863    }
 6864
 6865    pub fn invalidate_inlay_hints<'a>(
 6866        &'a mut self,
 6867        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6868    ) {
 6869        for buffer_id in for_buffers {
 6870            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6871                lsp_data.inlay_hints.clear();
 6872            }
 6873        }
 6874    }
 6875
 6876    pub fn inlay_hints(
 6877        &mut self,
 6878        invalidate: InvalidationStrategy,
 6879        buffer: Entity<Buffer>,
 6880        ranges: Vec<Range<text::Anchor>>,
 6881        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6882        cx: &mut Context<Self>,
 6883    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6884        let next_hint_id = self.next_hint_id.clone();
 6885        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6886        let query_version = lsp_data.buffer_version.clone();
 6887        let mut lsp_refresh_requested = false;
 6888        let for_server = if let InvalidationStrategy::RefreshRequested {
 6889            server_id,
 6890            request_id,
 6891        } = invalidate
 6892        {
 6893            let invalidated = lsp_data
 6894                .inlay_hints
 6895                .invalidate_for_server_refresh(server_id, request_id);
 6896            lsp_refresh_requested = invalidated;
 6897            Some(server_id)
 6898        } else {
 6899            None
 6900        };
 6901        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6902        let known_chunks = known_chunks
 6903            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6904            .map(|(_, known_chunks)| known_chunks)
 6905            .unwrap_or_default();
 6906
 6907        let buffer_snapshot = buffer.read(cx).snapshot();
 6908        let ranges = ranges
 6909            .iter()
 6910            .map(|range| range.to_point(&buffer_snapshot))
 6911            .collect::<Vec<_>>();
 6912
 6913        let mut hint_fetch_tasks = Vec::new();
 6914        let mut cached_inlay_hints = None;
 6915        let mut ranges_to_query = None;
 6916        let applicable_chunks = existing_inlay_hints
 6917            .applicable_chunks(ranges.as_slice())
 6918            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6919            .collect::<Vec<_>>();
 6920        if applicable_chunks.is_empty() {
 6921            return HashMap::default();
 6922        }
 6923
 6924        for row_chunk in applicable_chunks {
 6925            match (
 6926                existing_inlay_hints
 6927                    .cached_hints(&row_chunk)
 6928                    .filter(|_| !lsp_refresh_requested)
 6929                    .cloned(),
 6930                existing_inlay_hints
 6931                    .fetched_hints(&row_chunk)
 6932                    .as_ref()
 6933                    .filter(|_| !lsp_refresh_requested)
 6934                    .cloned(),
 6935            ) {
 6936                (None, None) => {
 6937                    let chunk_range = row_chunk.anchor_range();
 6938                    ranges_to_query
 6939                        .get_or_insert_with(Vec::new)
 6940                        .push((row_chunk, chunk_range));
 6941                }
 6942                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6943                (Some(cached_hints), None) => {
 6944                    for (server_id, cached_hints) in cached_hints {
 6945                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6946                            cached_inlay_hints
 6947                                .get_or_insert_with(HashMap::default)
 6948                                .entry(row_chunk.row_range())
 6949                                .or_insert_with(HashMap::default)
 6950                                .entry(server_id)
 6951                                .or_insert_with(Vec::new)
 6952                                .extend(cached_hints);
 6953                        }
 6954                    }
 6955                }
 6956                (Some(cached_hints), Some(fetched_hints)) => {
 6957                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6958                    for (server_id, cached_hints) in cached_hints {
 6959                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6960                            cached_inlay_hints
 6961                                .get_or_insert_with(HashMap::default)
 6962                                .entry(row_chunk.row_range())
 6963                                .or_insert_with(HashMap::default)
 6964                                .entry(server_id)
 6965                                .or_insert_with(Vec::new)
 6966                                .extend(cached_hints);
 6967                        }
 6968                    }
 6969                }
 6970            }
 6971        }
 6972
 6973        if hint_fetch_tasks.is_empty()
 6974            && ranges_to_query
 6975                .as_ref()
 6976                .is_none_or(|ranges| ranges.is_empty())
 6977            && let Some(cached_inlay_hints) = cached_inlay_hints
 6978        {
 6979            cached_inlay_hints
 6980                .into_iter()
 6981                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6982                .collect()
 6983        } else {
 6984            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6985                let next_hint_id = next_hint_id.clone();
 6986                let buffer = buffer.clone();
 6987                let query_version = query_version.clone();
 6988                let new_inlay_hints = cx
 6989                    .spawn(async move |lsp_store, cx| {
 6990                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6991                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6992                        })?;
 6993                        new_fetch_task
 6994                            .await
 6995                            .and_then(|new_hints_by_server| {
 6996                                lsp_store.update(cx, |lsp_store, cx| {
 6997                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6998                                    let update_cache = lsp_data.buffer_version == query_version;
 6999                                    if new_hints_by_server.is_empty() {
 7000                                        if update_cache {
 7001                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7002                                        }
 7003                                        HashMap::default()
 7004                                    } else {
 7005                                        new_hints_by_server
 7006                                            .into_iter()
 7007                                            .map(|(server_id, new_hints)| {
 7008                                                let new_hints = new_hints
 7009                                                    .into_iter()
 7010                                                    .map(|new_hint| {
 7011                                                        (
 7012                                                            InlayId::Hint(next_hint_id.fetch_add(
 7013                                                                1,
 7014                                                                atomic::Ordering::AcqRel,
 7015                                                            )),
 7016                                                            new_hint,
 7017                                                        )
 7018                                                    })
 7019                                                    .collect::<Vec<_>>();
 7020                                                if update_cache {
 7021                                                    lsp_data.inlay_hints.insert_new_hints(
 7022                                                        chunk,
 7023                                                        server_id,
 7024                                                        new_hints.clone(),
 7025                                                    );
 7026                                                }
 7027                                                (server_id, new_hints)
 7028                                            })
 7029                                            .collect()
 7030                                    }
 7031                                })
 7032                            })
 7033                            .map_err(Arc::new)
 7034                    })
 7035                    .shared();
 7036
 7037                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7038                *fetch_task = Some(new_inlay_hints.clone());
 7039                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7040            }
 7041
 7042            cached_inlay_hints
 7043                .unwrap_or_default()
 7044                .into_iter()
 7045                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7046                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7047                    (
 7048                        chunk.row_range(),
 7049                        cx.spawn(async move |_, _| {
 7050                            hints_fetch.await.map_err(|e| {
 7051                                if e.error_code() != ErrorCode::Internal {
 7052                                    anyhow!(e.error_code())
 7053                                } else {
 7054                                    anyhow!("{e:#}")
 7055                                }
 7056                            })
 7057                        }),
 7058                    )
 7059                }))
 7060                .collect()
 7061        }
 7062    }
 7063
 7064    fn fetch_inlay_hints(
 7065        &mut self,
 7066        for_server: Option<LanguageServerId>,
 7067        buffer: &Entity<Buffer>,
 7068        range: Range<Anchor>,
 7069        cx: &mut Context<Self>,
 7070    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7071        let request = InlayHints {
 7072            range: range.clone(),
 7073        };
 7074        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7075            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7076                return Task::ready(Ok(HashMap::default()));
 7077            }
 7078            let request_task = upstream_client.request_lsp(
 7079                project_id,
 7080                for_server.map(|id| id.to_proto()),
 7081                LSP_REQUEST_TIMEOUT,
 7082                cx.background_executor().clone(),
 7083                request.to_proto(project_id, buffer.read(cx)),
 7084            );
 7085            let buffer = buffer.clone();
 7086            cx.spawn(async move |weak_lsp_store, cx| {
 7087                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7088                    return Ok(HashMap::default());
 7089                };
 7090                let Some(responses) = request_task.await? else {
 7091                    return Ok(HashMap::default());
 7092                };
 7093
 7094                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7095                    let lsp_store = lsp_store.clone();
 7096                    let buffer = buffer.clone();
 7097                    let cx = cx.clone();
 7098                    let request = request.clone();
 7099                    async move {
 7100                        (
 7101                            LanguageServerId::from_proto(response.server_id),
 7102                            request
 7103                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7104                                .await,
 7105                        )
 7106                    }
 7107                }))
 7108                .await;
 7109
 7110                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7111                let mut has_errors = false;
 7112                let inlay_hints = inlay_hints
 7113                    .into_iter()
 7114                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7115                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7116                        Err(e) => {
 7117                            has_errors = true;
 7118                            log::error!("{e:#}");
 7119                            None
 7120                        }
 7121                    })
 7122                    .map(|(server_id, mut new_hints)| {
 7123                        new_hints.retain(|hint| {
 7124                            hint.position.is_valid(&buffer_snapshot)
 7125                                && range.start.is_valid(&buffer_snapshot)
 7126                                && range.end.is_valid(&buffer_snapshot)
 7127                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7128                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7129                        });
 7130                        (server_id, new_hints)
 7131                    })
 7132                    .collect::<HashMap<_, _>>();
 7133                anyhow::ensure!(
 7134                    !has_errors || !inlay_hints.is_empty(),
 7135                    "Failed to fetch inlay hints"
 7136                );
 7137                Ok(inlay_hints)
 7138            })
 7139        } else {
 7140            let inlay_hints_task = match for_server {
 7141                Some(server_id) => {
 7142                    let server_task = self.request_lsp(
 7143                        buffer.clone(),
 7144                        LanguageServerToQuery::Other(server_id),
 7145                        request,
 7146                        cx,
 7147                    );
 7148                    cx.background_spawn(async move {
 7149                        let mut responses = Vec::new();
 7150                        match server_task.await {
 7151                            Ok(response) => responses.push((server_id, response)),
 7152                            // rust-analyzer likes to error with this when its still loading up
 7153                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7154                            Err(e) => log::error!(
 7155                                "Error handling response for inlay hints request: {e:#}"
 7156                            ),
 7157                        }
 7158                        responses
 7159                    })
 7160                }
 7161                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7162            };
 7163            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7164            cx.background_spawn(async move {
 7165                Ok(inlay_hints_task
 7166                    .await
 7167                    .into_iter()
 7168                    .map(|(server_id, mut new_hints)| {
 7169                        new_hints.retain(|hint| {
 7170                            hint.position.is_valid(&buffer_snapshot)
 7171                                && range.start.is_valid(&buffer_snapshot)
 7172                                && range.end.is_valid(&buffer_snapshot)
 7173                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7174                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7175                        });
 7176                        (server_id, new_hints)
 7177                    })
 7178                    .collect())
 7179            })
 7180        }
 7181    }
 7182
 7183    pub fn pull_diagnostics_for_buffer(
 7184        &mut self,
 7185        buffer: Entity<Buffer>,
 7186        cx: &mut Context<Self>,
 7187    ) -> Task<anyhow::Result<()>> {
 7188        let diagnostics = self.pull_diagnostics(buffer, cx);
 7189        cx.spawn(async move |lsp_store, cx| {
 7190            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7191                return Ok(());
 7192            };
 7193            lsp_store.update(cx, |lsp_store, cx| {
 7194                if lsp_store.as_local().is_none() {
 7195                    return;
 7196                }
 7197
 7198                let mut unchanged_buffers = HashMap::default();
 7199                let server_diagnostics_updates = diagnostics
 7200                    .into_iter()
 7201                    .filter_map(|diagnostics_set| match diagnostics_set {
 7202                        LspPullDiagnostics::Response {
 7203                            server_id,
 7204                            uri,
 7205                            diagnostics,
 7206                            registration_id,
 7207                        } => Some((server_id, uri, diagnostics, registration_id)),
 7208                        LspPullDiagnostics::Default => None,
 7209                    })
 7210                    .fold(
 7211                        HashMap::default(),
 7212                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7213                            let (result_id, diagnostics) = match diagnostics {
 7214                                PulledDiagnostics::Unchanged { result_id } => {
 7215                                    unchanged_buffers
 7216                                        .entry(new_registration_id.clone())
 7217                                        .or_insert_with(HashSet::default)
 7218                                        .insert(uri.clone());
 7219                                    (Some(result_id), Vec::new())
 7220                                }
 7221                                PulledDiagnostics::Changed {
 7222                                    result_id,
 7223                                    diagnostics,
 7224                                } => (result_id, diagnostics),
 7225                            };
 7226                            let disk_based_sources = Cow::Owned(
 7227                                lsp_store
 7228                                    .language_server_adapter_for_id(server_id)
 7229                                    .as_ref()
 7230                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7231                                    .unwrap_or(&[])
 7232                                    .to_vec(),
 7233                            );
 7234                            acc.entry(server_id)
 7235                                .or_insert_with(HashMap::default)
 7236                                .entry(new_registration_id.clone())
 7237                                .or_insert_with(Vec::new)
 7238                                .push(DocumentDiagnosticsUpdate {
 7239                                    server_id,
 7240                                    diagnostics: lsp::PublishDiagnosticsParams {
 7241                                        uri,
 7242                                        diagnostics,
 7243                                        version: None,
 7244                                    },
 7245                                    result_id,
 7246                                    disk_based_sources,
 7247                                    registration_id: new_registration_id,
 7248                                });
 7249                            acc
 7250                        },
 7251                    );
 7252
 7253                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7254                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7255                        lsp_store
 7256                            .merge_lsp_diagnostics(
 7257                                DiagnosticSourceKind::Pulled,
 7258                                diagnostic_updates,
 7259                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7260                                    DiagnosticSourceKind::Pulled => {
 7261                                        old_diagnostic.registration_id != registration_id
 7262                                            || unchanged_buffers
 7263                                                .get(&old_diagnostic.registration_id)
 7264                                                .is_some_and(|unchanged_buffers| {
 7265                                                    unchanged_buffers.contains(&document_uri)
 7266                                                })
 7267                                    }
 7268                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7269                                        true
 7270                                    }
 7271                                },
 7272                                cx,
 7273                            )
 7274                            .log_err();
 7275                    }
 7276                }
 7277            })
 7278        })
 7279    }
 7280
 7281    pub fn document_colors(
 7282        &mut self,
 7283        known_cache_version: Option<usize>,
 7284        buffer: Entity<Buffer>,
 7285        cx: &mut Context<Self>,
 7286    ) -> Option<DocumentColorTask> {
 7287        let version_queried_for = buffer.read(cx).version();
 7288        let buffer_id = buffer.read(cx).remote_id();
 7289
 7290        let current_language_servers = self.as_local().map(|local| {
 7291            local
 7292                .buffers_opened_in_servers
 7293                .get(&buffer_id)
 7294                .cloned()
 7295                .unwrap_or_default()
 7296        });
 7297
 7298        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7299            if let Some(cached_colors) = &lsp_data.document_colors {
 7300                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7301                    let has_different_servers =
 7302                        current_language_servers.is_some_and(|current_language_servers| {
 7303                            current_language_servers
 7304                                != cached_colors.colors.keys().copied().collect()
 7305                        });
 7306                    if !has_different_servers {
 7307                        let cache_version = cached_colors.cache_version;
 7308                        if Some(cache_version) == known_cache_version {
 7309                            return None;
 7310                        } else {
 7311                            return Some(
 7312                                Task::ready(Ok(DocumentColors {
 7313                                    colors: cached_colors
 7314                                        .colors
 7315                                        .values()
 7316                                        .flatten()
 7317                                        .cloned()
 7318                                        .collect(),
 7319                                    cache_version: Some(cache_version),
 7320                                }))
 7321                                .shared(),
 7322                            );
 7323                        }
 7324                    }
 7325                }
 7326            }
 7327        }
 7328
 7329        let color_lsp_data = self
 7330            .latest_lsp_data(&buffer, cx)
 7331            .document_colors
 7332            .get_or_insert_default();
 7333        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7334            && !version_queried_for.changed_since(updating_for)
 7335        {
 7336            return Some(running_update.clone());
 7337        }
 7338        let buffer_version_queried_for = version_queried_for.clone();
 7339        let new_task = cx
 7340            .spawn(async move |lsp_store, cx| {
 7341                cx.background_executor()
 7342                    .timer(Duration::from_millis(30))
 7343                    .await;
 7344                let fetched_colors = lsp_store
 7345                    .update(cx, |lsp_store, cx| {
 7346                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7347                    })?
 7348                    .await
 7349                    .context("fetching document colors")
 7350                    .map_err(Arc::new);
 7351                let fetched_colors = match fetched_colors {
 7352                    Ok(fetched_colors) => {
 7353                        if Some(true)
 7354                            == buffer
 7355                                .update(cx, |buffer, _| {
 7356                                    buffer.version() != buffer_version_queried_for
 7357                                })
 7358                                .ok()
 7359                        {
 7360                            return Ok(DocumentColors::default());
 7361                        }
 7362                        fetched_colors
 7363                    }
 7364                    Err(e) => {
 7365                        lsp_store
 7366                            .update(cx, |lsp_store, _| {
 7367                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7368                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7369                                        document_colors.colors_update = None;
 7370                                    }
 7371                                }
 7372                            })
 7373                            .ok();
 7374                        return Err(e);
 7375                    }
 7376                };
 7377
 7378                lsp_store
 7379                    .update(cx, |lsp_store, cx| {
 7380                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7381                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7382
 7383                        if let Some(fetched_colors) = fetched_colors {
 7384                            if lsp_data.buffer_version == buffer_version_queried_for {
 7385                                lsp_colors.colors.extend(fetched_colors);
 7386                                lsp_colors.cache_version += 1;
 7387                            } else if !lsp_data
 7388                                .buffer_version
 7389                                .changed_since(&buffer_version_queried_for)
 7390                            {
 7391                                lsp_data.buffer_version = buffer_version_queried_for;
 7392                                lsp_colors.colors = fetched_colors;
 7393                                lsp_colors.cache_version += 1;
 7394                            }
 7395                        }
 7396                        lsp_colors.colors_update = None;
 7397                        let colors = lsp_colors
 7398                            .colors
 7399                            .values()
 7400                            .flatten()
 7401                            .cloned()
 7402                            .collect::<HashSet<_>>();
 7403                        DocumentColors {
 7404                            colors,
 7405                            cache_version: Some(lsp_colors.cache_version),
 7406                        }
 7407                    })
 7408                    .map_err(Arc::new)
 7409            })
 7410            .shared();
 7411        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7412        Some(new_task)
 7413    }
 7414
 7415    fn fetch_document_colors_for_buffer(
 7416        &mut self,
 7417        buffer: &Entity<Buffer>,
 7418        cx: &mut Context<Self>,
 7419    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7420        if let Some((client, project_id)) = self.upstream_client() {
 7421            let request = GetDocumentColor {};
 7422            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7423                return Task::ready(Ok(None));
 7424            }
 7425
 7426            let request_task = client.request_lsp(
 7427                project_id,
 7428                None,
 7429                LSP_REQUEST_TIMEOUT,
 7430                cx.background_executor().clone(),
 7431                request.to_proto(project_id, buffer.read(cx)),
 7432            );
 7433            let buffer = buffer.clone();
 7434            cx.spawn(async move |lsp_store, cx| {
 7435                let Some(lsp_store) = lsp_store.upgrade() else {
 7436                    return Ok(None);
 7437                };
 7438                let colors = join_all(
 7439                    request_task
 7440                        .await
 7441                        .log_err()
 7442                        .flatten()
 7443                        .map(|response| response.payload)
 7444                        .unwrap_or_default()
 7445                        .into_iter()
 7446                        .map(|color_response| {
 7447                            let response = request.response_from_proto(
 7448                                color_response.response,
 7449                                lsp_store.clone(),
 7450                                buffer.clone(),
 7451                                cx.clone(),
 7452                            );
 7453                            async move {
 7454                                (
 7455                                    LanguageServerId::from_proto(color_response.server_id),
 7456                                    response.await.log_err().unwrap_or_default(),
 7457                                )
 7458                            }
 7459                        }),
 7460                )
 7461                .await
 7462                .into_iter()
 7463                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7464                    acc.entry(server_id)
 7465                        .or_insert_with(HashSet::default)
 7466                        .extend(colors);
 7467                    acc
 7468                });
 7469                Ok(Some(colors))
 7470            })
 7471        } else {
 7472            let document_colors_task =
 7473                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7474            cx.background_spawn(async move {
 7475                Ok(Some(
 7476                    document_colors_task
 7477                        .await
 7478                        .into_iter()
 7479                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7480                            acc.entry(server_id)
 7481                                .or_insert_with(HashSet::default)
 7482                                .extend(colors);
 7483                            acc
 7484                        })
 7485                        .into_iter()
 7486                        .collect(),
 7487                ))
 7488            })
 7489        }
 7490    }
 7491
 7492    pub fn signature_help<T: ToPointUtf16>(
 7493        &mut self,
 7494        buffer: &Entity<Buffer>,
 7495        position: T,
 7496        cx: &mut Context<Self>,
 7497    ) -> Task<Option<Vec<SignatureHelp>>> {
 7498        let position = position.to_point_utf16(buffer.read(cx));
 7499
 7500        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7501            let request = GetSignatureHelp { position };
 7502            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7503                return Task::ready(None);
 7504            }
 7505            let request_task = client.request_lsp(
 7506                upstream_project_id,
 7507                None,
 7508                LSP_REQUEST_TIMEOUT,
 7509                cx.background_executor().clone(),
 7510                request.to_proto(upstream_project_id, buffer.read(cx)),
 7511            );
 7512            let buffer = buffer.clone();
 7513            cx.spawn(async move |weak_lsp_store, cx| {
 7514                let lsp_store = weak_lsp_store.upgrade()?;
 7515                let signatures = join_all(
 7516                    request_task
 7517                        .await
 7518                        .log_err()
 7519                        .flatten()
 7520                        .map(|response| response.payload)
 7521                        .unwrap_or_default()
 7522                        .into_iter()
 7523                        .map(|response| {
 7524                            let response = GetSignatureHelp { position }.response_from_proto(
 7525                                response.response,
 7526                                lsp_store.clone(),
 7527                                buffer.clone(),
 7528                                cx.clone(),
 7529                            );
 7530                            async move { response.await.log_err().flatten() }
 7531                        }),
 7532                )
 7533                .await
 7534                .into_iter()
 7535                .flatten()
 7536                .collect();
 7537                Some(signatures)
 7538            })
 7539        } else {
 7540            let all_actions_task = self.request_multiple_lsp_locally(
 7541                buffer,
 7542                Some(position),
 7543                GetSignatureHelp { position },
 7544                cx,
 7545            );
 7546            cx.background_spawn(async move {
 7547                Some(
 7548                    all_actions_task
 7549                        .await
 7550                        .into_iter()
 7551                        .flat_map(|(_, actions)| actions)
 7552                        .collect::<Vec<_>>(),
 7553                )
 7554            })
 7555        }
 7556    }
 7557
 7558    pub fn hover(
 7559        &mut self,
 7560        buffer: &Entity<Buffer>,
 7561        position: PointUtf16,
 7562        cx: &mut Context<Self>,
 7563    ) -> Task<Option<Vec<Hover>>> {
 7564        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7565            let request = GetHover { position };
 7566            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7567                return Task::ready(None);
 7568            }
 7569            let request_task = client.request_lsp(
 7570                upstream_project_id,
 7571                None,
 7572                LSP_REQUEST_TIMEOUT,
 7573                cx.background_executor().clone(),
 7574                request.to_proto(upstream_project_id, buffer.read(cx)),
 7575            );
 7576            let buffer = buffer.clone();
 7577            cx.spawn(async move |weak_lsp_store, cx| {
 7578                let lsp_store = weak_lsp_store.upgrade()?;
 7579                let hovers = join_all(
 7580                    request_task
 7581                        .await
 7582                        .log_err()
 7583                        .flatten()
 7584                        .map(|response| response.payload)
 7585                        .unwrap_or_default()
 7586                        .into_iter()
 7587                        .map(|response| {
 7588                            let response = GetHover { position }.response_from_proto(
 7589                                response.response,
 7590                                lsp_store.clone(),
 7591                                buffer.clone(),
 7592                                cx.clone(),
 7593                            );
 7594                            async move {
 7595                                response
 7596                                    .await
 7597                                    .log_err()
 7598                                    .flatten()
 7599                                    .and_then(remove_empty_hover_blocks)
 7600                            }
 7601                        }),
 7602                )
 7603                .await
 7604                .into_iter()
 7605                .flatten()
 7606                .collect();
 7607                Some(hovers)
 7608            })
 7609        } else {
 7610            let all_actions_task = self.request_multiple_lsp_locally(
 7611                buffer,
 7612                Some(position),
 7613                GetHover { position },
 7614                cx,
 7615            );
 7616            cx.background_spawn(async move {
 7617                Some(
 7618                    all_actions_task
 7619                        .await
 7620                        .into_iter()
 7621                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7622                        .collect::<Vec<Hover>>(),
 7623                )
 7624            })
 7625        }
 7626    }
 7627
 7628    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7629        let language_registry = self.languages.clone();
 7630
 7631        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7632            let request = upstream_client.request(proto::GetProjectSymbols {
 7633                project_id: *project_id,
 7634                query: query.to_string(),
 7635            });
 7636            cx.foreground_executor().spawn(async move {
 7637                let response = request.await?;
 7638                let mut symbols = Vec::new();
 7639                let core_symbols = response
 7640                    .symbols
 7641                    .into_iter()
 7642                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7643                    .collect::<Vec<_>>();
 7644                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7645                    .await;
 7646                Ok(symbols)
 7647            })
 7648        } else if let Some(local) = self.as_local() {
 7649            struct WorkspaceSymbolsResult {
 7650                server_id: LanguageServerId,
 7651                lsp_adapter: Arc<CachedLspAdapter>,
 7652                worktree: WeakEntity<Worktree>,
 7653                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7654            }
 7655
 7656            let mut requests = Vec::new();
 7657            let mut requested_servers = BTreeSet::new();
 7658            for (seed, state) in local.language_server_ids.iter() {
 7659                let Some(worktree_handle) = self
 7660                    .worktree_store
 7661                    .read(cx)
 7662                    .worktree_for_id(seed.worktree_id, cx)
 7663                else {
 7664                    continue;
 7665                };
 7666                let worktree = worktree_handle.read(cx);
 7667                if !worktree.is_visible() {
 7668                    continue;
 7669                }
 7670
 7671                if !requested_servers.insert(state.id) {
 7672                    continue;
 7673                }
 7674
 7675                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7676                    Some(LanguageServerState::Running {
 7677                        adapter, server, ..
 7678                    }) => (adapter.clone(), server),
 7679
 7680                    _ => continue,
 7681                };
 7682                let supports_workspace_symbol_request =
 7683                    match server.capabilities().workspace_symbol_provider {
 7684                        Some(OneOf::Left(supported)) => supported,
 7685                        Some(OneOf::Right(_)) => true,
 7686                        None => false,
 7687                    };
 7688                if !supports_workspace_symbol_request {
 7689                    continue;
 7690                }
 7691                let worktree_handle = worktree_handle.clone();
 7692                let server_id = server.server_id();
 7693                requests.push(
 7694                        server
 7695                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7696                                lsp::WorkspaceSymbolParams {
 7697                                    query: query.to_string(),
 7698                                    ..Default::default()
 7699                                },
 7700                            )
 7701                            .map(move |response| {
 7702                                let lsp_symbols = response.into_response()
 7703                                    .context("workspace symbols request")
 7704                                    .log_err()
 7705                                    .flatten()
 7706                                    .map(|symbol_response| match symbol_response {
 7707                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7708                                            flat_responses.into_iter().map(|lsp_symbol| {
 7709                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7710                                            }).collect::<Vec<_>>()
 7711                                        }
 7712                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7713                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7714                                                let location = match lsp_symbol.location {
 7715                                                    OneOf::Left(location) => location,
 7716                                                    OneOf::Right(_) => {
 7717                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7718                                                        return None
 7719                                                    }
 7720                                                };
 7721                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7722                                            }).collect::<Vec<_>>()
 7723                                        }
 7724                                    }).unwrap_or_default();
 7725
 7726                                WorkspaceSymbolsResult {
 7727                                    server_id,
 7728                                    lsp_adapter,
 7729                                    worktree: worktree_handle.downgrade(),
 7730                                    lsp_symbols,
 7731                                }
 7732                            }),
 7733                    );
 7734            }
 7735
 7736            cx.spawn(async move |this, cx| {
 7737                let responses = futures::future::join_all(requests).await;
 7738                let this = match this.upgrade() {
 7739                    Some(this) => this,
 7740                    None => return Ok(Vec::new()),
 7741                };
 7742
 7743                let mut symbols = Vec::new();
 7744                for result in responses {
 7745                    let core_symbols = this.update(cx, |this, cx| {
 7746                        result
 7747                            .lsp_symbols
 7748                            .into_iter()
 7749                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7750                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7751                                let source_worktree = result.worktree.upgrade()?;
 7752                                let source_worktree_id = source_worktree.read(cx).id();
 7753
 7754                                let path = if let Some((tree, rel_path)) =
 7755                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7756                                {
 7757                                    let worktree_id = tree.read(cx).id();
 7758                                    SymbolLocation::InProject(ProjectPath {
 7759                                        worktree_id,
 7760                                        path: rel_path,
 7761                                    })
 7762                                } else {
 7763                                    SymbolLocation::OutsideProject {
 7764                                        signature: this.symbol_signature(&abs_path),
 7765                                        abs_path: abs_path.into(),
 7766                                    }
 7767                                };
 7768
 7769                                Some(CoreSymbol {
 7770                                    source_language_server_id: result.server_id,
 7771                                    language_server_name: result.lsp_adapter.name.clone(),
 7772                                    source_worktree_id,
 7773                                    path,
 7774                                    kind: symbol_kind,
 7775                                    name: symbol_name,
 7776                                    range: range_from_lsp(symbol_location.range),
 7777                                })
 7778                            })
 7779                            .collect()
 7780                    })?;
 7781
 7782                    populate_labels_for_symbols(
 7783                        core_symbols,
 7784                        &language_registry,
 7785                        Some(result.lsp_adapter),
 7786                        &mut symbols,
 7787                    )
 7788                    .await;
 7789                }
 7790
 7791                Ok(symbols)
 7792            })
 7793        } else {
 7794            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7795        }
 7796    }
 7797
 7798    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7799        let mut summary = DiagnosticSummary::default();
 7800        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7801            summary.error_count += path_summary.error_count;
 7802            summary.warning_count += path_summary.warning_count;
 7803        }
 7804        summary
 7805    }
 7806
 7807    /// Returns the diagnostic summary for a specific project path.
 7808    pub fn diagnostic_summary_for_path(
 7809        &self,
 7810        project_path: &ProjectPath,
 7811        _: &App,
 7812    ) -> DiagnosticSummary {
 7813        if let Some(summaries) = self
 7814            .diagnostic_summaries
 7815            .get(&project_path.worktree_id)
 7816            .and_then(|map| map.get(&project_path.path))
 7817        {
 7818            let (error_count, warning_count) = summaries.iter().fold(
 7819                (0, 0),
 7820                |(error_count, warning_count), (_language_server_id, summary)| {
 7821                    (
 7822                        error_count + summary.error_count,
 7823                        warning_count + summary.warning_count,
 7824                    )
 7825                },
 7826            );
 7827
 7828            DiagnosticSummary {
 7829                error_count,
 7830                warning_count,
 7831            }
 7832        } else {
 7833            DiagnosticSummary::default()
 7834        }
 7835    }
 7836
 7837    pub fn diagnostic_summaries<'a>(
 7838        &'a self,
 7839        include_ignored: bool,
 7840        cx: &'a App,
 7841    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7842        self.worktree_store
 7843            .read(cx)
 7844            .visible_worktrees(cx)
 7845            .filter_map(|worktree| {
 7846                let worktree = worktree.read(cx);
 7847                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7848            })
 7849            .flat_map(move |(worktree, summaries)| {
 7850                let worktree_id = worktree.id();
 7851                summaries
 7852                    .iter()
 7853                    .filter(move |(path, _)| {
 7854                        include_ignored
 7855                            || worktree
 7856                                .entry_for_path(path.as_ref())
 7857                                .is_some_and(|entry| !entry.is_ignored)
 7858                    })
 7859                    .flat_map(move |(path, summaries)| {
 7860                        summaries.iter().map(move |(server_id, summary)| {
 7861                            (
 7862                                ProjectPath {
 7863                                    worktree_id,
 7864                                    path: path.clone(),
 7865                                },
 7866                                *server_id,
 7867                                *summary,
 7868                            )
 7869                        })
 7870                    })
 7871            })
 7872    }
 7873
 7874    pub fn on_buffer_edited(
 7875        &mut self,
 7876        buffer: Entity<Buffer>,
 7877        cx: &mut Context<Self>,
 7878    ) -> Option<()> {
 7879        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7880            Some(
 7881                self.as_local()?
 7882                    .language_servers_for_buffer(buffer, cx)
 7883                    .map(|i| i.1.clone())
 7884                    .collect(),
 7885            )
 7886        })?;
 7887
 7888        let buffer = buffer.read(cx);
 7889        let file = File::from_dyn(buffer.file())?;
 7890        let abs_path = file.as_local()?.abs_path(cx);
 7891        let uri = lsp::Uri::from_file_path(&abs_path)
 7892            .ok()
 7893            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7894            .log_err()?;
 7895        let next_snapshot = buffer.text_snapshot();
 7896        for language_server in language_servers {
 7897            let language_server = language_server.clone();
 7898
 7899            let buffer_snapshots = self
 7900                .as_local_mut()?
 7901                .buffer_snapshots
 7902                .get_mut(&buffer.remote_id())
 7903                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7904            let previous_snapshot = buffer_snapshots.last()?;
 7905
 7906            let build_incremental_change = || {
 7907                buffer
 7908                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7909                        previous_snapshot.snapshot.version(),
 7910                    )
 7911                    .map(|edit| {
 7912                        let edit_start = edit.new.start.0;
 7913                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7914                        let new_text = next_snapshot
 7915                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7916                            .collect();
 7917                        lsp::TextDocumentContentChangeEvent {
 7918                            range: Some(lsp::Range::new(
 7919                                point_to_lsp(edit_start),
 7920                                point_to_lsp(edit_end),
 7921                            )),
 7922                            range_length: None,
 7923                            text: new_text,
 7924                        }
 7925                    })
 7926                    .collect()
 7927            };
 7928
 7929            let document_sync_kind = language_server
 7930                .capabilities()
 7931                .text_document_sync
 7932                .as_ref()
 7933                .and_then(|sync| match sync {
 7934                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7935                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7936                });
 7937
 7938            let content_changes: Vec<_> = match document_sync_kind {
 7939                Some(lsp::TextDocumentSyncKind::FULL) => {
 7940                    vec![lsp::TextDocumentContentChangeEvent {
 7941                        range: None,
 7942                        range_length: None,
 7943                        text: next_snapshot.text(),
 7944                    }]
 7945                }
 7946                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7947                _ => {
 7948                    #[cfg(any(test, feature = "test-support"))]
 7949                    {
 7950                        build_incremental_change()
 7951                    }
 7952
 7953                    #[cfg(not(any(test, feature = "test-support")))]
 7954                    {
 7955                        continue;
 7956                    }
 7957                }
 7958            };
 7959
 7960            let next_version = previous_snapshot.version + 1;
 7961            buffer_snapshots.push(LspBufferSnapshot {
 7962                version: next_version,
 7963                snapshot: next_snapshot.clone(),
 7964            });
 7965
 7966            language_server
 7967                .notify::<lsp::notification::DidChangeTextDocument>(
 7968                    lsp::DidChangeTextDocumentParams {
 7969                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7970                            uri.clone(),
 7971                            next_version,
 7972                        ),
 7973                        content_changes,
 7974                    },
 7975                )
 7976                .ok();
 7977            self.pull_workspace_diagnostics(language_server.server_id());
 7978        }
 7979
 7980        None
 7981    }
 7982
 7983    pub fn on_buffer_saved(
 7984        &mut self,
 7985        buffer: Entity<Buffer>,
 7986        cx: &mut Context<Self>,
 7987    ) -> Option<()> {
 7988        let file = File::from_dyn(buffer.read(cx).file())?;
 7989        let worktree_id = file.worktree_id(cx);
 7990        let abs_path = file.as_local()?.abs_path(cx);
 7991        let text_document = lsp::TextDocumentIdentifier {
 7992            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7993        };
 7994        let local = self.as_local()?;
 7995
 7996        for server in local.language_servers_for_worktree(worktree_id) {
 7997            if let Some(include_text) = include_text(server.as_ref()) {
 7998                let text = if include_text {
 7999                    Some(buffer.read(cx).text())
 8000                } else {
 8001                    None
 8002                };
 8003                server
 8004                    .notify::<lsp::notification::DidSaveTextDocument>(
 8005                        lsp::DidSaveTextDocumentParams {
 8006                            text_document: text_document.clone(),
 8007                            text,
 8008                        },
 8009                    )
 8010                    .ok();
 8011            }
 8012        }
 8013
 8014        let language_servers = buffer.update(cx, |buffer, cx| {
 8015            local.language_server_ids_for_buffer(buffer, cx)
 8016        });
 8017        for language_server_id in language_servers {
 8018            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8019        }
 8020
 8021        None
 8022    }
 8023
 8024    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8025        maybe!(async move {
 8026            let mut refreshed_servers = HashSet::default();
 8027            let servers = lsp_store
 8028                .update(cx, |lsp_store, cx| {
 8029                    let local = lsp_store.as_local()?;
 8030
 8031                    let servers = local
 8032                        .language_server_ids
 8033                        .iter()
 8034                        .filter_map(|(seed, state)| {
 8035                            let worktree = lsp_store
 8036                                .worktree_store
 8037                                .read(cx)
 8038                                .worktree_for_id(seed.worktree_id, cx);
 8039                            let delegate: Arc<dyn LspAdapterDelegate> =
 8040                                worktree.map(|worktree| {
 8041                                    LocalLspAdapterDelegate::new(
 8042                                        local.languages.clone(),
 8043                                        &local.environment,
 8044                                        cx.weak_entity(),
 8045                                        &worktree,
 8046                                        local.http_client.clone(),
 8047                                        local.fs.clone(),
 8048                                        cx,
 8049                                    )
 8050                                })?;
 8051                            let server_id = state.id;
 8052
 8053                            let states = local.language_servers.get(&server_id)?;
 8054
 8055                            match states {
 8056                                LanguageServerState::Starting { .. } => None,
 8057                                LanguageServerState::Running {
 8058                                    adapter, server, ..
 8059                                } => {
 8060                                    let adapter = adapter.clone();
 8061                                    let server = server.clone();
 8062                                    refreshed_servers.insert(server.name());
 8063                                    let toolchain = seed.toolchain.clone();
 8064                                    Some(cx.spawn(async move |_, cx| {
 8065                                        let settings =
 8066                                            LocalLspStore::workspace_configuration_for_adapter(
 8067                                                adapter.adapter.clone(),
 8068                                                &delegate,
 8069                                                toolchain,
 8070                                                None,
 8071                                                cx,
 8072                                            )
 8073                                            .await
 8074                                            .ok()?;
 8075                                        server
 8076                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8077                                                lsp::DidChangeConfigurationParams { settings },
 8078                                            )
 8079                                            .ok()?;
 8080                                        Some(())
 8081                                    }))
 8082                                }
 8083                            }
 8084                        })
 8085                        .collect::<Vec<_>>();
 8086
 8087                    Some(servers)
 8088                })
 8089                .ok()
 8090                .flatten()?;
 8091
 8092            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8093            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8094            // to stop and unregister its language server wrapper.
 8095            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8096            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8097            let _: Vec<Option<()>> = join_all(servers).await;
 8098
 8099            Some(())
 8100        })
 8101        .await;
 8102    }
 8103
 8104    fn maintain_workspace_config(
 8105        external_refresh_requests: watch::Receiver<()>,
 8106        cx: &mut Context<Self>,
 8107    ) -> Task<Result<()>> {
 8108        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8109        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8110
 8111        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8112            *settings_changed_tx.borrow_mut() = ();
 8113        });
 8114
 8115        let mut joint_future =
 8116            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8117        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8118        // - 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).
 8119        // - 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.
 8120        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8121        // - 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,
 8122        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8123        cx.spawn(async move |this, cx| {
 8124            while let Some(()) = joint_future.next().await {
 8125                this.update(cx, |this, cx| {
 8126                    this.refresh_server_tree(cx);
 8127                })
 8128                .ok();
 8129
 8130                Self::refresh_workspace_configurations(&this, cx).await;
 8131            }
 8132
 8133            drop(settings_observation);
 8134            anyhow::Ok(())
 8135        })
 8136    }
 8137
 8138    pub fn running_language_servers_for_local_buffer<'a>(
 8139        &'a self,
 8140        buffer: &Buffer,
 8141        cx: &mut App,
 8142    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8143        let local = self.as_local();
 8144        let language_server_ids = local
 8145            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8146            .unwrap_or_default();
 8147
 8148        language_server_ids
 8149            .into_iter()
 8150            .filter_map(
 8151                move |server_id| match local?.language_servers.get(&server_id)? {
 8152                    LanguageServerState::Running {
 8153                        adapter, server, ..
 8154                    } => Some((adapter, server)),
 8155                    _ => None,
 8156                },
 8157            )
 8158    }
 8159
 8160    pub fn language_servers_for_local_buffer(
 8161        &self,
 8162        buffer: &Buffer,
 8163        cx: &mut App,
 8164    ) -> Vec<LanguageServerId> {
 8165        let local = self.as_local();
 8166        local
 8167            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8168            .unwrap_or_default()
 8169    }
 8170
 8171    pub fn language_server_for_local_buffer<'a>(
 8172        &'a self,
 8173        buffer: &'a Buffer,
 8174        server_id: LanguageServerId,
 8175        cx: &'a mut App,
 8176    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8177        self.as_local()?
 8178            .language_servers_for_buffer(buffer, cx)
 8179            .find(|(_, s)| s.server_id() == server_id)
 8180    }
 8181
 8182    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8183        self.diagnostic_summaries.remove(&id_to_remove);
 8184        if let Some(local) = self.as_local_mut() {
 8185            let to_remove = local.remove_worktree(id_to_remove, cx);
 8186            for server in to_remove {
 8187                self.language_server_statuses.remove(&server);
 8188            }
 8189        }
 8190    }
 8191
 8192    pub fn shared(
 8193        &mut self,
 8194        project_id: u64,
 8195        downstream_client: AnyProtoClient,
 8196        _: &mut Context<Self>,
 8197    ) {
 8198        self.downstream_client = Some((downstream_client.clone(), project_id));
 8199
 8200        for (server_id, status) in &self.language_server_statuses {
 8201            if let Some(server) = self.language_server_for_id(*server_id) {
 8202                downstream_client
 8203                    .send(proto::StartLanguageServer {
 8204                        project_id,
 8205                        server: Some(proto::LanguageServer {
 8206                            id: server_id.to_proto(),
 8207                            name: status.name.to_string(),
 8208                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8209                        }),
 8210                        capabilities: serde_json::to_string(&server.capabilities())
 8211                            .expect("serializing server LSP capabilities"),
 8212                    })
 8213                    .log_err();
 8214            }
 8215        }
 8216    }
 8217
 8218    pub fn disconnected_from_host(&mut self) {
 8219        self.downstream_client.take();
 8220    }
 8221
 8222    pub fn disconnected_from_ssh_remote(&mut self) {
 8223        if let LspStoreMode::Remote(RemoteLspStore {
 8224            upstream_client, ..
 8225        }) = &mut self.mode
 8226        {
 8227            upstream_client.take();
 8228        }
 8229    }
 8230
 8231    pub(crate) fn set_language_server_statuses_from_proto(
 8232        &mut self,
 8233        project: WeakEntity<Project>,
 8234        language_servers: Vec<proto::LanguageServer>,
 8235        server_capabilities: Vec<String>,
 8236        cx: &mut Context<Self>,
 8237    ) {
 8238        let lsp_logs = cx
 8239            .try_global::<GlobalLogStore>()
 8240            .map(|lsp_store| lsp_store.0.clone());
 8241
 8242        self.language_server_statuses = language_servers
 8243            .into_iter()
 8244            .zip(server_capabilities)
 8245            .map(|(server, server_capabilities)| {
 8246                let server_id = LanguageServerId(server.id as usize);
 8247                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8248                    self.lsp_server_capabilities
 8249                        .insert(server_id, server_capabilities);
 8250                }
 8251
 8252                let name = LanguageServerName::from_proto(server.name);
 8253                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8254
 8255                if let Some(lsp_logs) = &lsp_logs {
 8256                    lsp_logs.update(cx, |lsp_logs, cx| {
 8257                        lsp_logs.add_language_server(
 8258                            // Only remote clients get their language servers set from proto
 8259                            LanguageServerKind::Remote {
 8260                                project: project.clone(),
 8261                            },
 8262                            server_id,
 8263                            Some(name.clone()),
 8264                            worktree,
 8265                            None,
 8266                            cx,
 8267                        );
 8268                    });
 8269                }
 8270
 8271                (
 8272                    server_id,
 8273                    LanguageServerStatus {
 8274                        name,
 8275                        pending_work: Default::default(),
 8276                        has_pending_diagnostic_updates: false,
 8277                        progress_tokens: Default::default(),
 8278                        worktree,
 8279                        binary: None,
 8280                        configuration: None,
 8281                        workspace_folders: BTreeSet::new(),
 8282                    },
 8283                )
 8284            })
 8285            .collect();
 8286    }
 8287
 8288    #[cfg(test)]
 8289    pub fn update_diagnostic_entries(
 8290        &mut self,
 8291        server_id: LanguageServerId,
 8292        abs_path: PathBuf,
 8293        result_id: Option<SharedString>,
 8294        version: Option<i32>,
 8295        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8296        cx: &mut Context<Self>,
 8297    ) -> anyhow::Result<()> {
 8298        self.merge_diagnostic_entries(
 8299            vec![DocumentDiagnosticsUpdate {
 8300                diagnostics: DocumentDiagnostics {
 8301                    diagnostics,
 8302                    document_abs_path: abs_path,
 8303                    version,
 8304                },
 8305                result_id,
 8306                server_id,
 8307                disk_based_sources: Cow::Borrowed(&[]),
 8308                registration_id: None,
 8309            }],
 8310            |_, _, _| false,
 8311            cx,
 8312        )?;
 8313        Ok(())
 8314    }
 8315
 8316    pub fn merge_diagnostic_entries<'a>(
 8317        &mut self,
 8318        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8319        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8320        cx: &mut Context<Self>,
 8321    ) -> anyhow::Result<()> {
 8322        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8323        let mut updated_diagnostics_paths = HashMap::default();
 8324        for mut update in diagnostic_updates {
 8325            let abs_path = &update.diagnostics.document_abs_path;
 8326            let server_id = update.server_id;
 8327            let Some((worktree, relative_path)) =
 8328                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8329            else {
 8330                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8331                return Ok(());
 8332            };
 8333
 8334            let worktree_id = worktree.read(cx).id();
 8335            let project_path = ProjectPath {
 8336                worktree_id,
 8337                path: relative_path,
 8338            };
 8339
 8340            let document_uri = lsp::Uri::from_file_path(abs_path)
 8341                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8342            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8343                let snapshot = buffer_handle.read(cx).snapshot();
 8344                let buffer = buffer_handle.read(cx);
 8345                let reused_diagnostics = buffer
 8346                    .buffer_diagnostics(Some(server_id))
 8347                    .iter()
 8348                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8349                    .map(|v| {
 8350                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8351                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8352                        DiagnosticEntry {
 8353                            range: start..end,
 8354                            diagnostic: v.diagnostic.clone(),
 8355                        }
 8356                    })
 8357                    .collect::<Vec<_>>();
 8358
 8359                self.as_local_mut()
 8360                    .context("cannot merge diagnostics on a remote LspStore")?
 8361                    .update_buffer_diagnostics(
 8362                        &buffer_handle,
 8363                        server_id,
 8364                        Some(update.registration_id),
 8365                        update.result_id,
 8366                        update.diagnostics.version,
 8367                        update.diagnostics.diagnostics.clone(),
 8368                        reused_diagnostics.clone(),
 8369                        cx,
 8370                    )?;
 8371
 8372                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8373            } else if let Some(local) = self.as_local() {
 8374                let reused_diagnostics = local
 8375                    .diagnostics
 8376                    .get(&worktree_id)
 8377                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8378                    .and_then(|diagnostics_by_server_id| {
 8379                        diagnostics_by_server_id
 8380                            .binary_search_by_key(&server_id, |e| e.0)
 8381                            .ok()
 8382                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8383                    })
 8384                    .into_iter()
 8385                    .flatten()
 8386                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8387
 8388                update
 8389                    .diagnostics
 8390                    .diagnostics
 8391                    .extend(reused_diagnostics.cloned());
 8392            }
 8393
 8394            let updated = worktree.update(cx, |worktree, cx| {
 8395                self.update_worktree_diagnostics(
 8396                    worktree.id(),
 8397                    server_id,
 8398                    project_path.path.clone(),
 8399                    update.diagnostics.diagnostics,
 8400                    cx,
 8401                )
 8402            })?;
 8403            match updated {
 8404                ControlFlow::Continue(new_summary) => {
 8405                    if let Some((project_id, new_summary)) = new_summary {
 8406                        match &mut diagnostics_summary {
 8407                            Some(diagnostics_summary) => {
 8408                                diagnostics_summary
 8409                                    .more_summaries
 8410                                    .push(proto::DiagnosticSummary {
 8411                                        path: project_path.path.as_ref().to_proto(),
 8412                                        language_server_id: server_id.0 as u64,
 8413                                        error_count: new_summary.error_count,
 8414                                        warning_count: new_summary.warning_count,
 8415                                    })
 8416                            }
 8417                            None => {
 8418                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8419                                    project_id,
 8420                                    worktree_id: worktree_id.to_proto(),
 8421                                    summary: Some(proto::DiagnosticSummary {
 8422                                        path: project_path.path.as_ref().to_proto(),
 8423                                        language_server_id: server_id.0 as u64,
 8424                                        error_count: new_summary.error_count,
 8425                                        warning_count: new_summary.warning_count,
 8426                                    }),
 8427                                    more_summaries: Vec::new(),
 8428                                })
 8429                            }
 8430                        }
 8431                    }
 8432                    updated_diagnostics_paths
 8433                        .entry(server_id)
 8434                        .or_insert_with(Vec::new)
 8435                        .push(project_path);
 8436                }
 8437                ControlFlow::Break(()) => {}
 8438            }
 8439        }
 8440
 8441        if let Some((diagnostics_summary, (downstream_client, _))) =
 8442            diagnostics_summary.zip(self.downstream_client.as_ref())
 8443        {
 8444            downstream_client.send(diagnostics_summary).log_err();
 8445        }
 8446        for (server_id, paths) in updated_diagnostics_paths {
 8447            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8448        }
 8449        Ok(())
 8450    }
 8451
 8452    fn update_worktree_diagnostics(
 8453        &mut self,
 8454        worktree_id: WorktreeId,
 8455        server_id: LanguageServerId,
 8456        path_in_worktree: Arc<RelPath>,
 8457        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8458        _: &mut Context<Worktree>,
 8459    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8460        let local = match &mut self.mode {
 8461            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8462            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8463        };
 8464
 8465        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8466        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8467        let summaries_by_server_id = summaries_for_tree
 8468            .entry(path_in_worktree.clone())
 8469            .or_default();
 8470
 8471        let old_summary = summaries_by_server_id
 8472            .remove(&server_id)
 8473            .unwrap_or_default();
 8474
 8475        let new_summary = DiagnosticSummary::new(&diagnostics);
 8476        if diagnostics.is_empty() {
 8477            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8478            {
 8479                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8480                    diagnostics_by_server_id.remove(ix);
 8481                }
 8482                if diagnostics_by_server_id.is_empty() {
 8483                    diagnostics_for_tree.remove(&path_in_worktree);
 8484                }
 8485            }
 8486        } else {
 8487            summaries_by_server_id.insert(server_id, new_summary);
 8488            let diagnostics_by_server_id = diagnostics_for_tree
 8489                .entry(path_in_worktree.clone())
 8490                .or_default();
 8491            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8492                Ok(ix) => {
 8493                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8494                }
 8495                Err(ix) => {
 8496                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8497                }
 8498            }
 8499        }
 8500
 8501        if !old_summary.is_empty() || !new_summary.is_empty() {
 8502            if let Some((_, project_id)) = &self.downstream_client {
 8503                Ok(ControlFlow::Continue(Some((
 8504                    *project_id,
 8505                    proto::DiagnosticSummary {
 8506                        path: path_in_worktree.to_proto(),
 8507                        language_server_id: server_id.0 as u64,
 8508                        error_count: new_summary.error_count as u32,
 8509                        warning_count: new_summary.warning_count as u32,
 8510                    },
 8511                ))))
 8512            } else {
 8513                Ok(ControlFlow::Continue(None))
 8514            }
 8515        } else {
 8516            Ok(ControlFlow::Break(()))
 8517        }
 8518    }
 8519
 8520    pub fn open_buffer_for_symbol(
 8521        &mut self,
 8522        symbol: &Symbol,
 8523        cx: &mut Context<Self>,
 8524    ) -> Task<Result<Entity<Buffer>>> {
 8525        if let Some((client, project_id)) = self.upstream_client() {
 8526            let request = client.request(proto::OpenBufferForSymbol {
 8527                project_id,
 8528                symbol: Some(Self::serialize_symbol(symbol)),
 8529            });
 8530            cx.spawn(async move |this, cx| {
 8531                let response = request.await?;
 8532                let buffer_id = BufferId::new(response.buffer_id)?;
 8533                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8534                    .await
 8535            })
 8536        } else if let Some(local) = self.as_local() {
 8537            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8538                seed.worktree_id == symbol.source_worktree_id
 8539                    && state.id == symbol.source_language_server_id
 8540                    && symbol.language_server_name == seed.name
 8541            });
 8542            if !is_valid {
 8543                return Task::ready(Err(anyhow!(
 8544                    "language server for worktree and language not found"
 8545                )));
 8546            };
 8547
 8548            let symbol_abs_path = match &symbol.path {
 8549                SymbolLocation::InProject(project_path) => self
 8550                    .worktree_store
 8551                    .read(cx)
 8552                    .absolutize(&project_path, cx)
 8553                    .context("no such worktree"),
 8554                SymbolLocation::OutsideProject {
 8555                    abs_path,
 8556                    signature: _,
 8557                } => Ok(abs_path.to_path_buf()),
 8558            };
 8559            let symbol_abs_path = match symbol_abs_path {
 8560                Ok(abs_path) => abs_path,
 8561                Err(err) => return Task::ready(Err(err)),
 8562            };
 8563            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8564                uri
 8565            } else {
 8566                return Task::ready(Err(anyhow!("invalid symbol path")));
 8567            };
 8568
 8569            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8570        } else {
 8571            Task::ready(Err(anyhow!("no upstream client or local store")))
 8572        }
 8573    }
 8574
 8575    pub(crate) fn open_local_buffer_via_lsp(
 8576        &mut self,
 8577        abs_path: lsp::Uri,
 8578        language_server_id: LanguageServerId,
 8579        cx: &mut Context<Self>,
 8580    ) -> Task<Result<Entity<Buffer>>> {
 8581        cx.spawn(async move |lsp_store, cx| {
 8582            // Escape percent-encoded string.
 8583            let current_scheme = abs_path.scheme().to_owned();
 8584            // Uri is immutable, so we can't modify the scheme
 8585
 8586            let abs_path = abs_path
 8587                .to_file_path()
 8588                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8589            let p = abs_path.clone();
 8590            let yarn_worktree = lsp_store
 8591                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8592                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8593                        cx.spawn(async move |this, cx| {
 8594                            let t = this
 8595                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8596                                .ok()?;
 8597                            t.await
 8598                        })
 8599                    }),
 8600                    None => Task::ready(None),
 8601                })?
 8602                .await;
 8603            let (worktree_root_target, known_relative_path) =
 8604                if let Some((zip_root, relative_path)) = yarn_worktree {
 8605                    (zip_root, Some(relative_path))
 8606                } else {
 8607                    (Arc::<Path>::from(abs_path.as_path()), None)
 8608                };
 8609            let (worktree, relative_path) = if let Some(result) =
 8610                lsp_store.update(cx, |lsp_store, cx| {
 8611                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8612                        worktree_store.find_worktree(&worktree_root_target, cx)
 8613                    })
 8614                })? {
 8615                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8616                (result.0, relative_path)
 8617            } else {
 8618                let worktree = lsp_store
 8619                    .update(cx, |lsp_store, cx| {
 8620                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8621                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8622                        })
 8623                    })?
 8624                    .await?;
 8625                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8626                    lsp_store
 8627                        .update(cx, |lsp_store, cx| {
 8628                            if let Some(local) = lsp_store.as_local_mut() {
 8629                                local.register_language_server_for_invisible_worktree(
 8630                                    &worktree,
 8631                                    language_server_id,
 8632                                    cx,
 8633                                )
 8634                            }
 8635                        })
 8636                        .ok();
 8637                }
 8638                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8639                let relative_path = if let Some(known_path) = known_relative_path {
 8640                    known_path
 8641                } else {
 8642                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8643                        .into_arc()
 8644                };
 8645                (worktree, relative_path)
 8646            };
 8647            let project_path = ProjectPath {
 8648                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8649                path: relative_path,
 8650            };
 8651            lsp_store
 8652                .update(cx, |lsp_store, cx| {
 8653                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8654                        buffer_store.open_buffer(project_path, cx)
 8655                    })
 8656                })?
 8657                .await
 8658        })
 8659    }
 8660
 8661    fn request_multiple_lsp_locally<P, R>(
 8662        &mut self,
 8663        buffer: &Entity<Buffer>,
 8664        position: Option<P>,
 8665        request: R,
 8666        cx: &mut Context<Self>,
 8667    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8668    where
 8669        P: ToOffset,
 8670        R: LspCommand + Clone,
 8671        <R::LspRequest as lsp::request::Request>::Result: Send,
 8672        <R::LspRequest as lsp::request::Request>::Params: Send,
 8673    {
 8674        let Some(local) = self.as_local() else {
 8675            return Task::ready(Vec::new());
 8676        };
 8677
 8678        let snapshot = buffer.read(cx).snapshot();
 8679        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8680
 8681        let server_ids = buffer.update(cx, |buffer, cx| {
 8682            local
 8683                .language_servers_for_buffer(buffer, cx)
 8684                .filter(|(adapter, _)| {
 8685                    scope
 8686                        .as_ref()
 8687                        .map(|scope| scope.language_allowed(&adapter.name))
 8688                        .unwrap_or(true)
 8689                })
 8690                .map(|(_, server)| server.server_id())
 8691                .filter(|server_id| {
 8692                    self.as_local().is_none_or(|local| {
 8693                        local
 8694                            .buffers_opened_in_servers
 8695                            .get(&snapshot.remote_id())
 8696                            .is_some_and(|servers| servers.contains(server_id))
 8697                    })
 8698                })
 8699                .collect::<Vec<_>>()
 8700        });
 8701
 8702        let mut response_results = server_ids
 8703            .into_iter()
 8704            .map(|server_id| {
 8705                let task = self.request_lsp(
 8706                    buffer.clone(),
 8707                    LanguageServerToQuery::Other(server_id),
 8708                    request.clone(),
 8709                    cx,
 8710                );
 8711                async move { (server_id, task.await) }
 8712            })
 8713            .collect::<FuturesUnordered<_>>();
 8714
 8715        cx.background_spawn(async move {
 8716            let mut responses = Vec::with_capacity(response_results.len());
 8717            while let Some((server_id, response_result)) = response_results.next().await {
 8718                match response_result {
 8719                    Ok(response) => responses.push((server_id, response)),
 8720                    // rust-analyzer likes to error with this when its still loading up
 8721                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8722                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8723                }
 8724            }
 8725            responses
 8726        })
 8727    }
 8728
 8729    async fn handle_lsp_get_completions(
 8730        this: Entity<Self>,
 8731        envelope: TypedEnvelope<proto::GetCompletions>,
 8732        mut cx: AsyncApp,
 8733    ) -> Result<proto::GetCompletionsResponse> {
 8734        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8735
 8736        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8737        let buffer_handle = this.update(&mut cx, |this, cx| {
 8738            this.buffer_store.read(cx).get_existing(buffer_id)
 8739        })??;
 8740        let request = GetCompletions::from_proto(
 8741            envelope.payload,
 8742            this.clone(),
 8743            buffer_handle.clone(),
 8744            cx.clone(),
 8745        )
 8746        .await?;
 8747
 8748        let server_to_query = match request.server_id {
 8749            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8750            None => LanguageServerToQuery::FirstCapable,
 8751        };
 8752
 8753        let response = this
 8754            .update(&mut cx, |this, cx| {
 8755                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8756            })?
 8757            .await?;
 8758        this.update(&mut cx, |this, cx| {
 8759            Ok(GetCompletions::response_to_proto(
 8760                response,
 8761                this,
 8762                sender_id,
 8763                &buffer_handle.read(cx).version(),
 8764                cx,
 8765            ))
 8766        })?
 8767    }
 8768
 8769    async fn handle_lsp_command<T: LspCommand>(
 8770        this: Entity<Self>,
 8771        envelope: TypedEnvelope<T::ProtoRequest>,
 8772        mut cx: AsyncApp,
 8773    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8774    where
 8775        <T::LspRequest as lsp::request::Request>::Params: Send,
 8776        <T::LspRequest as lsp::request::Request>::Result: Send,
 8777    {
 8778        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8779        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8780        let buffer_handle = this.update(&mut cx, |this, cx| {
 8781            this.buffer_store.read(cx).get_existing(buffer_id)
 8782        })??;
 8783        let request = T::from_proto(
 8784            envelope.payload,
 8785            this.clone(),
 8786            buffer_handle.clone(),
 8787            cx.clone(),
 8788        )
 8789        .await?;
 8790        let response = this
 8791            .update(&mut cx, |this, cx| {
 8792                this.request_lsp(
 8793                    buffer_handle.clone(),
 8794                    LanguageServerToQuery::FirstCapable,
 8795                    request,
 8796                    cx,
 8797                )
 8798            })?
 8799            .await?;
 8800        this.update(&mut cx, |this, cx| {
 8801            Ok(T::response_to_proto(
 8802                response,
 8803                this,
 8804                sender_id,
 8805                &buffer_handle.read(cx).version(),
 8806                cx,
 8807            ))
 8808        })?
 8809    }
 8810
 8811    async fn handle_lsp_query(
 8812        lsp_store: Entity<Self>,
 8813        envelope: TypedEnvelope<proto::LspQuery>,
 8814        mut cx: AsyncApp,
 8815    ) -> Result<proto::Ack> {
 8816        use proto::lsp_query::Request;
 8817        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8818        let lsp_query = envelope.payload;
 8819        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8820        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8821        match lsp_query.request.context("invalid LSP query request")? {
 8822            Request::GetReferences(get_references) => {
 8823                let position = get_references.position.clone().and_then(deserialize_anchor);
 8824                Self::query_lsp_locally::<GetReferences>(
 8825                    lsp_store,
 8826                    server_id,
 8827                    sender_id,
 8828                    lsp_request_id,
 8829                    get_references,
 8830                    position,
 8831                    &mut cx,
 8832                )
 8833                .await?;
 8834            }
 8835            Request::GetDocumentColor(get_document_color) => {
 8836                Self::query_lsp_locally::<GetDocumentColor>(
 8837                    lsp_store,
 8838                    server_id,
 8839                    sender_id,
 8840                    lsp_request_id,
 8841                    get_document_color,
 8842                    None,
 8843                    &mut cx,
 8844                )
 8845                .await?;
 8846            }
 8847            Request::GetHover(get_hover) => {
 8848                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8849                Self::query_lsp_locally::<GetHover>(
 8850                    lsp_store,
 8851                    server_id,
 8852                    sender_id,
 8853                    lsp_request_id,
 8854                    get_hover,
 8855                    position,
 8856                    &mut cx,
 8857                )
 8858                .await?;
 8859            }
 8860            Request::GetCodeActions(get_code_actions) => {
 8861                Self::query_lsp_locally::<GetCodeActions>(
 8862                    lsp_store,
 8863                    server_id,
 8864                    sender_id,
 8865                    lsp_request_id,
 8866                    get_code_actions,
 8867                    None,
 8868                    &mut cx,
 8869                )
 8870                .await?;
 8871            }
 8872            Request::GetSignatureHelp(get_signature_help) => {
 8873                let position = get_signature_help
 8874                    .position
 8875                    .clone()
 8876                    .and_then(deserialize_anchor);
 8877                Self::query_lsp_locally::<GetSignatureHelp>(
 8878                    lsp_store,
 8879                    server_id,
 8880                    sender_id,
 8881                    lsp_request_id,
 8882                    get_signature_help,
 8883                    position,
 8884                    &mut cx,
 8885                )
 8886                .await?;
 8887            }
 8888            Request::GetCodeLens(get_code_lens) => {
 8889                Self::query_lsp_locally::<GetCodeLens>(
 8890                    lsp_store,
 8891                    server_id,
 8892                    sender_id,
 8893                    lsp_request_id,
 8894                    get_code_lens,
 8895                    None,
 8896                    &mut cx,
 8897                )
 8898                .await?;
 8899            }
 8900            Request::GetDefinition(get_definition) => {
 8901                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8902                Self::query_lsp_locally::<GetDefinitions>(
 8903                    lsp_store,
 8904                    server_id,
 8905                    sender_id,
 8906                    lsp_request_id,
 8907                    get_definition,
 8908                    position,
 8909                    &mut cx,
 8910                )
 8911                .await?;
 8912            }
 8913            Request::GetDeclaration(get_declaration) => {
 8914                let position = get_declaration
 8915                    .position
 8916                    .clone()
 8917                    .and_then(deserialize_anchor);
 8918                Self::query_lsp_locally::<GetDeclarations>(
 8919                    lsp_store,
 8920                    server_id,
 8921                    sender_id,
 8922                    lsp_request_id,
 8923                    get_declaration,
 8924                    position,
 8925                    &mut cx,
 8926                )
 8927                .await?;
 8928            }
 8929            Request::GetTypeDefinition(get_type_definition) => {
 8930                let position = get_type_definition
 8931                    .position
 8932                    .clone()
 8933                    .and_then(deserialize_anchor);
 8934                Self::query_lsp_locally::<GetTypeDefinitions>(
 8935                    lsp_store,
 8936                    server_id,
 8937                    sender_id,
 8938                    lsp_request_id,
 8939                    get_type_definition,
 8940                    position,
 8941                    &mut cx,
 8942                )
 8943                .await?;
 8944            }
 8945            Request::GetImplementation(get_implementation) => {
 8946                let position = get_implementation
 8947                    .position
 8948                    .clone()
 8949                    .and_then(deserialize_anchor);
 8950                Self::query_lsp_locally::<GetImplementations>(
 8951                    lsp_store,
 8952                    server_id,
 8953                    sender_id,
 8954                    lsp_request_id,
 8955                    get_implementation,
 8956                    position,
 8957                    &mut cx,
 8958                )
 8959                .await?;
 8960            }
 8961            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8962                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8963                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8964                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8965                    this.buffer_store.read(cx).get_existing(buffer_id)
 8966                })??;
 8967                buffer
 8968                    .update(&mut cx, |buffer, _| {
 8969                        buffer.wait_for_version(version.clone())
 8970                    })?
 8971                    .await?;
 8972                lsp_store.update(&mut cx, |lsp_store, cx| {
 8973                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8974                    let key = LspKey {
 8975                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8976                        server_queried: server_id,
 8977                    };
 8978                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8979                    ) {
 8980                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8981                            lsp_requests.clear();
 8982                        };
 8983                    }
 8984
 8985                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8986                    existing_queries.insert(
 8987                        lsp_request_id,
 8988                        cx.spawn(async move |lsp_store, cx| {
 8989                            let diagnostics_pull = lsp_store
 8990                                .update(cx, |lsp_store, cx| {
 8991                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8992                                })
 8993                                .ok();
 8994                            if let Some(diagnostics_pull) = diagnostics_pull {
 8995                                match diagnostics_pull.await {
 8996                                    Ok(()) => {}
 8997                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8998                                };
 8999                            }
 9000                        }),
 9001                    );
 9002                })?;
 9003            }
 9004            Request::InlayHints(inlay_hints) => {
 9005                let query_start = inlay_hints
 9006                    .start
 9007                    .clone()
 9008                    .and_then(deserialize_anchor)
 9009                    .context("invalid inlay hints range start")?;
 9010                let query_end = inlay_hints
 9011                    .end
 9012                    .clone()
 9013                    .and_then(deserialize_anchor)
 9014                    .context("invalid inlay hints range end")?;
 9015                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9016                    &lsp_store,
 9017                    server_id,
 9018                    lsp_request_id,
 9019                    &inlay_hints,
 9020                    query_start..query_end,
 9021                    &mut cx,
 9022                )
 9023                .await
 9024                .context("preparing inlay hints request")?;
 9025                Self::query_lsp_locally::<InlayHints>(
 9026                    lsp_store,
 9027                    server_id,
 9028                    sender_id,
 9029                    lsp_request_id,
 9030                    inlay_hints,
 9031                    None,
 9032                    &mut cx,
 9033                )
 9034                .await
 9035                .context("querying for inlay hints")?
 9036            }
 9037        }
 9038        Ok(proto::Ack {})
 9039    }
 9040
 9041    async fn handle_lsp_query_response(
 9042        lsp_store: Entity<Self>,
 9043        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9044        cx: AsyncApp,
 9045    ) -> Result<()> {
 9046        lsp_store.read_with(&cx, |lsp_store, _| {
 9047            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9048                upstream_client.handle_lsp_response(envelope.clone());
 9049            }
 9050        })?;
 9051        Ok(())
 9052    }
 9053
 9054    async fn handle_apply_code_action(
 9055        this: Entity<Self>,
 9056        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9057        mut cx: AsyncApp,
 9058    ) -> Result<proto::ApplyCodeActionResponse> {
 9059        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9060        let action =
 9061            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9062        let apply_code_action = this.update(&mut cx, |this, cx| {
 9063            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9064            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9065            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9066        })??;
 9067
 9068        let project_transaction = apply_code_action.await?;
 9069        let project_transaction = this.update(&mut cx, |this, cx| {
 9070            this.buffer_store.update(cx, |buffer_store, cx| {
 9071                buffer_store.serialize_project_transaction_for_peer(
 9072                    project_transaction,
 9073                    sender_id,
 9074                    cx,
 9075                )
 9076            })
 9077        })?;
 9078        Ok(proto::ApplyCodeActionResponse {
 9079            transaction: Some(project_transaction),
 9080        })
 9081    }
 9082
 9083    async fn handle_register_buffer_with_language_servers(
 9084        this: Entity<Self>,
 9085        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9086        mut cx: AsyncApp,
 9087    ) -> Result<proto::Ack> {
 9088        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9089        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9090        this.update(&mut cx, |this, cx| {
 9091            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9092                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9093                    project_id: upstream_project_id,
 9094                    buffer_id: buffer_id.to_proto(),
 9095                    only_servers: envelope.payload.only_servers,
 9096                });
 9097            }
 9098
 9099            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9100                anyhow::bail!("buffer is not open");
 9101            };
 9102
 9103            let handle = this.register_buffer_with_language_servers(
 9104                &buffer,
 9105                envelope
 9106                    .payload
 9107                    .only_servers
 9108                    .into_iter()
 9109                    .filter_map(|selector| {
 9110                        Some(match selector.selector? {
 9111                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9112                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9113                            }
 9114                            proto::language_server_selector::Selector::Name(name) => {
 9115                                LanguageServerSelector::Name(LanguageServerName(
 9116                                    SharedString::from(name),
 9117                                ))
 9118                            }
 9119                        })
 9120                    })
 9121                    .collect(),
 9122                false,
 9123                cx,
 9124            );
 9125            this.buffer_store().update(cx, |buffer_store, _| {
 9126                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9127            });
 9128
 9129            Ok(())
 9130        })??;
 9131        Ok(proto::Ack {})
 9132    }
 9133
 9134    async fn handle_rename_project_entry(
 9135        this: Entity<Self>,
 9136        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9137        mut cx: AsyncApp,
 9138    ) -> Result<proto::ProjectEntryResponse> {
 9139        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9140        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9141        let new_path =
 9142            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9143
 9144        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9145            .update(&mut cx, |this, cx| {
 9146                let (worktree, entry) = this
 9147                    .worktree_store
 9148                    .read(cx)
 9149                    .worktree_and_entry_for_id(entry_id, cx)?;
 9150                let new_worktree = this
 9151                    .worktree_store
 9152                    .read(cx)
 9153                    .worktree_for_id(new_worktree_id, cx)?;
 9154                Some((
 9155                    this.worktree_store.clone(),
 9156                    worktree,
 9157                    new_worktree,
 9158                    entry.clone(),
 9159                ))
 9160            })?
 9161            .context("worktree not found")?;
 9162        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9163            (worktree.absolutize(&old_entry.path), worktree.id())
 9164        })?;
 9165        let new_abs_path =
 9166            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9167
 9168        let _transaction = Self::will_rename_entry(
 9169            this.downgrade(),
 9170            old_worktree_id,
 9171            &old_abs_path,
 9172            &new_abs_path,
 9173            old_entry.is_dir(),
 9174            cx.clone(),
 9175        )
 9176        .await;
 9177        let response = WorktreeStore::handle_rename_project_entry(
 9178            worktree_store,
 9179            envelope.payload,
 9180            cx.clone(),
 9181        )
 9182        .await;
 9183        this.read_with(&cx, |this, _| {
 9184            this.did_rename_entry(
 9185                old_worktree_id,
 9186                &old_abs_path,
 9187                &new_abs_path,
 9188                old_entry.is_dir(),
 9189            );
 9190        })
 9191        .ok();
 9192        response
 9193    }
 9194
 9195    async fn handle_update_diagnostic_summary(
 9196        this: Entity<Self>,
 9197        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9198        mut cx: AsyncApp,
 9199    ) -> Result<()> {
 9200        this.update(&mut cx, |lsp_store, cx| {
 9201            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9202            let mut updated_diagnostics_paths = HashMap::default();
 9203            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9204            for message_summary in envelope
 9205                .payload
 9206                .summary
 9207                .into_iter()
 9208                .chain(envelope.payload.more_summaries)
 9209            {
 9210                let project_path = ProjectPath {
 9211                    worktree_id,
 9212                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9213                };
 9214                let path = project_path.path.clone();
 9215                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9216                let summary = DiagnosticSummary {
 9217                    error_count: message_summary.error_count as usize,
 9218                    warning_count: message_summary.warning_count as usize,
 9219                };
 9220
 9221                if summary.is_empty() {
 9222                    if let Some(worktree_summaries) =
 9223                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9224                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9225                    {
 9226                        summaries.remove(&server_id);
 9227                        if summaries.is_empty() {
 9228                            worktree_summaries.remove(&path);
 9229                        }
 9230                    }
 9231                } else {
 9232                    lsp_store
 9233                        .diagnostic_summaries
 9234                        .entry(worktree_id)
 9235                        .or_default()
 9236                        .entry(path)
 9237                        .or_default()
 9238                        .insert(server_id, summary);
 9239                }
 9240
 9241                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9242                    match &mut diagnostics_summary {
 9243                        Some(diagnostics_summary) => {
 9244                            diagnostics_summary
 9245                                .more_summaries
 9246                                .push(proto::DiagnosticSummary {
 9247                                    path: project_path.path.as_ref().to_proto(),
 9248                                    language_server_id: server_id.0 as u64,
 9249                                    error_count: summary.error_count as u32,
 9250                                    warning_count: summary.warning_count as u32,
 9251                                })
 9252                        }
 9253                        None => {
 9254                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9255                                project_id: *project_id,
 9256                                worktree_id: worktree_id.to_proto(),
 9257                                summary: Some(proto::DiagnosticSummary {
 9258                                    path: project_path.path.as_ref().to_proto(),
 9259                                    language_server_id: server_id.0 as u64,
 9260                                    error_count: summary.error_count as u32,
 9261                                    warning_count: summary.warning_count as u32,
 9262                                }),
 9263                                more_summaries: Vec::new(),
 9264                            })
 9265                        }
 9266                    }
 9267                }
 9268                updated_diagnostics_paths
 9269                    .entry(server_id)
 9270                    .or_insert_with(Vec::new)
 9271                    .push(project_path);
 9272            }
 9273
 9274            if let Some((diagnostics_summary, (downstream_client, _))) =
 9275                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9276            {
 9277                downstream_client.send(diagnostics_summary).log_err();
 9278            }
 9279            for (server_id, paths) in updated_diagnostics_paths {
 9280                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9281            }
 9282            Ok(())
 9283        })?
 9284    }
 9285
 9286    async fn handle_start_language_server(
 9287        lsp_store: Entity<Self>,
 9288        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9289        mut cx: AsyncApp,
 9290    ) -> Result<()> {
 9291        let server = envelope.payload.server.context("invalid server")?;
 9292        let server_capabilities =
 9293            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9294                .with_context(|| {
 9295                    format!(
 9296                        "incorrect server capabilities {}",
 9297                        envelope.payload.capabilities
 9298                    )
 9299                })?;
 9300        lsp_store.update(&mut cx, |lsp_store, cx| {
 9301            let server_id = LanguageServerId(server.id as usize);
 9302            let server_name = LanguageServerName::from_proto(server.name.clone());
 9303            lsp_store
 9304                .lsp_server_capabilities
 9305                .insert(server_id, server_capabilities);
 9306            lsp_store.language_server_statuses.insert(
 9307                server_id,
 9308                LanguageServerStatus {
 9309                    name: server_name.clone(),
 9310                    pending_work: Default::default(),
 9311                    has_pending_diagnostic_updates: false,
 9312                    progress_tokens: Default::default(),
 9313                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9314                    binary: None,
 9315                    configuration: None,
 9316                    workspace_folders: BTreeSet::new(),
 9317                },
 9318            );
 9319            cx.emit(LspStoreEvent::LanguageServerAdded(
 9320                server_id,
 9321                server_name,
 9322                server.worktree_id.map(WorktreeId::from_proto),
 9323            ));
 9324            cx.notify();
 9325        })?;
 9326        Ok(())
 9327    }
 9328
 9329    async fn handle_update_language_server(
 9330        lsp_store: Entity<Self>,
 9331        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9332        mut cx: AsyncApp,
 9333    ) -> Result<()> {
 9334        lsp_store.update(&mut cx, |lsp_store, cx| {
 9335            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9336
 9337            match envelope.payload.variant.context("invalid variant")? {
 9338                proto::update_language_server::Variant::WorkStart(payload) => {
 9339                    lsp_store.on_lsp_work_start(
 9340                        language_server_id,
 9341                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9342                            .context("invalid progress token value")?,
 9343                        LanguageServerProgress {
 9344                            title: payload.title,
 9345                            is_disk_based_diagnostics_progress: false,
 9346                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9347                            message: payload.message,
 9348                            percentage: payload.percentage.map(|p| p as usize),
 9349                            last_update_at: cx.background_executor().now(),
 9350                        },
 9351                        cx,
 9352                    );
 9353                }
 9354                proto::update_language_server::Variant::WorkProgress(payload) => {
 9355                    lsp_store.on_lsp_work_progress(
 9356                        language_server_id,
 9357                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9358                            .context("invalid progress token value")?,
 9359                        LanguageServerProgress {
 9360                            title: None,
 9361                            is_disk_based_diagnostics_progress: false,
 9362                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9363                            message: payload.message,
 9364                            percentage: payload.percentage.map(|p| p as usize),
 9365                            last_update_at: cx.background_executor().now(),
 9366                        },
 9367                        cx,
 9368                    );
 9369                }
 9370
 9371                proto::update_language_server::Variant::WorkEnd(payload) => {
 9372                    lsp_store.on_lsp_work_end(
 9373                        language_server_id,
 9374                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9375                            .context("invalid progress token value")?,
 9376                        cx,
 9377                    );
 9378                }
 9379
 9380                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9381                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9382                }
 9383
 9384                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9385                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9386                }
 9387
 9388                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9389                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9390                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9391                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9392                        language_server_id,
 9393                        name: envelope
 9394                            .payload
 9395                            .server_name
 9396                            .map(SharedString::new)
 9397                            .map(LanguageServerName),
 9398                        message: non_lsp,
 9399                    });
 9400                }
 9401            }
 9402
 9403            Ok(())
 9404        })?
 9405    }
 9406
 9407    async fn handle_language_server_log(
 9408        this: Entity<Self>,
 9409        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9410        mut cx: AsyncApp,
 9411    ) -> Result<()> {
 9412        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9413        let log_type = envelope
 9414            .payload
 9415            .log_type
 9416            .map(LanguageServerLogType::from_proto)
 9417            .context("invalid language server log type")?;
 9418
 9419        let message = envelope.payload.message;
 9420
 9421        this.update(&mut cx, |_, cx| {
 9422            cx.emit(LspStoreEvent::LanguageServerLog(
 9423                language_server_id,
 9424                log_type,
 9425                message,
 9426            ));
 9427        })
 9428    }
 9429
 9430    async fn handle_lsp_ext_cancel_flycheck(
 9431        lsp_store: Entity<Self>,
 9432        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9433        cx: AsyncApp,
 9434    ) -> Result<proto::Ack> {
 9435        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9436        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9437            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9438                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9439            } else {
 9440                None
 9441            }
 9442        })?;
 9443        if let Some(task) = task {
 9444            task.context("handling lsp ext cancel flycheck")?;
 9445        }
 9446
 9447        Ok(proto::Ack {})
 9448    }
 9449
 9450    async fn handle_lsp_ext_run_flycheck(
 9451        lsp_store: Entity<Self>,
 9452        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9453        mut cx: AsyncApp,
 9454    ) -> Result<proto::Ack> {
 9455        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9456        lsp_store.update(&mut cx, |lsp_store, cx| {
 9457            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9458                let text_document = if envelope.payload.current_file_only {
 9459                    let buffer_id = envelope
 9460                        .payload
 9461                        .buffer_id
 9462                        .map(|id| BufferId::new(id))
 9463                        .transpose()?;
 9464                    buffer_id
 9465                        .and_then(|buffer_id| {
 9466                            lsp_store
 9467                                .buffer_store()
 9468                                .read(cx)
 9469                                .get(buffer_id)
 9470                                .and_then(|buffer| {
 9471                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9472                                })
 9473                                .map(|path| make_text_document_identifier(&path))
 9474                        })
 9475                        .transpose()?
 9476                } else {
 9477                    None
 9478                };
 9479                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9480                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9481                )?;
 9482            }
 9483            anyhow::Ok(())
 9484        })??;
 9485
 9486        Ok(proto::Ack {})
 9487    }
 9488
 9489    async fn handle_lsp_ext_clear_flycheck(
 9490        lsp_store: Entity<Self>,
 9491        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9492        cx: AsyncApp,
 9493    ) -> Result<proto::Ack> {
 9494        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9495        lsp_store
 9496            .read_with(&cx, |lsp_store, _| {
 9497                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9498                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9499                } else {
 9500                    None
 9501                }
 9502            })
 9503            .context("handling lsp ext clear flycheck")?;
 9504
 9505        Ok(proto::Ack {})
 9506    }
 9507
 9508    pub fn disk_based_diagnostics_started(
 9509        &mut self,
 9510        language_server_id: LanguageServerId,
 9511        cx: &mut Context<Self>,
 9512    ) {
 9513        if let Some(language_server_status) =
 9514            self.language_server_statuses.get_mut(&language_server_id)
 9515        {
 9516            language_server_status.has_pending_diagnostic_updates = true;
 9517        }
 9518
 9519        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9520        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9521            language_server_id,
 9522            name: self
 9523                .language_server_adapter_for_id(language_server_id)
 9524                .map(|adapter| adapter.name()),
 9525            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9526                Default::default(),
 9527            ),
 9528        })
 9529    }
 9530
 9531    pub fn disk_based_diagnostics_finished(
 9532        &mut self,
 9533        language_server_id: LanguageServerId,
 9534        cx: &mut Context<Self>,
 9535    ) {
 9536        if let Some(language_server_status) =
 9537            self.language_server_statuses.get_mut(&language_server_id)
 9538        {
 9539            language_server_status.has_pending_diagnostic_updates = false;
 9540        }
 9541
 9542        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9543        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9544            language_server_id,
 9545            name: self
 9546                .language_server_adapter_for_id(language_server_id)
 9547                .map(|adapter| adapter.name()),
 9548            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9549                Default::default(),
 9550            ),
 9551        })
 9552    }
 9553
 9554    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9555    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9556    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9557    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9558    // the language server might take some time to publish diagnostics.
 9559    fn simulate_disk_based_diagnostics_events_if_needed(
 9560        &mut self,
 9561        language_server_id: LanguageServerId,
 9562        cx: &mut Context<Self>,
 9563    ) {
 9564        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9565
 9566        let Some(LanguageServerState::Running {
 9567            simulate_disk_based_diagnostics_completion,
 9568            adapter,
 9569            ..
 9570        }) = self
 9571            .as_local_mut()
 9572            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9573        else {
 9574            return;
 9575        };
 9576
 9577        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9578            return;
 9579        }
 9580
 9581        let prev_task =
 9582            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9583                cx.background_executor()
 9584                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9585                    .await;
 9586
 9587                this.update(cx, |this, cx| {
 9588                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9589
 9590                    if let Some(LanguageServerState::Running {
 9591                        simulate_disk_based_diagnostics_completion,
 9592                        ..
 9593                    }) = this.as_local_mut().and_then(|local_store| {
 9594                        local_store.language_servers.get_mut(&language_server_id)
 9595                    }) {
 9596                        *simulate_disk_based_diagnostics_completion = None;
 9597                    }
 9598                })
 9599                .ok();
 9600            }));
 9601
 9602        if prev_task.is_none() {
 9603            self.disk_based_diagnostics_started(language_server_id, cx);
 9604        }
 9605    }
 9606
 9607    pub fn language_server_statuses(
 9608        &self,
 9609    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9610        self.language_server_statuses
 9611            .iter()
 9612            .map(|(key, value)| (*key, value))
 9613    }
 9614
 9615    pub(super) fn did_rename_entry(
 9616        &self,
 9617        worktree_id: WorktreeId,
 9618        old_path: &Path,
 9619        new_path: &Path,
 9620        is_dir: bool,
 9621    ) {
 9622        maybe!({
 9623            let local_store = self.as_local()?;
 9624
 9625            let old_uri = lsp::Uri::from_file_path(old_path)
 9626                .ok()
 9627                .map(|uri| uri.to_string())?;
 9628            let new_uri = lsp::Uri::from_file_path(new_path)
 9629                .ok()
 9630                .map(|uri| uri.to_string())?;
 9631
 9632            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9633                let Some(filter) = local_store
 9634                    .language_server_paths_watched_for_rename
 9635                    .get(&language_server.server_id())
 9636                else {
 9637                    continue;
 9638                };
 9639
 9640                if filter.should_send_did_rename(&old_uri, is_dir) {
 9641                    language_server
 9642                        .notify::<DidRenameFiles>(RenameFilesParams {
 9643                            files: vec![FileRename {
 9644                                old_uri: old_uri.clone(),
 9645                                new_uri: new_uri.clone(),
 9646                            }],
 9647                        })
 9648                        .ok();
 9649                }
 9650            }
 9651            Some(())
 9652        });
 9653    }
 9654
 9655    pub(super) fn will_rename_entry(
 9656        this: WeakEntity<Self>,
 9657        worktree_id: WorktreeId,
 9658        old_path: &Path,
 9659        new_path: &Path,
 9660        is_dir: bool,
 9661        cx: AsyncApp,
 9662    ) -> Task<ProjectTransaction> {
 9663        let old_uri = lsp::Uri::from_file_path(old_path)
 9664            .ok()
 9665            .map(|uri| uri.to_string());
 9666        let new_uri = lsp::Uri::from_file_path(new_path)
 9667            .ok()
 9668            .map(|uri| uri.to_string());
 9669        cx.spawn(async move |cx| {
 9670            let mut tasks = vec![];
 9671            this.update(cx, |this, cx| {
 9672                let local_store = this.as_local()?;
 9673                let old_uri = old_uri?;
 9674                let new_uri = new_uri?;
 9675                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9676                    let Some(filter) = local_store
 9677                        .language_server_paths_watched_for_rename
 9678                        .get(&language_server.server_id())
 9679                    else {
 9680                        continue;
 9681                    };
 9682
 9683                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9684                        let apply_edit = cx.spawn({
 9685                            let old_uri = old_uri.clone();
 9686                            let new_uri = new_uri.clone();
 9687                            let language_server = language_server.clone();
 9688                            async move |this, cx| {
 9689                                let edit = language_server
 9690                                    .request::<WillRenameFiles>(RenameFilesParams {
 9691                                        files: vec![FileRename { old_uri, new_uri }],
 9692                                    })
 9693                                    .await
 9694                                    .into_response()
 9695                                    .context("will rename files")
 9696                                    .log_err()
 9697                                    .flatten()?;
 9698
 9699                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9700                                    this.upgrade()?,
 9701                                    edit,
 9702                                    false,
 9703                                    language_server.clone(),
 9704                                    cx,
 9705                                )
 9706                                .await
 9707                                .ok()?;
 9708                                Some(transaction)
 9709                            }
 9710                        });
 9711                        tasks.push(apply_edit);
 9712                    }
 9713                }
 9714                Some(())
 9715            })
 9716            .ok()
 9717            .flatten();
 9718            let mut merged_transaction = ProjectTransaction::default();
 9719            for task in tasks {
 9720                // Await on tasks sequentially so that the order of application of edits is deterministic
 9721                // (at least with regards to the order of registration of language servers)
 9722                if let Some(transaction) = task.await {
 9723                    for (buffer, buffer_transaction) in transaction.0 {
 9724                        merged_transaction.0.insert(buffer, buffer_transaction);
 9725                    }
 9726                }
 9727            }
 9728            merged_transaction
 9729        })
 9730    }
 9731
 9732    fn lsp_notify_abs_paths_changed(
 9733        &mut self,
 9734        server_id: LanguageServerId,
 9735        changes: Vec<PathEvent>,
 9736    ) {
 9737        maybe!({
 9738            let server = self.language_server_for_id(server_id)?;
 9739            let changes = changes
 9740                .into_iter()
 9741                .filter_map(|event| {
 9742                    let typ = match event.kind? {
 9743                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9744                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9745                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9746                    };
 9747                    Some(lsp::FileEvent {
 9748                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9749                        typ,
 9750                    })
 9751                })
 9752                .collect::<Vec<_>>();
 9753            if !changes.is_empty() {
 9754                server
 9755                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9756                        lsp::DidChangeWatchedFilesParams { changes },
 9757                    )
 9758                    .ok();
 9759            }
 9760            Some(())
 9761        });
 9762    }
 9763
 9764    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9765        self.as_local()?.language_server_for_id(id)
 9766    }
 9767
 9768    fn on_lsp_progress(
 9769        &mut self,
 9770        progress_params: lsp::ProgressParams,
 9771        language_server_id: LanguageServerId,
 9772        disk_based_diagnostics_progress_token: Option<String>,
 9773        cx: &mut Context<Self>,
 9774    ) {
 9775        match progress_params.value {
 9776            lsp::ProgressParamsValue::WorkDone(progress) => {
 9777                self.handle_work_done_progress(
 9778                    progress,
 9779                    language_server_id,
 9780                    disk_based_diagnostics_progress_token,
 9781                    ProgressToken::from_lsp(progress_params.token),
 9782                    cx,
 9783                );
 9784            }
 9785            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9786                let registration_id = match progress_params.token {
 9787                    lsp::NumberOrString::Number(_) => None,
 9788                    lsp::NumberOrString::String(token) => token
 9789                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9790                        .map(|(_, id)| id.to_owned()),
 9791                };
 9792                if let Some(LanguageServerState::Running {
 9793                    workspace_diagnostics_refresh_tasks,
 9794                    ..
 9795                }) = self
 9796                    .as_local_mut()
 9797                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9798                    && let Some(workspace_diagnostics) =
 9799                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9800                {
 9801                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9802                    self.apply_workspace_diagnostic_report(
 9803                        language_server_id,
 9804                        report,
 9805                        registration_id.map(SharedString::from),
 9806                        cx,
 9807                    )
 9808                }
 9809            }
 9810        }
 9811    }
 9812
 9813    fn handle_work_done_progress(
 9814        &mut self,
 9815        progress: lsp::WorkDoneProgress,
 9816        language_server_id: LanguageServerId,
 9817        disk_based_diagnostics_progress_token: Option<String>,
 9818        token: ProgressToken,
 9819        cx: &mut Context<Self>,
 9820    ) {
 9821        let language_server_status =
 9822            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9823                status
 9824            } else {
 9825                return;
 9826            };
 9827
 9828        if !language_server_status.progress_tokens.contains(&token) {
 9829            return;
 9830        }
 9831
 9832        let is_disk_based_diagnostics_progress =
 9833            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9834                (&disk_based_diagnostics_progress_token, &token)
 9835            {
 9836                token.starts_with(disk_based_token)
 9837            } else {
 9838                false
 9839            };
 9840
 9841        match progress {
 9842            lsp::WorkDoneProgress::Begin(report) => {
 9843                if is_disk_based_diagnostics_progress {
 9844                    self.disk_based_diagnostics_started(language_server_id, cx);
 9845                }
 9846                self.on_lsp_work_start(
 9847                    language_server_id,
 9848                    token.clone(),
 9849                    LanguageServerProgress {
 9850                        title: Some(report.title),
 9851                        is_disk_based_diagnostics_progress,
 9852                        is_cancellable: report.cancellable.unwrap_or(false),
 9853                        message: report.message.clone(),
 9854                        percentage: report.percentage.map(|p| p as usize),
 9855                        last_update_at: cx.background_executor().now(),
 9856                    },
 9857                    cx,
 9858                );
 9859            }
 9860            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9861                language_server_id,
 9862                token,
 9863                LanguageServerProgress {
 9864                    title: None,
 9865                    is_disk_based_diagnostics_progress,
 9866                    is_cancellable: report.cancellable.unwrap_or(false),
 9867                    message: report.message,
 9868                    percentage: report.percentage.map(|p| p as usize),
 9869                    last_update_at: cx.background_executor().now(),
 9870                },
 9871                cx,
 9872            ),
 9873            lsp::WorkDoneProgress::End(_) => {
 9874                language_server_status.progress_tokens.remove(&token);
 9875                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9876                if is_disk_based_diagnostics_progress {
 9877                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9878                }
 9879            }
 9880        }
 9881    }
 9882
 9883    fn on_lsp_work_start(
 9884        &mut self,
 9885        language_server_id: LanguageServerId,
 9886        token: ProgressToken,
 9887        progress: LanguageServerProgress,
 9888        cx: &mut Context<Self>,
 9889    ) {
 9890        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9891            status.pending_work.insert(token.clone(), progress.clone());
 9892            cx.notify();
 9893        }
 9894        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9895            language_server_id,
 9896            name: self
 9897                .language_server_adapter_for_id(language_server_id)
 9898                .map(|adapter| adapter.name()),
 9899            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9900                token: Some(token.to_proto()),
 9901                title: progress.title,
 9902                message: progress.message,
 9903                percentage: progress.percentage.map(|p| p as u32),
 9904                is_cancellable: Some(progress.is_cancellable),
 9905            }),
 9906        })
 9907    }
 9908
 9909    fn on_lsp_work_progress(
 9910        &mut self,
 9911        language_server_id: LanguageServerId,
 9912        token: ProgressToken,
 9913        progress: LanguageServerProgress,
 9914        cx: &mut Context<Self>,
 9915    ) {
 9916        let mut did_update = false;
 9917        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9918            match status.pending_work.entry(token.clone()) {
 9919                btree_map::Entry::Vacant(entry) => {
 9920                    entry.insert(progress.clone());
 9921                    did_update = true;
 9922                }
 9923                btree_map::Entry::Occupied(mut entry) => {
 9924                    let entry = entry.get_mut();
 9925                    if (progress.last_update_at - entry.last_update_at)
 9926                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9927                    {
 9928                        entry.last_update_at = progress.last_update_at;
 9929                        if progress.message.is_some() {
 9930                            entry.message = progress.message.clone();
 9931                        }
 9932                        if progress.percentage.is_some() {
 9933                            entry.percentage = progress.percentage;
 9934                        }
 9935                        if progress.is_cancellable != entry.is_cancellable {
 9936                            entry.is_cancellable = progress.is_cancellable;
 9937                        }
 9938                        did_update = true;
 9939                    }
 9940                }
 9941            }
 9942        }
 9943
 9944        if did_update {
 9945            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9946                language_server_id,
 9947                name: self
 9948                    .language_server_adapter_for_id(language_server_id)
 9949                    .map(|adapter| adapter.name()),
 9950                message: proto::update_language_server::Variant::WorkProgress(
 9951                    proto::LspWorkProgress {
 9952                        token: Some(token.to_proto()),
 9953                        message: progress.message,
 9954                        percentage: progress.percentage.map(|p| p as u32),
 9955                        is_cancellable: Some(progress.is_cancellable),
 9956                    },
 9957                ),
 9958            })
 9959        }
 9960    }
 9961
 9962    fn on_lsp_work_end(
 9963        &mut self,
 9964        language_server_id: LanguageServerId,
 9965        token: ProgressToken,
 9966        cx: &mut Context<Self>,
 9967    ) {
 9968        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9969            if let Some(work) = status.pending_work.remove(&token)
 9970                && !work.is_disk_based_diagnostics_progress
 9971            {
 9972                cx.emit(LspStoreEvent::RefreshInlayHints {
 9973                    server_id: language_server_id,
 9974                    request_id: None,
 9975                });
 9976            }
 9977            cx.notify();
 9978        }
 9979
 9980        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9981            language_server_id,
 9982            name: self
 9983                .language_server_adapter_for_id(language_server_id)
 9984                .map(|adapter| adapter.name()),
 9985            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9986                token: Some(token.to_proto()),
 9987            }),
 9988        })
 9989    }
 9990
 9991    pub async fn handle_resolve_completion_documentation(
 9992        this: Entity<Self>,
 9993        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9994        mut cx: AsyncApp,
 9995    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9996        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9997
 9998        let completion = this
 9999            .read_with(&cx, |this, cx| {
10000                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10001                let server = this
10002                    .language_server_for_id(id)
10003                    .with_context(|| format!("No language server {id}"))?;
10004
10005                anyhow::Ok(cx.background_spawn(async move {
10006                    let can_resolve = server
10007                        .capabilities()
10008                        .completion_provider
10009                        .as_ref()
10010                        .and_then(|options| options.resolve_provider)
10011                        .unwrap_or(false);
10012                    if can_resolve {
10013                        server
10014                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10015                            .await
10016                            .into_response()
10017                            .context("resolve completion item")
10018                    } else {
10019                        anyhow::Ok(lsp_completion)
10020                    }
10021                }))
10022            })??
10023            .await?;
10024
10025        let mut documentation_is_markdown = false;
10026        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10027        let documentation = match completion.documentation {
10028            Some(lsp::Documentation::String(text)) => text,
10029
10030            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10031                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10032                value
10033            }
10034
10035            _ => String::new(),
10036        };
10037
10038        // If we have a new buffer_id, that means we're talking to a new client
10039        // and want to check for new text_edits in the completion too.
10040        let mut old_replace_start = None;
10041        let mut old_replace_end = None;
10042        let mut old_insert_start = None;
10043        let mut old_insert_end = None;
10044        let mut new_text = String::default();
10045        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10046            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10047                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10048                anyhow::Ok(buffer.read(cx).snapshot())
10049            })??;
10050
10051            if let Some(text_edit) = completion.text_edit.as_ref() {
10052                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10053
10054                if let Some(mut edit) = edit {
10055                    LineEnding::normalize(&mut edit.new_text);
10056
10057                    new_text = edit.new_text;
10058                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10059                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10060                    if let Some(insert_range) = edit.insert_range {
10061                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10062                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10063                    }
10064                }
10065            }
10066        }
10067
10068        Ok(proto::ResolveCompletionDocumentationResponse {
10069            documentation,
10070            documentation_is_markdown,
10071            old_replace_start,
10072            old_replace_end,
10073            new_text,
10074            lsp_completion,
10075            old_insert_start,
10076            old_insert_end,
10077        })
10078    }
10079
10080    async fn handle_on_type_formatting(
10081        this: Entity<Self>,
10082        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10083        mut cx: AsyncApp,
10084    ) -> Result<proto::OnTypeFormattingResponse> {
10085        let on_type_formatting = this.update(&mut cx, |this, cx| {
10086            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10087            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10088            let position = envelope
10089                .payload
10090                .position
10091                .and_then(deserialize_anchor)
10092                .context("invalid position")?;
10093            anyhow::Ok(this.apply_on_type_formatting(
10094                buffer,
10095                position,
10096                envelope.payload.trigger.clone(),
10097                cx,
10098            ))
10099        })??;
10100
10101        let transaction = on_type_formatting
10102            .await?
10103            .as_ref()
10104            .map(language::proto::serialize_transaction);
10105        Ok(proto::OnTypeFormattingResponse { transaction })
10106    }
10107
10108    async fn handle_refresh_inlay_hints(
10109        lsp_store: Entity<Self>,
10110        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10111        mut cx: AsyncApp,
10112    ) -> Result<proto::Ack> {
10113        lsp_store.update(&mut cx, |_, cx| {
10114            cx.emit(LspStoreEvent::RefreshInlayHints {
10115                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10116                request_id: envelope.payload.request_id.map(|id| id as usize),
10117            });
10118        })?;
10119        Ok(proto::Ack {})
10120    }
10121
10122    async fn handle_pull_workspace_diagnostics(
10123        lsp_store: Entity<Self>,
10124        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10125        mut cx: AsyncApp,
10126    ) -> Result<proto::Ack> {
10127        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10128        lsp_store.update(&mut cx, |lsp_store, _| {
10129            lsp_store.pull_workspace_diagnostics(server_id);
10130        })?;
10131        Ok(proto::Ack {})
10132    }
10133
10134    async fn handle_get_color_presentation(
10135        lsp_store: Entity<Self>,
10136        envelope: TypedEnvelope<proto::GetColorPresentation>,
10137        mut cx: AsyncApp,
10138    ) -> Result<proto::GetColorPresentationResponse> {
10139        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10140        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10141            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10142        })??;
10143
10144        let color = envelope
10145            .payload
10146            .color
10147            .context("invalid color resolve request")?;
10148        let start = color
10149            .lsp_range_start
10150            .context("invalid color resolve request")?;
10151        let end = color
10152            .lsp_range_end
10153            .context("invalid color resolve request")?;
10154
10155        let color = DocumentColor {
10156            lsp_range: lsp::Range {
10157                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10158                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10159            },
10160            color: lsp::Color {
10161                red: color.red,
10162                green: color.green,
10163                blue: color.blue,
10164                alpha: color.alpha,
10165            },
10166            resolved: false,
10167            color_presentations: Vec::new(),
10168        };
10169        let resolved_color = lsp_store
10170            .update(&mut cx, |lsp_store, cx| {
10171                lsp_store.resolve_color_presentation(
10172                    color,
10173                    buffer.clone(),
10174                    LanguageServerId(envelope.payload.server_id as usize),
10175                    cx,
10176                )
10177            })?
10178            .await
10179            .context("resolving color presentation")?;
10180
10181        Ok(proto::GetColorPresentationResponse {
10182            presentations: resolved_color
10183                .color_presentations
10184                .into_iter()
10185                .map(|presentation| proto::ColorPresentation {
10186                    label: presentation.label.to_string(),
10187                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10188                    additional_text_edits: presentation
10189                        .additional_text_edits
10190                        .into_iter()
10191                        .map(serialize_lsp_edit)
10192                        .collect(),
10193                })
10194                .collect(),
10195        })
10196    }
10197
10198    async fn handle_resolve_inlay_hint(
10199        lsp_store: Entity<Self>,
10200        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10201        mut cx: AsyncApp,
10202    ) -> Result<proto::ResolveInlayHintResponse> {
10203        let proto_hint = envelope
10204            .payload
10205            .hint
10206            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10207        let hint = InlayHints::proto_to_project_hint(proto_hint)
10208            .context("resolved proto inlay hint conversion")?;
10209        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10210            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10211            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10212        })??;
10213        let response_hint = lsp_store
10214            .update(&mut cx, |lsp_store, cx| {
10215                lsp_store.resolve_inlay_hint(
10216                    hint,
10217                    buffer,
10218                    LanguageServerId(envelope.payload.language_server_id as usize),
10219                    cx,
10220                )
10221            })?
10222            .await
10223            .context("inlay hints fetch")?;
10224        Ok(proto::ResolveInlayHintResponse {
10225            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10226        })
10227    }
10228
10229    async fn handle_refresh_code_lens(
10230        this: Entity<Self>,
10231        _: TypedEnvelope<proto::RefreshCodeLens>,
10232        mut cx: AsyncApp,
10233    ) -> Result<proto::Ack> {
10234        this.update(&mut cx, |_, cx| {
10235            cx.emit(LspStoreEvent::RefreshCodeLens);
10236        })?;
10237        Ok(proto::Ack {})
10238    }
10239
10240    async fn handle_open_buffer_for_symbol(
10241        this: Entity<Self>,
10242        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10243        mut cx: AsyncApp,
10244    ) -> Result<proto::OpenBufferForSymbolResponse> {
10245        let peer_id = envelope.original_sender_id().unwrap_or_default();
10246        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10247        let symbol = Self::deserialize_symbol(symbol)?;
10248        this.read_with(&cx, |this, _| {
10249            if let SymbolLocation::OutsideProject {
10250                abs_path,
10251                signature,
10252            } = &symbol.path
10253            {
10254                let new_signature = this.symbol_signature(&abs_path);
10255                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10256            }
10257            Ok(())
10258        })??;
10259        let buffer = this
10260            .update(&mut cx, |this, cx| {
10261                this.open_buffer_for_symbol(
10262                    &Symbol {
10263                        language_server_name: symbol.language_server_name,
10264                        source_worktree_id: symbol.source_worktree_id,
10265                        source_language_server_id: symbol.source_language_server_id,
10266                        path: symbol.path,
10267                        name: symbol.name,
10268                        kind: symbol.kind,
10269                        range: symbol.range,
10270                        label: CodeLabel::default(),
10271                    },
10272                    cx,
10273                )
10274            })?
10275            .await?;
10276
10277        this.update(&mut cx, |this, cx| {
10278            let is_private = buffer
10279                .read(cx)
10280                .file()
10281                .map(|f| f.is_private())
10282                .unwrap_or_default();
10283            if is_private {
10284                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10285            } else {
10286                this.buffer_store
10287                    .update(cx, |buffer_store, cx| {
10288                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10289                    })
10290                    .detach_and_log_err(cx);
10291                let buffer_id = buffer.read(cx).remote_id().to_proto();
10292                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10293            }
10294        })?
10295    }
10296
10297    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10298        let mut hasher = Sha256::new();
10299        hasher.update(abs_path.to_string_lossy().as_bytes());
10300        hasher.update(self.nonce.to_be_bytes());
10301        hasher.finalize().as_slice().try_into().unwrap()
10302    }
10303
10304    pub async fn handle_get_project_symbols(
10305        this: Entity<Self>,
10306        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10307        mut cx: AsyncApp,
10308    ) -> Result<proto::GetProjectSymbolsResponse> {
10309        let symbols = this
10310            .update(&mut cx, |this, cx| {
10311                this.symbols(&envelope.payload.query, cx)
10312            })?
10313            .await?;
10314
10315        Ok(proto::GetProjectSymbolsResponse {
10316            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10317        })
10318    }
10319
10320    pub async fn handle_restart_language_servers(
10321        this: Entity<Self>,
10322        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10323        mut cx: AsyncApp,
10324    ) -> Result<proto::Ack> {
10325        this.update(&mut cx, |lsp_store, cx| {
10326            let buffers =
10327                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10328            lsp_store.restart_language_servers_for_buffers(
10329                buffers,
10330                envelope
10331                    .payload
10332                    .only_servers
10333                    .into_iter()
10334                    .filter_map(|selector| {
10335                        Some(match selector.selector? {
10336                            proto::language_server_selector::Selector::ServerId(server_id) => {
10337                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10338                            }
10339                            proto::language_server_selector::Selector::Name(name) => {
10340                                LanguageServerSelector::Name(LanguageServerName(
10341                                    SharedString::from(name),
10342                                ))
10343                            }
10344                        })
10345                    })
10346                    .collect(),
10347                cx,
10348            );
10349        })?;
10350
10351        Ok(proto::Ack {})
10352    }
10353
10354    pub async fn handle_stop_language_servers(
10355        lsp_store: Entity<Self>,
10356        envelope: TypedEnvelope<proto::StopLanguageServers>,
10357        mut cx: AsyncApp,
10358    ) -> Result<proto::Ack> {
10359        lsp_store.update(&mut cx, |lsp_store, cx| {
10360            if envelope.payload.all
10361                && envelope.payload.also_servers.is_empty()
10362                && envelope.payload.buffer_ids.is_empty()
10363            {
10364                lsp_store.stop_all_language_servers(cx);
10365            } else {
10366                let buffers =
10367                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10368                lsp_store
10369                    .stop_language_servers_for_buffers(
10370                        buffers,
10371                        envelope
10372                            .payload
10373                            .also_servers
10374                            .into_iter()
10375                            .filter_map(|selector| {
10376                                Some(match selector.selector? {
10377                                    proto::language_server_selector::Selector::ServerId(
10378                                        server_id,
10379                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10380                                        server_id,
10381                                    )),
10382                                    proto::language_server_selector::Selector::Name(name) => {
10383                                        LanguageServerSelector::Name(LanguageServerName(
10384                                            SharedString::from(name),
10385                                        ))
10386                                    }
10387                                })
10388                            })
10389                            .collect(),
10390                        cx,
10391                    )
10392                    .detach_and_log_err(cx);
10393            }
10394        })?;
10395
10396        Ok(proto::Ack {})
10397    }
10398
10399    pub async fn handle_cancel_language_server_work(
10400        lsp_store: Entity<Self>,
10401        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10402        mut cx: AsyncApp,
10403    ) -> Result<proto::Ack> {
10404        lsp_store.update(&mut cx, |lsp_store, cx| {
10405            if let Some(work) = envelope.payload.work {
10406                match work {
10407                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10408                        let buffers =
10409                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10410                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10411                    }
10412                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10413                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10414                        let token = work
10415                            .token
10416                            .map(|token| {
10417                                ProgressToken::from_proto(token)
10418                                    .context("invalid work progress token")
10419                            })
10420                            .transpose()?;
10421                        lsp_store.cancel_language_server_work(server_id, token, cx);
10422                    }
10423                }
10424            }
10425            anyhow::Ok(())
10426        })??;
10427
10428        Ok(proto::Ack {})
10429    }
10430
10431    fn buffer_ids_to_buffers(
10432        &mut self,
10433        buffer_ids: impl Iterator<Item = u64>,
10434        cx: &mut Context<Self>,
10435    ) -> Vec<Entity<Buffer>> {
10436        buffer_ids
10437            .into_iter()
10438            .flat_map(|buffer_id| {
10439                self.buffer_store
10440                    .read(cx)
10441                    .get(BufferId::new(buffer_id).log_err()?)
10442            })
10443            .collect::<Vec<_>>()
10444    }
10445
10446    async fn handle_apply_additional_edits_for_completion(
10447        this: Entity<Self>,
10448        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10449        mut cx: AsyncApp,
10450    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10451        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10452            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10453            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10454            let completion = Self::deserialize_completion(
10455                envelope.payload.completion.context("invalid completion")?,
10456            )?;
10457            anyhow::Ok((buffer, completion))
10458        })??;
10459
10460        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10461            this.apply_additional_edits_for_completion(
10462                buffer,
10463                Rc::new(RefCell::new(Box::new([Completion {
10464                    replace_range: completion.replace_range,
10465                    new_text: completion.new_text,
10466                    source: completion.source,
10467                    documentation: None,
10468                    label: CodeLabel::default(),
10469                    match_start: None,
10470                    snippet_deduplication_key: None,
10471                    insert_text_mode: None,
10472                    icon_path: None,
10473                    confirm: None,
10474                }]))),
10475                0,
10476                false,
10477                cx,
10478            )
10479        })?;
10480
10481        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10482            transaction: apply_additional_edits
10483                .await?
10484                .as_ref()
10485                .map(language::proto::serialize_transaction),
10486        })
10487    }
10488
10489    pub fn last_formatting_failure(&self) -> Option<&str> {
10490        self.last_formatting_failure.as_deref()
10491    }
10492
10493    pub fn reset_last_formatting_failure(&mut self) {
10494        self.last_formatting_failure = None;
10495    }
10496
10497    pub fn environment_for_buffer(
10498        &self,
10499        buffer: &Entity<Buffer>,
10500        cx: &mut Context<Self>,
10501    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10502        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10503            environment.update(cx, |env, cx| {
10504                env.buffer_environment(buffer, &self.worktree_store, cx)
10505            })
10506        } else {
10507            Task::ready(None).shared()
10508        }
10509    }
10510
10511    pub fn format(
10512        &mut self,
10513        buffers: HashSet<Entity<Buffer>>,
10514        target: LspFormatTarget,
10515        push_to_history: bool,
10516        trigger: FormatTrigger,
10517        cx: &mut Context<Self>,
10518    ) -> Task<anyhow::Result<ProjectTransaction>> {
10519        let logger = zlog::scoped!("format");
10520        if self.as_local().is_some() {
10521            zlog::trace!(logger => "Formatting locally");
10522            let logger = zlog::scoped!(logger => "local");
10523            let buffers = buffers
10524                .into_iter()
10525                .map(|buffer_handle| {
10526                    let buffer = buffer_handle.read(cx);
10527                    let buffer_abs_path = File::from_dyn(buffer.file())
10528                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10529
10530                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10531                })
10532                .collect::<Vec<_>>();
10533
10534            cx.spawn(async move |lsp_store, cx| {
10535                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10536
10537                for (handle, abs_path, id) in buffers {
10538                    let env = lsp_store
10539                        .update(cx, |lsp_store, cx| {
10540                            lsp_store.environment_for_buffer(&handle, cx)
10541                        })?
10542                        .await;
10543
10544                    let ranges = match &target {
10545                        LspFormatTarget::Buffers => None,
10546                        LspFormatTarget::Ranges(ranges) => {
10547                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10548                        }
10549                    };
10550
10551                    formattable_buffers.push(FormattableBuffer {
10552                        handle,
10553                        abs_path,
10554                        env,
10555                        ranges,
10556                    });
10557                }
10558                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10559
10560                let format_timer = zlog::time!(logger => "Formatting buffers");
10561                let result = LocalLspStore::format_locally(
10562                    lsp_store.clone(),
10563                    formattable_buffers,
10564                    push_to_history,
10565                    trigger,
10566                    logger,
10567                    cx,
10568                )
10569                .await;
10570                format_timer.end();
10571
10572                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10573
10574                lsp_store.update(cx, |lsp_store, _| {
10575                    lsp_store.update_last_formatting_failure(&result);
10576                })?;
10577
10578                result
10579            })
10580        } else if let Some((client, project_id)) = self.upstream_client() {
10581            zlog::trace!(logger => "Formatting remotely");
10582            let logger = zlog::scoped!(logger => "remote");
10583            // Don't support formatting ranges via remote
10584            match target {
10585                LspFormatTarget::Buffers => {}
10586                LspFormatTarget::Ranges(_) => {
10587                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10588                    return Task::ready(Ok(ProjectTransaction::default()));
10589                }
10590            }
10591
10592            let buffer_store = self.buffer_store();
10593            cx.spawn(async move |lsp_store, cx| {
10594                zlog::trace!(logger => "Sending remote format request");
10595                let request_timer = zlog::time!(logger => "remote format request");
10596                let result = client
10597                    .request(proto::FormatBuffers {
10598                        project_id,
10599                        trigger: trigger as i32,
10600                        buffer_ids: buffers
10601                            .iter()
10602                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10603                            .collect::<Result<_>>()?,
10604                    })
10605                    .await
10606                    .and_then(|result| result.transaction.context("missing transaction"));
10607                request_timer.end();
10608
10609                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10610
10611                lsp_store.update(cx, |lsp_store, _| {
10612                    lsp_store.update_last_formatting_failure(&result);
10613                })?;
10614
10615                let transaction_response = result?;
10616                let _timer = zlog::time!(logger => "deserializing project transaction");
10617                buffer_store
10618                    .update(cx, |buffer_store, cx| {
10619                        buffer_store.deserialize_project_transaction(
10620                            transaction_response,
10621                            push_to_history,
10622                            cx,
10623                        )
10624                    })?
10625                    .await
10626            })
10627        } else {
10628            zlog::trace!(logger => "Not formatting");
10629            Task::ready(Ok(ProjectTransaction::default()))
10630        }
10631    }
10632
10633    async fn handle_format_buffers(
10634        this: Entity<Self>,
10635        envelope: TypedEnvelope<proto::FormatBuffers>,
10636        mut cx: AsyncApp,
10637    ) -> Result<proto::FormatBuffersResponse> {
10638        let sender_id = envelope.original_sender_id().unwrap_or_default();
10639        let format = this.update(&mut cx, |this, cx| {
10640            let mut buffers = HashSet::default();
10641            for buffer_id in &envelope.payload.buffer_ids {
10642                let buffer_id = BufferId::new(*buffer_id)?;
10643                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10644            }
10645            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10646            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10647        })??;
10648
10649        let project_transaction = format.await?;
10650        let project_transaction = this.update(&mut cx, |this, cx| {
10651            this.buffer_store.update(cx, |buffer_store, cx| {
10652                buffer_store.serialize_project_transaction_for_peer(
10653                    project_transaction,
10654                    sender_id,
10655                    cx,
10656                )
10657            })
10658        })?;
10659        Ok(proto::FormatBuffersResponse {
10660            transaction: Some(project_transaction),
10661        })
10662    }
10663
10664    async fn handle_apply_code_action_kind(
10665        this: Entity<Self>,
10666        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10667        mut cx: AsyncApp,
10668    ) -> Result<proto::ApplyCodeActionKindResponse> {
10669        let sender_id = envelope.original_sender_id().unwrap_or_default();
10670        let format = this.update(&mut cx, |this, cx| {
10671            let mut buffers = HashSet::default();
10672            for buffer_id in &envelope.payload.buffer_ids {
10673                let buffer_id = BufferId::new(*buffer_id)?;
10674                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10675            }
10676            let kind = match envelope.payload.kind.as_str() {
10677                "" => CodeActionKind::EMPTY,
10678                "quickfix" => CodeActionKind::QUICKFIX,
10679                "refactor" => CodeActionKind::REFACTOR,
10680                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10681                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10682                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10683                "source" => CodeActionKind::SOURCE,
10684                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10685                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10686                _ => anyhow::bail!(
10687                    "Invalid code action kind {}",
10688                    envelope.payload.kind.as_str()
10689                ),
10690            };
10691            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10692        })??;
10693
10694        let project_transaction = format.await?;
10695        let project_transaction = this.update(&mut cx, |this, cx| {
10696            this.buffer_store.update(cx, |buffer_store, cx| {
10697                buffer_store.serialize_project_transaction_for_peer(
10698                    project_transaction,
10699                    sender_id,
10700                    cx,
10701                )
10702            })
10703        })?;
10704        Ok(proto::ApplyCodeActionKindResponse {
10705            transaction: Some(project_transaction),
10706        })
10707    }
10708
10709    async fn shutdown_language_server(
10710        server_state: Option<LanguageServerState>,
10711        name: LanguageServerName,
10712        cx: &mut AsyncApp,
10713    ) {
10714        let server = match server_state {
10715            Some(LanguageServerState::Starting { startup, .. }) => {
10716                let mut timer = cx
10717                    .background_executor()
10718                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10719                    .fuse();
10720
10721                select! {
10722                    server = startup.fuse() => server,
10723                    () = timer => {
10724                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10725                        None
10726                    },
10727                }
10728            }
10729
10730            Some(LanguageServerState::Running { server, .. }) => Some(server),
10731
10732            None => None,
10733        };
10734
10735        if let Some(server) = server
10736            && let Some(shutdown) = server.shutdown()
10737        {
10738            shutdown.await;
10739        }
10740    }
10741
10742    // Returns a list of all of the worktrees which no longer have a language server and the root path
10743    // for the stopped server
10744    fn stop_local_language_server(
10745        &mut self,
10746        server_id: LanguageServerId,
10747        cx: &mut Context<Self>,
10748    ) -> Task<()> {
10749        let local = match &mut self.mode {
10750            LspStoreMode::Local(local) => local,
10751            _ => {
10752                return Task::ready(());
10753            }
10754        };
10755
10756        // Remove this server ID from all entries in the given worktree.
10757        local
10758            .language_server_ids
10759            .retain(|_, state| state.id != server_id);
10760        self.buffer_store.update(cx, |buffer_store, cx| {
10761            for buffer in buffer_store.buffers() {
10762                buffer.update(cx, |buffer, cx| {
10763                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10764                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10765                });
10766            }
10767        });
10768
10769        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10770            summaries.retain(|path, summaries_by_server_id| {
10771                if summaries_by_server_id.remove(&server_id).is_some() {
10772                    if let Some((client, project_id)) = self.downstream_client.clone() {
10773                        client
10774                            .send(proto::UpdateDiagnosticSummary {
10775                                project_id,
10776                                worktree_id: worktree_id.to_proto(),
10777                                summary: Some(proto::DiagnosticSummary {
10778                                    path: path.as_ref().to_proto(),
10779                                    language_server_id: server_id.0 as u64,
10780                                    error_count: 0,
10781                                    warning_count: 0,
10782                                }),
10783                                more_summaries: Vec::new(),
10784                            })
10785                            .log_err();
10786                    }
10787                    !summaries_by_server_id.is_empty()
10788                } else {
10789                    true
10790                }
10791            });
10792        }
10793
10794        let local = self.as_local_mut().unwrap();
10795        for diagnostics in local.diagnostics.values_mut() {
10796            diagnostics.retain(|_, diagnostics_by_server_id| {
10797                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10798                    diagnostics_by_server_id.remove(ix);
10799                    !diagnostics_by_server_id.is_empty()
10800                } else {
10801                    true
10802                }
10803            });
10804        }
10805        local.language_server_watched_paths.remove(&server_id);
10806
10807        let server_state = local.language_servers.remove(&server_id);
10808        self.cleanup_lsp_data(server_id);
10809        let name = self
10810            .language_server_statuses
10811            .remove(&server_id)
10812            .map(|status| status.name)
10813            .or_else(|| {
10814                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10815                    Some(adapter.name())
10816                } else {
10817                    None
10818                }
10819            });
10820
10821        if let Some(name) = name {
10822            log::info!("stopping language server {name}");
10823            self.languages
10824                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10825            cx.notify();
10826
10827            return cx.spawn(async move |lsp_store, cx| {
10828                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10829                lsp_store
10830                    .update(cx, |lsp_store, cx| {
10831                        lsp_store
10832                            .languages
10833                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10834                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10835                        cx.notify();
10836                    })
10837                    .ok();
10838            });
10839        }
10840
10841        if server_state.is_some() {
10842            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10843        }
10844        Task::ready(())
10845    }
10846
10847    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10848        if let Some((client, project_id)) = self.upstream_client() {
10849            let request = client.request(proto::StopLanguageServers {
10850                project_id,
10851                buffer_ids: Vec::new(),
10852                also_servers: Vec::new(),
10853                all: true,
10854            });
10855            cx.background_spawn(request).detach_and_log_err(cx);
10856        } else {
10857            let Some(local) = self.as_local_mut() else {
10858                return;
10859            };
10860            let language_servers_to_stop = local
10861                .language_server_ids
10862                .values()
10863                .map(|state| state.id)
10864                .collect();
10865            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10866            let tasks = language_servers_to_stop
10867                .into_iter()
10868                .map(|server| self.stop_local_language_server(server, cx))
10869                .collect::<Vec<_>>();
10870            cx.background_spawn(async move {
10871                futures::future::join_all(tasks).await;
10872            })
10873            .detach();
10874        }
10875    }
10876
10877    pub fn restart_language_servers_for_buffers(
10878        &mut self,
10879        buffers: Vec<Entity<Buffer>>,
10880        only_restart_servers: HashSet<LanguageServerSelector>,
10881        cx: &mut Context<Self>,
10882    ) {
10883        if let Some((client, project_id)) = self.upstream_client() {
10884            let request = client.request(proto::RestartLanguageServers {
10885                project_id,
10886                buffer_ids: buffers
10887                    .into_iter()
10888                    .map(|b| b.read(cx).remote_id().to_proto())
10889                    .collect(),
10890                only_servers: only_restart_servers
10891                    .into_iter()
10892                    .map(|selector| {
10893                        let selector = match selector {
10894                            LanguageServerSelector::Id(language_server_id) => {
10895                                proto::language_server_selector::Selector::ServerId(
10896                                    language_server_id.to_proto(),
10897                                )
10898                            }
10899                            LanguageServerSelector::Name(language_server_name) => {
10900                                proto::language_server_selector::Selector::Name(
10901                                    language_server_name.to_string(),
10902                                )
10903                            }
10904                        };
10905                        proto::LanguageServerSelector {
10906                            selector: Some(selector),
10907                        }
10908                    })
10909                    .collect(),
10910                all: false,
10911            });
10912            cx.background_spawn(request).detach_and_log_err(cx);
10913        } else {
10914            let stop_task = if only_restart_servers.is_empty() {
10915                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10916            } else {
10917                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10918            };
10919            cx.spawn(async move |lsp_store, cx| {
10920                stop_task.await;
10921                lsp_store
10922                    .update(cx, |lsp_store, cx| {
10923                        for buffer in buffers {
10924                            lsp_store.register_buffer_with_language_servers(
10925                                &buffer,
10926                                only_restart_servers.clone(),
10927                                true,
10928                                cx,
10929                            );
10930                        }
10931                    })
10932                    .ok()
10933            })
10934            .detach();
10935        }
10936    }
10937
10938    pub fn stop_language_servers_for_buffers(
10939        &mut self,
10940        buffers: Vec<Entity<Buffer>>,
10941        also_stop_servers: HashSet<LanguageServerSelector>,
10942        cx: &mut Context<Self>,
10943    ) -> Task<Result<()>> {
10944        if let Some((client, project_id)) = self.upstream_client() {
10945            let request = client.request(proto::StopLanguageServers {
10946                project_id,
10947                buffer_ids: buffers
10948                    .into_iter()
10949                    .map(|b| b.read(cx).remote_id().to_proto())
10950                    .collect(),
10951                also_servers: also_stop_servers
10952                    .into_iter()
10953                    .map(|selector| {
10954                        let selector = match selector {
10955                            LanguageServerSelector::Id(language_server_id) => {
10956                                proto::language_server_selector::Selector::ServerId(
10957                                    language_server_id.to_proto(),
10958                                )
10959                            }
10960                            LanguageServerSelector::Name(language_server_name) => {
10961                                proto::language_server_selector::Selector::Name(
10962                                    language_server_name.to_string(),
10963                                )
10964                            }
10965                        };
10966                        proto::LanguageServerSelector {
10967                            selector: Some(selector),
10968                        }
10969                    })
10970                    .collect(),
10971                all: false,
10972            });
10973            cx.background_spawn(async move {
10974                let _ = request.await?;
10975                Ok(())
10976            })
10977        } else {
10978            let task =
10979                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10980            cx.background_spawn(async move {
10981                task.await;
10982                Ok(())
10983            })
10984        }
10985    }
10986
10987    fn stop_local_language_servers_for_buffers(
10988        &mut self,
10989        buffers: &[Entity<Buffer>],
10990        also_stop_servers: HashSet<LanguageServerSelector>,
10991        cx: &mut Context<Self>,
10992    ) -> Task<()> {
10993        let Some(local) = self.as_local_mut() else {
10994            return Task::ready(());
10995        };
10996        let mut language_server_names_to_stop = BTreeSet::default();
10997        let mut language_servers_to_stop = also_stop_servers
10998            .into_iter()
10999            .flat_map(|selector| match selector {
11000                LanguageServerSelector::Id(id) => Some(id),
11001                LanguageServerSelector::Name(name) => {
11002                    language_server_names_to_stop.insert(name);
11003                    None
11004                }
11005            })
11006            .collect::<BTreeSet<_>>();
11007
11008        let mut covered_worktrees = HashSet::default();
11009        for buffer in buffers {
11010            buffer.update(cx, |buffer, cx| {
11011                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11012                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11013                    && covered_worktrees.insert(worktree_id)
11014                {
11015                    language_server_names_to_stop.retain(|name| {
11016                        let old_ids_count = language_servers_to_stop.len();
11017                        let all_language_servers_with_this_name = local
11018                            .language_server_ids
11019                            .iter()
11020                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11021                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11022                        old_ids_count == language_servers_to_stop.len()
11023                    });
11024                }
11025            });
11026        }
11027        for name in language_server_names_to_stop {
11028            language_servers_to_stop.extend(
11029                local
11030                    .language_server_ids
11031                    .iter()
11032                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11033            );
11034        }
11035
11036        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11037        let tasks = language_servers_to_stop
11038            .into_iter()
11039            .map(|server| self.stop_local_language_server(server, cx))
11040            .collect::<Vec<_>>();
11041
11042        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11043    }
11044
11045    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11046        let (worktree, relative_path) =
11047            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11048
11049        let project_path = ProjectPath {
11050            worktree_id: worktree.read(cx).id(),
11051            path: relative_path,
11052        };
11053
11054        Some(
11055            self.buffer_store()
11056                .read(cx)
11057                .get_by_path(&project_path)?
11058                .read(cx),
11059        )
11060    }
11061
11062    #[cfg(any(test, feature = "test-support"))]
11063    pub fn update_diagnostics(
11064        &mut self,
11065        server_id: LanguageServerId,
11066        diagnostics: lsp::PublishDiagnosticsParams,
11067        result_id: Option<SharedString>,
11068        source_kind: DiagnosticSourceKind,
11069        disk_based_sources: &[String],
11070        cx: &mut Context<Self>,
11071    ) -> Result<()> {
11072        self.merge_lsp_diagnostics(
11073            source_kind,
11074            vec![DocumentDiagnosticsUpdate {
11075                diagnostics,
11076                result_id,
11077                server_id,
11078                disk_based_sources: Cow::Borrowed(disk_based_sources),
11079                registration_id: None,
11080            }],
11081            |_, _, _| false,
11082            cx,
11083        )
11084    }
11085
11086    pub fn merge_lsp_diagnostics(
11087        &mut self,
11088        source_kind: DiagnosticSourceKind,
11089        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11090        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11091        cx: &mut Context<Self>,
11092    ) -> Result<()> {
11093        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11094        let updates = lsp_diagnostics
11095            .into_iter()
11096            .filter_map(|update| {
11097                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11098                Some(DocumentDiagnosticsUpdate {
11099                    diagnostics: self.lsp_to_document_diagnostics(
11100                        abs_path,
11101                        source_kind,
11102                        update.server_id,
11103                        update.diagnostics,
11104                        &update.disk_based_sources,
11105                        update.registration_id.clone(),
11106                    ),
11107                    result_id: update.result_id,
11108                    server_id: update.server_id,
11109                    disk_based_sources: update.disk_based_sources,
11110                    registration_id: update.registration_id,
11111                })
11112            })
11113            .collect();
11114        self.merge_diagnostic_entries(updates, merge, cx)?;
11115        Ok(())
11116    }
11117
11118    fn lsp_to_document_diagnostics(
11119        &mut self,
11120        document_abs_path: PathBuf,
11121        source_kind: DiagnosticSourceKind,
11122        server_id: LanguageServerId,
11123        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11124        disk_based_sources: &[String],
11125        registration_id: Option<SharedString>,
11126    ) -> DocumentDiagnostics {
11127        let mut diagnostics = Vec::default();
11128        let mut primary_diagnostic_group_ids = HashMap::default();
11129        let mut sources_by_group_id = HashMap::default();
11130        let mut supporting_diagnostics = HashMap::default();
11131
11132        let adapter = self.language_server_adapter_for_id(server_id);
11133
11134        // Ensure that primary diagnostics are always the most severe
11135        lsp_diagnostics
11136            .diagnostics
11137            .sort_by_key(|item| item.severity);
11138
11139        for diagnostic in &lsp_diagnostics.diagnostics {
11140            let source = diagnostic.source.as_ref();
11141            let range = range_from_lsp(diagnostic.range);
11142            let is_supporting = diagnostic
11143                .related_information
11144                .as_ref()
11145                .is_some_and(|infos| {
11146                    infos.iter().any(|info| {
11147                        primary_diagnostic_group_ids.contains_key(&(
11148                            source,
11149                            diagnostic.code.clone(),
11150                            range_from_lsp(info.location.range),
11151                        ))
11152                    })
11153                });
11154
11155            let is_unnecessary = diagnostic
11156                .tags
11157                .as_ref()
11158                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11159
11160            let underline = self
11161                .language_server_adapter_for_id(server_id)
11162                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11163
11164            if is_supporting {
11165                supporting_diagnostics.insert(
11166                    (source, diagnostic.code.clone(), range),
11167                    (diagnostic.severity, is_unnecessary),
11168                );
11169            } else {
11170                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11171                let is_disk_based =
11172                    source.is_some_and(|source| disk_based_sources.contains(source));
11173
11174                sources_by_group_id.insert(group_id, source);
11175                primary_diagnostic_group_ids
11176                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11177
11178                diagnostics.push(DiagnosticEntry {
11179                    range,
11180                    diagnostic: Diagnostic {
11181                        source: diagnostic.source.clone(),
11182                        source_kind,
11183                        code: diagnostic.code.clone(),
11184                        code_description: diagnostic
11185                            .code_description
11186                            .as_ref()
11187                            .and_then(|d| d.href.clone()),
11188                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11189                        markdown: adapter.as_ref().and_then(|adapter| {
11190                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11191                        }),
11192                        message: diagnostic.message.trim().to_string(),
11193                        group_id,
11194                        is_primary: true,
11195                        is_disk_based,
11196                        is_unnecessary,
11197                        underline,
11198                        data: diagnostic.data.clone(),
11199                        registration_id: registration_id.clone(),
11200                    },
11201                });
11202                if let Some(infos) = &diagnostic.related_information {
11203                    for info in infos {
11204                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11205                            let range = range_from_lsp(info.location.range);
11206                            diagnostics.push(DiagnosticEntry {
11207                                range,
11208                                diagnostic: Diagnostic {
11209                                    source: diagnostic.source.clone(),
11210                                    source_kind,
11211                                    code: diagnostic.code.clone(),
11212                                    code_description: diagnostic
11213                                        .code_description
11214                                        .as_ref()
11215                                        .and_then(|d| d.href.clone()),
11216                                    severity: DiagnosticSeverity::INFORMATION,
11217                                    markdown: adapter.as_ref().and_then(|adapter| {
11218                                        adapter.diagnostic_message_to_markdown(&info.message)
11219                                    }),
11220                                    message: info.message.trim().to_string(),
11221                                    group_id,
11222                                    is_primary: false,
11223                                    is_disk_based,
11224                                    is_unnecessary: false,
11225                                    underline,
11226                                    data: diagnostic.data.clone(),
11227                                    registration_id: registration_id.clone(),
11228                                },
11229                            });
11230                        }
11231                    }
11232                }
11233            }
11234        }
11235
11236        for entry in &mut diagnostics {
11237            let diagnostic = &mut entry.diagnostic;
11238            if !diagnostic.is_primary {
11239                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11240                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11241                    source,
11242                    diagnostic.code.clone(),
11243                    entry.range.clone(),
11244                )) {
11245                    if let Some(severity) = severity {
11246                        diagnostic.severity = severity;
11247                    }
11248                    diagnostic.is_unnecessary = is_unnecessary;
11249                }
11250            }
11251        }
11252
11253        DocumentDiagnostics {
11254            diagnostics,
11255            document_abs_path,
11256            version: lsp_diagnostics.version,
11257        }
11258    }
11259
11260    fn insert_newly_running_language_server(
11261        &mut self,
11262        adapter: Arc<CachedLspAdapter>,
11263        language_server: Arc<LanguageServer>,
11264        server_id: LanguageServerId,
11265        key: LanguageServerSeed,
11266        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11267        cx: &mut Context<Self>,
11268    ) {
11269        let Some(local) = self.as_local_mut() else {
11270            return;
11271        };
11272        // If the language server for this key doesn't match the server id, don't store the
11273        // server. Which will cause it to be dropped, killing the process
11274        if local
11275            .language_server_ids
11276            .get(&key)
11277            .map(|state| state.id != server_id)
11278            .unwrap_or(false)
11279        {
11280            return;
11281        }
11282
11283        // Update language_servers collection with Running variant of LanguageServerState
11284        // indicating that the server is up and running and ready
11285        let workspace_folders = workspace_folders.lock().clone();
11286        language_server.set_workspace_folders(workspace_folders);
11287
11288        let workspace_diagnostics_refresh_tasks = language_server
11289            .capabilities()
11290            .diagnostic_provider
11291            .and_then(|provider| {
11292                local
11293                    .language_server_dynamic_registrations
11294                    .entry(server_id)
11295                    .or_default()
11296                    .diagnostics
11297                    .entry(None)
11298                    .or_insert(provider.clone());
11299                let workspace_refresher =
11300                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11301
11302                Some((None, workspace_refresher))
11303            })
11304            .into_iter()
11305            .collect();
11306        local.language_servers.insert(
11307            server_id,
11308            LanguageServerState::Running {
11309                workspace_diagnostics_refresh_tasks,
11310                adapter: adapter.clone(),
11311                server: language_server.clone(),
11312                simulate_disk_based_diagnostics_completion: None,
11313            },
11314        );
11315        local
11316            .languages
11317            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11318        if let Some(file_ops_caps) = language_server
11319            .capabilities()
11320            .workspace
11321            .as_ref()
11322            .and_then(|ws| ws.file_operations.as_ref())
11323        {
11324            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11325            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11326            if did_rename_caps.or(will_rename_caps).is_some() {
11327                let watcher = RenamePathsWatchedForServer::default()
11328                    .with_did_rename_patterns(did_rename_caps)
11329                    .with_will_rename_patterns(will_rename_caps);
11330                local
11331                    .language_server_paths_watched_for_rename
11332                    .insert(server_id, watcher);
11333            }
11334        }
11335
11336        self.language_server_statuses.insert(
11337            server_id,
11338            LanguageServerStatus {
11339                name: language_server.name(),
11340                pending_work: Default::default(),
11341                has_pending_diagnostic_updates: false,
11342                progress_tokens: Default::default(),
11343                worktree: Some(key.worktree_id),
11344                binary: Some(language_server.binary().clone()),
11345                configuration: Some(language_server.configuration().clone()),
11346                workspace_folders: language_server.workspace_folders(),
11347            },
11348        );
11349
11350        cx.emit(LspStoreEvent::LanguageServerAdded(
11351            server_id,
11352            language_server.name(),
11353            Some(key.worktree_id),
11354        ));
11355
11356        let server_capabilities = language_server.capabilities();
11357        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11358            downstream_client
11359                .send(proto::StartLanguageServer {
11360                    project_id: *project_id,
11361                    server: Some(proto::LanguageServer {
11362                        id: server_id.to_proto(),
11363                        name: language_server.name().to_string(),
11364                        worktree_id: Some(key.worktree_id.to_proto()),
11365                    }),
11366                    capabilities: serde_json::to_string(&server_capabilities)
11367                        .expect("serializing server LSP capabilities"),
11368                })
11369                .log_err();
11370        }
11371        self.lsp_server_capabilities
11372            .insert(server_id, server_capabilities);
11373
11374        // Tell the language server about every open buffer in the worktree that matches the language.
11375        // Also check for buffers in worktrees that reused this server
11376        let mut worktrees_using_server = vec![key.worktree_id];
11377        if let Some(local) = self.as_local() {
11378            // Find all worktrees that have this server in their language server tree
11379            for (worktree_id, servers) in &local.lsp_tree.instances {
11380                if *worktree_id != key.worktree_id {
11381                    for server_map in servers.roots.values() {
11382                        if server_map
11383                            .values()
11384                            .any(|(node, _)| node.id() == Some(server_id))
11385                        {
11386                            worktrees_using_server.push(*worktree_id);
11387                        }
11388                    }
11389                }
11390            }
11391        }
11392
11393        let mut buffer_paths_registered = Vec::new();
11394        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11395            let mut lsp_adapters = HashMap::default();
11396            for buffer_handle in buffer_store.buffers() {
11397                let buffer = buffer_handle.read(cx);
11398                let file = match File::from_dyn(buffer.file()) {
11399                    Some(file) => file,
11400                    None => continue,
11401                };
11402                let language = match buffer.language() {
11403                    Some(language) => language,
11404                    None => continue,
11405                };
11406
11407                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11408                    || !lsp_adapters
11409                        .entry(language.name())
11410                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11411                        .iter()
11412                        .any(|a| a.name == key.name)
11413                {
11414                    continue;
11415                }
11416                // didOpen
11417                let file = match file.as_local() {
11418                    Some(file) => file,
11419                    None => continue,
11420                };
11421
11422                let local = self.as_local_mut().unwrap();
11423
11424                let buffer_id = buffer.remote_id();
11425                if local.registered_buffers.contains_key(&buffer_id) {
11426                    let versions = local
11427                        .buffer_snapshots
11428                        .entry(buffer_id)
11429                        .or_default()
11430                        .entry(server_id)
11431                        .and_modify(|_| {
11432                            assert!(
11433                            false,
11434                            "There should not be an existing snapshot for a newly inserted buffer"
11435                        )
11436                        })
11437                        .or_insert_with(|| {
11438                            vec![LspBufferSnapshot {
11439                                version: 0,
11440                                snapshot: buffer.text_snapshot(),
11441                            }]
11442                        });
11443
11444                    let snapshot = versions.last().unwrap();
11445                    let version = snapshot.version;
11446                    let initial_snapshot = &snapshot.snapshot;
11447                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11448                    language_server.register_buffer(
11449                        uri,
11450                        adapter.language_id(&language.name()),
11451                        version,
11452                        initial_snapshot.text(),
11453                    );
11454                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11455                    local
11456                        .buffers_opened_in_servers
11457                        .entry(buffer_id)
11458                        .or_default()
11459                        .insert(server_id);
11460                }
11461                buffer_handle.update(cx, |buffer, cx| {
11462                    buffer.set_completion_triggers(
11463                        server_id,
11464                        language_server
11465                            .capabilities()
11466                            .completion_provider
11467                            .as_ref()
11468                            .and_then(|provider| {
11469                                provider
11470                                    .trigger_characters
11471                                    .as_ref()
11472                                    .map(|characters| characters.iter().cloned().collect())
11473                            })
11474                            .unwrap_or_default(),
11475                        cx,
11476                    )
11477                });
11478            }
11479        });
11480
11481        for (buffer_id, abs_path) in buffer_paths_registered {
11482            cx.emit(LspStoreEvent::LanguageServerUpdate {
11483                language_server_id: server_id,
11484                name: Some(adapter.name()),
11485                message: proto::update_language_server::Variant::RegisteredForBuffer(
11486                    proto::RegisteredForBuffer {
11487                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11488                        buffer_id: buffer_id.to_proto(),
11489                    },
11490                ),
11491            });
11492        }
11493
11494        cx.notify();
11495    }
11496
11497    pub fn language_servers_running_disk_based_diagnostics(
11498        &self,
11499    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11500        self.language_server_statuses
11501            .iter()
11502            .filter_map(|(id, status)| {
11503                if status.has_pending_diagnostic_updates {
11504                    Some(*id)
11505                } else {
11506                    None
11507                }
11508            })
11509    }
11510
11511    pub(crate) fn cancel_language_server_work_for_buffers(
11512        &mut self,
11513        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11514        cx: &mut Context<Self>,
11515    ) {
11516        if let Some((client, project_id)) = self.upstream_client() {
11517            let request = client.request(proto::CancelLanguageServerWork {
11518                project_id,
11519                work: Some(proto::cancel_language_server_work::Work::Buffers(
11520                    proto::cancel_language_server_work::Buffers {
11521                        buffer_ids: buffers
11522                            .into_iter()
11523                            .map(|b| b.read(cx).remote_id().to_proto())
11524                            .collect(),
11525                    },
11526                )),
11527            });
11528            cx.background_spawn(request).detach_and_log_err(cx);
11529        } else if let Some(local) = self.as_local() {
11530            let servers = buffers
11531                .into_iter()
11532                .flat_map(|buffer| {
11533                    buffer.update(cx, |buffer, cx| {
11534                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11535                    })
11536                })
11537                .collect::<HashSet<_>>();
11538            for server_id in servers {
11539                self.cancel_language_server_work(server_id, None, cx);
11540            }
11541        }
11542    }
11543
11544    pub(crate) fn cancel_language_server_work(
11545        &mut self,
11546        server_id: LanguageServerId,
11547        token_to_cancel: Option<ProgressToken>,
11548        cx: &mut Context<Self>,
11549    ) {
11550        if let Some(local) = self.as_local() {
11551            let status = self.language_server_statuses.get(&server_id);
11552            let server = local.language_servers.get(&server_id);
11553            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11554            {
11555                for (token, progress) in &status.pending_work {
11556                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11557                        && token != token_to_cancel
11558                    {
11559                        continue;
11560                    }
11561                    if progress.is_cancellable {
11562                        server
11563                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11564                                WorkDoneProgressCancelParams {
11565                                    token: token.to_lsp(),
11566                                },
11567                            )
11568                            .ok();
11569                    }
11570                }
11571            }
11572        } else if let Some((client, project_id)) = self.upstream_client() {
11573            let request = client.request(proto::CancelLanguageServerWork {
11574                project_id,
11575                work: Some(
11576                    proto::cancel_language_server_work::Work::LanguageServerWork(
11577                        proto::cancel_language_server_work::LanguageServerWork {
11578                            language_server_id: server_id.to_proto(),
11579                            token: token_to_cancel.map(|token| token.to_proto()),
11580                        },
11581                    ),
11582                ),
11583            });
11584            cx.background_spawn(request).detach_and_log_err(cx);
11585        }
11586    }
11587
11588    fn register_supplementary_language_server(
11589        &mut self,
11590        id: LanguageServerId,
11591        name: LanguageServerName,
11592        server: Arc<LanguageServer>,
11593        cx: &mut Context<Self>,
11594    ) {
11595        if let Some(local) = self.as_local_mut() {
11596            local
11597                .supplementary_language_servers
11598                .insert(id, (name.clone(), server));
11599            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11600        }
11601    }
11602
11603    fn unregister_supplementary_language_server(
11604        &mut self,
11605        id: LanguageServerId,
11606        cx: &mut Context<Self>,
11607    ) {
11608        if let Some(local) = self.as_local_mut() {
11609            local.supplementary_language_servers.remove(&id);
11610            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11611        }
11612    }
11613
11614    pub(crate) fn supplementary_language_servers(
11615        &self,
11616    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11617        self.as_local().into_iter().flat_map(|local| {
11618            local
11619                .supplementary_language_servers
11620                .iter()
11621                .map(|(id, (name, _))| (*id, name.clone()))
11622        })
11623    }
11624
11625    pub fn language_server_adapter_for_id(
11626        &self,
11627        id: LanguageServerId,
11628    ) -> Option<Arc<CachedLspAdapter>> {
11629        self.as_local()
11630            .and_then(|local| local.language_servers.get(&id))
11631            .and_then(|language_server_state| match language_server_state {
11632                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11633                _ => None,
11634            })
11635    }
11636
11637    pub(super) fn update_local_worktree_language_servers(
11638        &mut self,
11639        worktree_handle: &Entity<Worktree>,
11640        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11641        cx: &mut Context<Self>,
11642    ) {
11643        if changes.is_empty() {
11644            return;
11645        }
11646
11647        let Some(local) = self.as_local() else { return };
11648
11649        local.prettier_store.update(cx, |prettier_store, cx| {
11650            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11651        });
11652
11653        let worktree_id = worktree_handle.read(cx).id();
11654        let mut language_server_ids = local
11655            .language_server_ids
11656            .iter()
11657            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11658            .collect::<Vec<_>>();
11659        language_server_ids.sort();
11660        language_server_ids.dedup();
11661
11662        // let abs_path = worktree_handle.read(cx).abs_path();
11663        for server_id in &language_server_ids {
11664            if let Some(LanguageServerState::Running { server, .. }) =
11665                local.language_servers.get(server_id)
11666                && let Some(watched_paths) = local
11667                    .language_server_watched_paths
11668                    .get(server_id)
11669                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11670            {
11671                let params = lsp::DidChangeWatchedFilesParams {
11672                    changes: changes
11673                        .iter()
11674                        .filter_map(|(path, _, change)| {
11675                            if !watched_paths.is_match(path.as_std_path()) {
11676                                return None;
11677                            }
11678                            let typ = match change {
11679                                PathChange::Loaded => return None,
11680                                PathChange::Added => lsp::FileChangeType::CREATED,
11681                                PathChange::Removed => lsp::FileChangeType::DELETED,
11682                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11683                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11684                            };
11685                            let uri = lsp::Uri::from_file_path(
11686                                worktree_handle.read(cx).absolutize(&path),
11687                            )
11688                            .ok()?;
11689                            Some(lsp::FileEvent { uri, typ })
11690                        })
11691                        .collect(),
11692                };
11693                if !params.changes.is_empty() {
11694                    server
11695                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11696                        .ok();
11697                }
11698            }
11699        }
11700        for (path, _, _) in changes {
11701            if let Some(file_name) = path.file_name()
11702                && local.watched_manifest_filenames.contains(file_name)
11703            {
11704                self.request_workspace_config_refresh();
11705                break;
11706            }
11707        }
11708    }
11709
11710    pub fn wait_for_remote_buffer(
11711        &mut self,
11712        id: BufferId,
11713        cx: &mut Context<Self>,
11714    ) -> Task<Result<Entity<Buffer>>> {
11715        self.buffer_store.update(cx, |buffer_store, cx| {
11716            buffer_store.wait_for_remote_buffer(id, cx)
11717        })
11718    }
11719
11720    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11721        let mut result = proto::Symbol {
11722            language_server_name: symbol.language_server_name.0.to_string(),
11723            source_worktree_id: symbol.source_worktree_id.to_proto(),
11724            language_server_id: symbol.source_language_server_id.to_proto(),
11725            name: symbol.name.clone(),
11726            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11727            start: Some(proto::PointUtf16 {
11728                row: symbol.range.start.0.row,
11729                column: symbol.range.start.0.column,
11730            }),
11731            end: Some(proto::PointUtf16 {
11732                row: symbol.range.end.0.row,
11733                column: symbol.range.end.0.column,
11734            }),
11735            worktree_id: Default::default(),
11736            path: Default::default(),
11737            signature: Default::default(),
11738        };
11739        match &symbol.path {
11740            SymbolLocation::InProject(path) => {
11741                result.worktree_id = path.worktree_id.to_proto();
11742                result.path = path.path.to_proto();
11743            }
11744            SymbolLocation::OutsideProject {
11745                abs_path,
11746                signature,
11747            } => {
11748                result.path = abs_path.to_string_lossy().into_owned();
11749                result.signature = signature.to_vec();
11750            }
11751        }
11752        result
11753    }
11754
11755    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11756        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11757        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11758        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11759
11760        let path = if serialized_symbol.signature.is_empty() {
11761            SymbolLocation::InProject(ProjectPath {
11762                worktree_id,
11763                path: RelPath::from_proto(&serialized_symbol.path)
11764                    .context("invalid symbol path")?,
11765            })
11766        } else {
11767            SymbolLocation::OutsideProject {
11768                abs_path: Path::new(&serialized_symbol.path).into(),
11769                signature: serialized_symbol
11770                    .signature
11771                    .try_into()
11772                    .map_err(|_| anyhow!("invalid signature"))?,
11773            }
11774        };
11775
11776        let start = serialized_symbol.start.context("invalid start")?;
11777        let end = serialized_symbol.end.context("invalid end")?;
11778        Ok(CoreSymbol {
11779            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11780            source_worktree_id,
11781            source_language_server_id: LanguageServerId::from_proto(
11782                serialized_symbol.language_server_id,
11783            ),
11784            path,
11785            name: serialized_symbol.name,
11786            range: Unclipped(PointUtf16::new(start.row, start.column))
11787                ..Unclipped(PointUtf16::new(end.row, end.column)),
11788            kind,
11789        })
11790    }
11791
11792    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11793        let mut serialized_completion = proto::Completion {
11794            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11795            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11796            new_text: completion.new_text.clone(),
11797            ..proto::Completion::default()
11798        };
11799        match &completion.source {
11800            CompletionSource::Lsp {
11801                insert_range,
11802                server_id,
11803                lsp_completion,
11804                lsp_defaults,
11805                resolved,
11806            } => {
11807                let (old_insert_start, old_insert_end) = insert_range
11808                    .as_ref()
11809                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11810                    .unzip();
11811
11812                serialized_completion.old_insert_start = old_insert_start;
11813                serialized_completion.old_insert_end = old_insert_end;
11814                serialized_completion.source = proto::completion::Source::Lsp as i32;
11815                serialized_completion.server_id = server_id.0 as u64;
11816                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11817                serialized_completion.lsp_defaults = lsp_defaults
11818                    .as_deref()
11819                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11820                serialized_completion.resolved = *resolved;
11821            }
11822            CompletionSource::BufferWord {
11823                word_range,
11824                resolved,
11825            } => {
11826                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11827                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11828                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11829                serialized_completion.resolved = *resolved;
11830            }
11831            CompletionSource::Custom => {
11832                serialized_completion.source = proto::completion::Source::Custom as i32;
11833                serialized_completion.resolved = true;
11834            }
11835            CompletionSource::Dap { sort_text } => {
11836                serialized_completion.source = proto::completion::Source::Dap as i32;
11837                serialized_completion.sort_text = Some(sort_text.clone());
11838            }
11839        }
11840
11841        serialized_completion
11842    }
11843
11844    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11845        let old_replace_start = completion
11846            .old_replace_start
11847            .and_then(deserialize_anchor)
11848            .context("invalid old start")?;
11849        let old_replace_end = completion
11850            .old_replace_end
11851            .and_then(deserialize_anchor)
11852            .context("invalid old end")?;
11853        let insert_range = {
11854            match completion.old_insert_start.zip(completion.old_insert_end) {
11855                Some((start, end)) => {
11856                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11857                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11858                    Some(start..end)
11859                }
11860                None => None,
11861            }
11862        };
11863        Ok(CoreCompletion {
11864            replace_range: old_replace_start..old_replace_end,
11865            new_text: completion.new_text,
11866            source: match proto::completion::Source::from_i32(completion.source) {
11867                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11868                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11869                    insert_range,
11870                    server_id: LanguageServerId::from_proto(completion.server_id),
11871                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11872                    lsp_defaults: completion
11873                        .lsp_defaults
11874                        .as_deref()
11875                        .map(serde_json::from_slice)
11876                        .transpose()?,
11877                    resolved: completion.resolved,
11878                },
11879                Some(proto::completion::Source::BufferWord) => {
11880                    let word_range = completion
11881                        .buffer_word_start
11882                        .and_then(deserialize_anchor)
11883                        .context("invalid buffer word start")?
11884                        ..completion
11885                            .buffer_word_end
11886                            .and_then(deserialize_anchor)
11887                            .context("invalid buffer word end")?;
11888                    CompletionSource::BufferWord {
11889                        word_range,
11890                        resolved: completion.resolved,
11891                    }
11892                }
11893                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11894                    sort_text: completion
11895                        .sort_text
11896                        .context("expected sort text to exist")?,
11897                },
11898                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11899            },
11900        })
11901    }
11902
11903    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11904        let (kind, lsp_action) = match &action.lsp_action {
11905            LspAction::Action(code_action) => (
11906                proto::code_action::Kind::Action as i32,
11907                serde_json::to_vec(code_action).unwrap(),
11908            ),
11909            LspAction::Command(command) => (
11910                proto::code_action::Kind::Command as i32,
11911                serde_json::to_vec(command).unwrap(),
11912            ),
11913            LspAction::CodeLens(code_lens) => (
11914                proto::code_action::Kind::CodeLens as i32,
11915                serde_json::to_vec(code_lens).unwrap(),
11916            ),
11917        };
11918
11919        proto::CodeAction {
11920            server_id: action.server_id.0 as u64,
11921            start: Some(serialize_anchor(&action.range.start)),
11922            end: Some(serialize_anchor(&action.range.end)),
11923            lsp_action,
11924            kind,
11925            resolved: action.resolved,
11926        }
11927    }
11928
11929    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11930        let start = action
11931            .start
11932            .and_then(deserialize_anchor)
11933            .context("invalid start")?;
11934        let end = action
11935            .end
11936            .and_then(deserialize_anchor)
11937            .context("invalid end")?;
11938        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11939            Some(proto::code_action::Kind::Action) => {
11940                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11941            }
11942            Some(proto::code_action::Kind::Command) => {
11943                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11944            }
11945            Some(proto::code_action::Kind::CodeLens) => {
11946                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11947            }
11948            None => anyhow::bail!("Unknown action kind {}", action.kind),
11949        };
11950        Ok(CodeAction {
11951            server_id: LanguageServerId(action.server_id as usize),
11952            range: start..end,
11953            resolved: action.resolved,
11954            lsp_action,
11955        })
11956    }
11957
11958    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11959        match &formatting_result {
11960            Ok(_) => self.last_formatting_failure = None,
11961            Err(error) => {
11962                let error_string = format!("{error:#}");
11963                log::error!("Formatting failed: {error_string}");
11964                self.last_formatting_failure
11965                    .replace(error_string.lines().join(" "));
11966            }
11967        }
11968    }
11969
11970    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11971        self.lsp_server_capabilities.remove(&for_server);
11972        for lsp_data in self.lsp_data.values_mut() {
11973            lsp_data.remove_server_data(for_server);
11974        }
11975        if let Some(local) = self.as_local_mut() {
11976            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11977            local
11978                .workspace_pull_diagnostics_result_ids
11979                .remove(&for_server);
11980            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11981                buffer_servers.remove(&for_server);
11982            }
11983        }
11984    }
11985
11986    pub fn result_id_for_buffer_pull(
11987        &self,
11988        server_id: LanguageServerId,
11989        buffer_id: BufferId,
11990        registration_id: &Option<SharedString>,
11991        cx: &App,
11992    ) -> Option<SharedString> {
11993        let abs_path = self
11994            .buffer_store
11995            .read(cx)
11996            .get(buffer_id)
11997            .and_then(|b| File::from_dyn(b.read(cx).file()))
11998            .map(|f| f.abs_path(cx))?;
11999        self.as_local()?
12000            .buffer_pull_diagnostics_result_ids
12001            .get(&server_id)?
12002            .get(registration_id)?
12003            .get(&abs_path)?
12004            .clone()
12005    }
12006
12007    /// Gets all result_ids for a workspace diagnostics pull request.
12008    /// First, it tries to find buffer's result_id retrieved via the diagnostics pull; if it fails, it falls back to the workspace disagnostics pull result_id.
12009    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12010    pub fn result_ids_for_workspace_refresh(
12011        &self,
12012        server_id: LanguageServerId,
12013        registration_id: &Option<SharedString>,
12014    ) -> HashMap<PathBuf, SharedString> {
12015        let Some(local) = self.as_local() else {
12016            return HashMap::default();
12017        };
12018        local
12019            .workspace_pull_diagnostics_result_ids
12020            .get(&server_id)
12021            .into_iter()
12022            .filter_map(|diagnostics| diagnostics.get(registration_id))
12023            .flatten()
12024            .filter_map(|(abs_path, result_id)| {
12025                let result_id = local
12026                    .buffer_pull_diagnostics_result_ids
12027                    .get(&server_id)
12028                    .and_then(|buffer_ids_result_ids| {
12029                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12030                    })
12031                    .cloned()
12032                    .flatten()
12033                    .or_else(|| result_id.clone())?;
12034                Some((abs_path.clone(), result_id))
12035            })
12036            .collect()
12037    }
12038
12039    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12040        if let Some(LanguageServerState::Running {
12041            workspace_diagnostics_refresh_tasks,
12042            ..
12043        }) = self
12044            .as_local_mut()
12045            .and_then(|local| local.language_servers.get_mut(&server_id))
12046        {
12047            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12048                diagnostics.refresh_tx.try_send(()).ok();
12049            }
12050        }
12051    }
12052
12053    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12054        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12055            return;
12056        };
12057        let Some(local) = self.as_local_mut() else {
12058            return;
12059        };
12060
12061        for server_id in buffer.update(cx, |buffer, cx| {
12062            local.language_server_ids_for_buffer(buffer, cx)
12063        }) {
12064            if let Some(LanguageServerState::Running {
12065                workspace_diagnostics_refresh_tasks,
12066                ..
12067            }) = local.language_servers.get_mut(&server_id)
12068            {
12069                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12070                    diagnostics.refresh_tx.try_send(()).ok();
12071                }
12072            }
12073        }
12074    }
12075
12076    fn apply_workspace_diagnostic_report(
12077        &mut self,
12078        server_id: LanguageServerId,
12079        report: lsp::WorkspaceDiagnosticReportResult,
12080        registration_id: Option<SharedString>,
12081        cx: &mut Context<Self>,
12082    ) {
12083        let workspace_diagnostics =
12084            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12085                report,
12086                server_id,
12087                registration_id,
12088            );
12089        let mut unchanged_buffers = HashMap::default();
12090        let workspace_diagnostics_updates = workspace_diagnostics
12091            .into_iter()
12092            .filter_map(
12093                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12094                    LspPullDiagnostics::Response {
12095                        server_id,
12096                        uri,
12097                        diagnostics,
12098                        registration_id,
12099                    } => Some((
12100                        server_id,
12101                        uri,
12102                        diagnostics,
12103                        workspace_diagnostics.version,
12104                        registration_id,
12105                    )),
12106                    LspPullDiagnostics::Default => None,
12107                },
12108            )
12109            .fold(
12110                HashMap::default(),
12111                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12112                    let (result_id, diagnostics) = match diagnostics {
12113                        PulledDiagnostics::Unchanged { result_id } => {
12114                            unchanged_buffers
12115                                .entry(new_registration_id.clone())
12116                                .or_insert_with(HashSet::default)
12117                                .insert(uri.clone());
12118                            (Some(result_id), Vec::new())
12119                        }
12120                        PulledDiagnostics::Changed {
12121                            result_id,
12122                            diagnostics,
12123                        } => (result_id, diagnostics),
12124                    };
12125                    let disk_based_sources = Cow::Owned(
12126                        self.language_server_adapter_for_id(server_id)
12127                            .as_ref()
12128                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12129                            .unwrap_or(&[])
12130                            .to_vec(),
12131                    );
12132
12133                    let Some(abs_path) = uri.to_file_path().ok() else {
12134                        return acc;
12135                    };
12136                    let Some((worktree, relative_path)) =
12137                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12138                    else {
12139                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12140                        return acc;
12141                    };
12142                    let worktree_id = worktree.read(cx).id();
12143                    let project_path = ProjectPath {
12144                        worktree_id,
12145                        path: relative_path,
12146                    };
12147                    if let Some(local_lsp_store) = self.as_local_mut() {
12148                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12149                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12150                    }
12151                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12152                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12153                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12154                        acc.entry(server_id)
12155                            .or_insert_with(HashMap::default)
12156                            .entry(new_registration_id.clone())
12157                            .or_insert_with(Vec::new)
12158                            .push(DocumentDiagnosticsUpdate {
12159                                server_id,
12160                                diagnostics: lsp::PublishDiagnosticsParams {
12161                                    uri,
12162                                    diagnostics,
12163                                    version,
12164                                },
12165                                result_id,
12166                                disk_based_sources,
12167                                registration_id: new_registration_id,
12168                            });
12169                    }
12170                    acc
12171                },
12172            );
12173
12174        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12175            for (registration_id, diagnostic_updates) in diagnostic_updates {
12176                self.merge_lsp_diagnostics(
12177                    DiagnosticSourceKind::Pulled,
12178                    diagnostic_updates,
12179                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12180                        DiagnosticSourceKind::Pulled => {
12181                            old_diagnostic.registration_id != registration_id
12182                                || unchanged_buffers
12183                                    .get(&old_diagnostic.registration_id)
12184                                    .is_some_and(|unchanged_buffers| {
12185                                        unchanged_buffers.contains(&document_uri)
12186                                    })
12187                        }
12188                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12189                    },
12190                    cx,
12191                )
12192                .log_err();
12193            }
12194        }
12195    }
12196
12197    fn register_server_capabilities(
12198        &mut self,
12199        server_id: LanguageServerId,
12200        params: lsp::RegistrationParams,
12201        cx: &mut Context<Self>,
12202    ) -> anyhow::Result<()> {
12203        let server = self
12204            .language_server_for_id(server_id)
12205            .with_context(|| format!("no server {server_id} found"))?;
12206        for reg in params.registrations {
12207            match reg.method.as_str() {
12208                "workspace/didChangeWatchedFiles" => {
12209                    if let Some(options) = reg.register_options {
12210                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12211                            let caps = serde_json::from_value(options)?;
12212                            local_lsp_store
12213                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12214                            true
12215                        } else {
12216                            false
12217                        };
12218                        if notify {
12219                            notify_server_capabilities_updated(&server, cx);
12220                        }
12221                    }
12222                }
12223                "workspace/didChangeConfiguration" => {
12224                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12225                }
12226                "workspace/didChangeWorkspaceFolders" => {
12227                    // In this case register options is an empty object, we can ignore it
12228                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12229                        supported: Some(true),
12230                        change_notifications: Some(OneOf::Right(reg.id)),
12231                    };
12232                    server.update_capabilities(|capabilities| {
12233                        capabilities
12234                            .workspace
12235                            .get_or_insert_default()
12236                            .workspace_folders = Some(caps);
12237                    });
12238                    notify_server_capabilities_updated(&server, cx);
12239                }
12240                "workspace/symbol" => {
12241                    let options = parse_register_capabilities(reg)?;
12242                    server.update_capabilities(|capabilities| {
12243                        capabilities.workspace_symbol_provider = Some(options);
12244                    });
12245                    notify_server_capabilities_updated(&server, cx);
12246                }
12247                "workspace/fileOperations" => {
12248                    if let Some(options) = reg.register_options {
12249                        let caps = serde_json::from_value(options)?;
12250                        server.update_capabilities(|capabilities| {
12251                            capabilities
12252                                .workspace
12253                                .get_or_insert_default()
12254                                .file_operations = Some(caps);
12255                        });
12256                        notify_server_capabilities_updated(&server, cx);
12257                    }
12258                }
12259                "workspace/executeCommand" => {
12260                    if let Some(options) = reg.register_options {
12261                        let options = serde_json::from_value(options)?;
12262                        server.update_capabilities(|capabilities| {
12263                            capabilities.execute_command_provider = Some(options);
12264                        });
12265                        notify_server_capabilities_updated(&server, cx);
12266                    }
12267                }
12268                "textDocument/rangeFormatting" => {
12269                    let options = parse_register_capabilities(reg)?;
12270                    server.update_capabilities(|capabilities| {
12271                        capabilities.document_range_formatting_provider = Some(options);
12272                    });
12273                    notify_server_capabilities_updated(&server, cx);
12274                }
12275                "textDocument/onTypeFormatting" => {
12276                    if let Some(options) = reg
12277                        .register_options
12278                        .map(serde_json::from_value)
12279                        .transpose()?
12280                    {
12281                        server.update_capabilities(|capabilities| {
12282                            capabilities.document_on_type_formatting_provider = Some(options);
12283                        });
12284                        notify_server_capabilities_updated(&server, cx);
12285                    }
12286                }
12287                "textDocument/formatting" => {
12288                    let options = parse_register_capabilities(reg)?;
12289                    server.update_capabilities(|capabilities| {
12290                        capabilities.document_formatting_provider = Some(options);
12291                    });
12292                    notify_server_capabilities_updated(&server, cx);
12293                }
12294                "textDocument/rename" => {
12295                    let options = parse_register_capabilities(reg)?;
12296                    server.update_capabilities(|capabilities| {
12297                        capabilities.rename_provider = Some(options);
12298                    });
12299                    notify_server_capabilities_updated(&server, cx);
12300                }
12301                "textDocument/inlayHint" => {
12302                    let options = parse_register_capabilities(reg)?;
12303                    server.update_capabilities(|capabilities| {
12304                        capabilities.inlay_hint_provider = Some(options);
12305                    });
12306                    notify_server_capabilities_updated(&server, cx);
12307                }
12308                "textDocument/documentSymbol" => {
12309                    let options = parse_register_capabilities(reg)?;
12310                    server.update_capabilities(|capabilities| {
12311                        capabilities.document_symbol_provider = Some(options);
12312                    });
12313                    notify_server_capabilities_updated(&server, cx);
12314                }
12315                "textDocument/codeAction" => {
12316                    let options = parse_register_capabilities(reg)?;
12317                    let provider = match options {
12318                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12319                        OneOf::Right(caps) => caps,
12320                    };
12321                    server.update_capabilities(|capabilities| {
12322                        capabilities.code_action_provider = Some(provider);
12323                    });
12324                    notify_server_capabilities_updated(&server, cx);
12325                }
12326                "textDocument/definition" => {
12327                    let options = parse_register_capabilities(reg)?;
12328                    server.update_capabilities(|capabilities| {
12329                        capabilities.definition_provider = Some(options);
12330                    });
12331                    notify_server_capabilities_updated(&server, cx);
12332                }
12333                "textDocument/completion" => {
12334                    if let Some(caps) = reg
12335                        .register_options
12336                        .map(serde_json::from_value::<CompletionOptions>)
12337                        .transpose()?
12338                    {
12339                        server.update_capabilities(|capabilities| {
12340                            capabilities.completion_provider = Some(caps.clone());
12341                        });
12342
12343                        if let Some(local) = self.as_local() {
12344                            let mut buffers_with_language_server = Vec::new();
12345                            for handle in self.buffer_store.read(cx).buffers() {
12346                                let buffer_id = handle.read(cx).remote_id();
12347                                if local
12348                                    .buffers_opened_in_servers
12349                                    .get(&buffer_id)
12350                                    .filter(|s| s.contains(&server_id))
12351                                    .is_some()
12352                                {
12353                                    buffers_with_language_server.push(handle);
12354                                }
12355                            }
12356                            let triggers = caps
12357                                .trigger_characters
12358                                .unwrap_or_default()
12359                                .into_iter()
12360                                .collect::<BTreeSet<_>>();
12361                            for handle in buffers_with_language_server {
12362                                let triggers = triggers.clone();
12363                                let _ = handle.update(cx, move |buffer, cx| {
12364                                    buffer.set_completion_triggers(server_id, triggers, cx);
12365                                });
12366                            }
12367                        }
12368                        notify_server_capabilities_updated(&server, cx);
12369                    }
12370                }
12371                "textDocument/hover" => {
12372                    let options = parse_register_capabilities(reg)?;
12373                    let provider = match options {
12374                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12375                        OneOf::Right(caps) => caps,
12376                    };
12377                    server.update_capabilities(|capabilities| {
12378                        capabilities.hover_provider = Some(provider);
12379                    });
12380                    notify_server_capabilities_updated(&server, cx);
12381                }
12382                "textDocument/signatureHelp" => {
12383                    if let Some(caps) = reg
12384                        .register_options
12385                        .map(serde_json::from_value)
12386                        .transpose()?
12387                    {
12388                        server.update_capabilities(|capabilities| {
12389                            capabilities.signature_help_provider = Some(caps);
12390                        });
12391                        notify_server_capabilities_updated(&server, cx);
12392                    }
12393                }
12394                "textDocument/didChange" => {
12395                    if let Some(sync_kind) = reg
12396                        .register_options
12397                        .and_then(|opts| opts.get("syncKind").cloned())
12398                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12399                        .transpose()?
12400                    {
12401                        server.update_capabilities(|capabilities| {
12402                            let mut sync_options =
12403                                Self::take_text_document_sync_options(capabilities);
12404                            sync_options.change = Some(sync_kind);
12405                            capabilities.text_document_sync =
12406                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12407                        });
12408                        notify_server_capabilities_updated(&server, cx);
12409                    }
12410                }
12411                "textDocument/didSave" => {
12412                    if let Some(include_text) = reg
12413                        .register_options
12414                        .map(|opts| {
12415                            let transpose = opts
12416                                .get("includeText")
12417                                .cloned()
12418                                .map(serde_json::from_value::<Option<bool>>)
12419                                .transpose();
12420                            match transpose {
12421                                Ok(value) => Ok(value.flatten()),
12422                                Err(e) => Err(e),
12423                            }
12424                        })
12425                        .transpose()?
12426                    {
12427                        server.update_capabilities(|capabilities| {
12428                            let mut sync_options =
12429                                Self::take_text_document_sync_options(capabilities);
12430                            sync_options.save =
12431                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12432                                    include_text,
12433                                }));
12434                            capabilities.text_document_sync =
12435                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12436                        });
12437                        notify_server_capabilities_updated(&server, cx);
12438                    }
12439                }
12440                "textDocument/codeLens" => {
12441                    if let Some(caps) = reg
12442                        .register_options
12443                        .map(serde_json::from_value)
12444                        .transpose()?
12445                    {
12446                        server.update_capabilities(|capabilities| {
12447                            capabilities.code_lens_provider = Some(caps);
12448                        });
12449                        notify_server_capabilities_updated(&server, cx);
12450                    }
12451                }
12452                "textDocument/diagnostic" => {
12453                    if let Some(caps) = reg
12454                        .register_options
12455                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12456                        .transpose()?
12457                    {
12458                        let local = self
12459                            .as_local_mut()
12460                            .context("Expected LSP Store to be local")?;
12461                        let state = local
12462                            .language_servers
12463                            .get_mut(&server_id)
12464                            .context("Could not obtain Language Servers state")?;
12465                        local
12466                            .language_server_dynamic_registrations
12467                            .entry(server_id)
12468                            .or_default()
12469                            .diagnostics
12470                            .insert(Some(reg.id.clone()), caps.clone());
12471
12472                        let supports_workspace_diagnostics =
12473                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12474                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12475                                    diagnostic_options.workspace_diagnostics
12476                                }
12477                                DiagnosticServerCapabilities::RegistrationOptions(
12478                                    diagnostic_registration_options,
12479                                ) => {
12480                                    diagnostic_registration_options
12481                                        .diagnostic_options
12482                                        .workspace_diagnostics
12483                                }
12484                            };
12485
12486                        if supports_workspace_diagnostics(&caps) {
12487                            if let LanguageServerState::Running {
12488                                workspace_diagnostics_refresh_tasks,
12489                                ..
12490                            } = state
12491                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12492                                    Some(reg.id.clone()),
12493                                    caps.clone(),
12494                                    server.clone(),
12495                                    cx,
12496                                )
12497                            {
12498                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12499                            }
12500                        }
12501
12502                        server.update_capabilities(|capabilities| {
12503                            capabilities.diagnostic_provider = Some(caps);
12504                        });
12505
12506                        notify_server_capabilities_updated(&server, cx);
12507                    }
12508                }
12509                "textDocument/documentColor" => {
12510                    let options = parse_register_capabilities(reg)?;
12511                    let provider = match options {
12512                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12513                        OneOf::Right(caps) => caps,
12514                    };
12515                    server.update_capabilities(|capabilities| {
12516                        capabilities.color_provider = Some(provider);
12517                    });
12518                    notify_server_capabilities_updated(&server, cx);
12519                }
12520                _ => log::warn!("unhandled capability registration: {reg:?}"),
12521            }
12522        }
12523
12524        Ok(())
12525    }
12526
12527    fn unregister_server_capabilities(
12528        &mut self,
12529        server_id: LanguageServerId,
12530        params: lsp::UnregistrationParams,
12531        cx: &mut Context<Self>,
12532    ) -> anyhow::Result<()> {
12533        let server = self
12534            .language_server_for_id(server_id)
12535            .with_context(|| format!("no server {server_id} found"))?;
12536        for unreg in params.unregisterations.iter() {
12537            match unreg.method.as_str() {
12538                "workspace/didChangeWatchedFiles" => {
12539                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12540                        local_lsp_store
12541                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12542                        true
12543                    } else {
12544                        false
12545                    };
12546                    if notify {
12547                        notify_server_capabilities_updated(&server, cx);
12548                    }
12549                }
12550                "workspace/didChangeConfiguration" => {
12551                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12552                }
12553                "workspace/didChangeWorkspaceFolders" => {
12554                    server.update_capabilities(|capabilities| {
12555                        capabilities
12556                            .workspace
12557                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12558                                workspace_folders: None,
12559                                file_operations: None,
12560                            })
12561                            .workspace_folders = None;
12562                    });
12563                    notify_server_capabilities_updated(&server, cx);
12564                }
12565                "workspace/symbol" => {
12566                    server.update_capabilities(|capabilities| {
12567                        capabilities.workspace_symbol_provider = None
12568                    });
12569                    notify_server_capabilities_updated(&server, cx);
12570                }
12571                "workspace/fileOperations" => {
12572                    server.update_capabilities(|capabilities| {
12573                        capabilities
12574                            .workspace
12575                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12576                                workspace_folders: None,
12577                                file_operations: None,
12578                            })
12579                            .file_operations = None;
12580                    });
12581                    notify_server_capabilities_updated(&server, cx);
12582                }
12583                "workspace/executeCommand" => {
12584                    server.update_capabilities(|capabilities| {
12585                        capabilities.execute_command_provider = None;
12586                    });
12587                    notify_server_capabilities_updated(&server, cx);
12588                }
12589                "textDocument/rangeFormatting" => {
12590                    server.update_capabilities(|capabilities| {
12591                        capabilities.document_range_formatting_provider = None
12592                    });
12593                    notify_server_capabilities_updated(&server, cx);
12594                }
12595                "textDocument/onTypeFormatting" => {
12596                    server.update_capabilities(|capabilities| {
12597                        capabilities.document_on_type_formatting_provider = None;
12598                    });
12599                    notify_server_capabilities_updated(&server, cx);
12600                }
12601                "textDocument/formatting" => {
12602                    server.update_capabilities(|capabilities| {
12603                        capabilities.document_formatting_provider = None;
12604                    });
12605                    notify_server_capabilities_updated(&server, cx);
12606                }
12607                "textDocument/rename" => {
12608                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12609                    notify_server_capabilities_updated(&server, cx);
12610                }
12611                "textDocument/codeAction" => {
12612                    server.update_capabilities(|capabilities| {
12613                        capabilities.code_action_provider = None;
12614                    });
12615                    notify_server_capabilities_updated(&server, cx);
12616                }
12617                "textDocument/definition" => {
12618                    server.update_capabilities(|capabilities| {
12619                        capabilities.definition_provider = None;
12620                    });
12621                    notify_server_capabilities_updated(&server, cx);
12622                }
12623                "textDocument/completion" => {
12624                    server.update_capabilities(|capabilities| {
12625                        capabilities.completion_provider = None;
12626                    });
12627                    notify_server_capabilities_updated(&server, cx);
12628                }
12629                "textDocument/hover" => {
12630                    server.update_capabilities(|capabilities| {
12631                        capabilities.hover_provider = None;
12632                    });
12633                    notify_server_capabilities_updated(&server, cx);
12634                }
12635                "textDocument/signatureHelp" => {
12636                    server.update_capabilities(|capabilities| {
12637                        capabilities.signature_help_provider = None;
12638                    });
12639                    notify_server_capabilities_updated(&server, cx);
12640                }
12641                "textDocument/didChange" => {
12642                    server.update_capabilities(|capabilities| {
12643                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12644                        sync_options.change = None;
12645                        capabilities.text_document_sync =
12646                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12647                    });
12648                    notify_server_capabilities_updated(&server, cx);
12649                }
12650                "textDocument/didSave" => {
12651                    server.update_capabilities(|capabilities| {
12652                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12653                        sync_options.save = None;
12654                        capabilities.text_document_sync =
12655                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12656                    });
12657                    notify_server_capabilities_updated(&server, cx);
12658                }
12659                "textDocument/codeLens" => {
12660                    server.update_capabilities(|capabilities| {
12661                        capabilities.code_lens_provider = None;
12662                    });
12663                    notify_server_capabilities_updated(&server, cx);
12664                }
12665                "textDocument/diagnostic" => {
12666                    let local = self
12667                        .as_local_mut()
12668                        .context("Expected LSP Store to be local")?;
12669
12670                    let state = local
12671                        .language_servers
12672                        .get_mut(&server_id)
12673                        .context("Could not obtain Language Servers state")?;
12674                    let registrations = local
12675                        .language_server_dynamic_registrations
12676                        .get_mut(&server_id)
12677                        .with_context(|| {
12678                            format!("Expected dynamic registration to exist for server {server_id}")
12679                        })?;
12680                    registrations.diagnostics
12681                        .remove(&Some(unreg.id.clone()))
12682                        .with_context(|| format!(
12683                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12684                            unreg.id)
12685                        )?;
12686                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12687
12688                    if let LanguageServerState::Running {
12689                        workspace_diagnostics_refresh_tasks,
12690                        ..
12691                    } = state
12692                    {
12693                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12694                    }
12695
12696                    if removed_last_diagnostic_provider {
12697                        server.update_capabilities(|capabilities| {
12698                            debug_assert!(capabilities.diagnostic_provider.is_some());
12699                            capabilities.diagnostic_provider = None;
12700                        });
12701                    }
12702
12703                    notify_server_capabilities_updated(&server, cx);
12704                }
12705                "textDocument/documentColor" => {
12706                    server.update_capabilities(|capabilities| {
12707                        capabilities.color_provider = None;
12708                    });
12709                    notify_server_capabilities_updated(&server, cx);
12710                }
12711                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12712            }
12713        }
12714
12715        Ok(())
12716    }
12717
12718    async fn deduplicate_range_based_lsp_requests<T>(
12719        lsp_store: &Entity<Self>,
12720        server_id: Option<LanguageServerId>,
12721        lsp_request_id: LspRequestId,
12722        proto_request: &T::ProtoRequest,
12723        range: Range<Anchor>,
12724        cx: &mut AsyncApp,
12725    ) -> Result<()>
12726    where
12727        T: LspCommand,
12728        T::ProtoRequest: proto::LspRequestMessage,
12729    {
12730        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12731        let version = deserialize_version(proto_request.buffer_version());
12732        let buffer = lsp_store.update(cx, |this, cx| {
12733            this.buffer_store.read(cx).get_existing(buffer_id)
12734        })??;
12735        buffer
12736            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12737            .await?;
12738        lsp_store.update(cx, |lsp_store, cx| {
12739            let buffer_snapshot = buffer.read(cx).snapshot();
12740            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12741            let chunks_queried_for = lsp_data
12742                .inlay_hints
12743                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12744                .collect::<Vec<_>>();
12745            match chunks_queried_for.as_slice() {
12746                &[chunk] => {
12747                    let key = LspKey {
12748                        request_type: TypeId::of::<T>(),
12749                        server_queried: server_id,
12750                    };
12751                    let previous_request = lsp_data
12752                        .chunk_lsp_requests
12753                        .entry(key)
12754                        .or_default()
12755                        .insert(chunk, lsp_request_id);
12756                    if let Some((previous_request, running_requests)) =
12757                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12758                    {
12759                        running_requests.remove(&previous_request);
12760                    }
12761                }
12762                _ambiguous_chunks => {
12763                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12764                    // there, a buffer version-based check will be performed and outdated requests discarded.
12765                }
12766            }
12767            anyhow::Ok(())
12768        })??;
12769
12770        Ok(())
12771    }
12772
12773    async fn query_lsp_locally<T>(
12774        lsp_store: Entity<Self>,
12775        for_server_id: Option<LanguageServerId>,
12776        sender_id: proto::PeerId,
12777        lsp_request_id: LspRequestId,
12778        proto_request: T::ProtoRequest,
12779        position: Option<Anchor>,
12780        cx: &mut AsyncApp,
12781    ) -> Result<()>
12782    where
12783        T: LspCommand + Clone,
12784        T::ProtoRequest: proto::LspRequestMessage,
12785        <T::ProtoRequest as proto::RequestMessage>::Response:
12786            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12787    {
12788        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12789        let version = deserialize_version(proto_request.buffer_version());
12790        let buffer = lsp_store.update(cx, |this, cx| {
12791            this.buffer_store.read(cx).get_existing(buffer_id)
12792        })??;
12793        buffer
12794            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12795            .await?;
12796        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12797        let request =
12798            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12799        let key = LspKey {
12800            request_type: TypeId::of::<T>(),
12801            server_queried: for_server_id,
12802        };
12803        lsp_store.update(cx, |lsp_store, cx| {
12804            let request_task = match for_server_id {
12805                Some(server_id) => {
12806                    let server_task = lsp_store.request_lsp(
12807                        buffer.clone(),
12808                        LanguageServerToQuery::Other(server_id),
12809                        request.clone(),
12810                        cx,
12811                    );
12812                    cx.background_spawn(async move {
12813                        let mut responses = Vec::new();
12814                        match server_task.await {
12815                            Ok(response) => responses.push((server_id, response)),
12816                            // rust-analyzer likes to error with this when its still loading up
12817                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12818                            Err(e) => log::error!(
12819                                "Error handling response for request {request:?}: {e:#}"
12820                            ),
12821                        }
12822                        responses
12823                    })
12824                }
12825                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12826            };
12827            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12828            if T::ProtoRequest::stop_previous_requests() {
12829                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12830                    lsp_requests.clear();
12831                }
12832            }
12833            lsp_data.lsp_requests.entry(key).or_default().insert(
12834                lsp_request_id,
12835                cx.spawn(async move |lsp_store, cx| {
12836                    let response = request_task.await;
12837                    lsp_store
12838                        .update(cx, |lsp_store, cx| {
12839                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12840                            {
12841                                let response = response
12842                                    .into_iter()
12843                                    .map(|(server_id, response)| {
12844                                        (
12845                                            server_id.to_proto(),
12846                                            T::response_to_proto(
12847                                                response,
12848                                                lsp_store,
12849                                                sender_id,
12850                                                &buffer_version,
12851                                                cx,
12852                                            )
12853                                            .into(),
12854                                        )
12855                                    })
12856                                    .collect::<HashMap<_, _>>();
12857                                match client.send_lsp_response::<T::ProtoRequest>(
12858                                    project_id,
12859                                    lsp_request_id,
12860                                    response,
12861                                ) {
12862                                    Ok(()) => {}
12863                                    Err(e) => {
12864                                        log::error!("Failed to send LSP response: {e:#}",)
12865                                    }
12866                                }
12867                            }
12868                        })
12869                        .ok();
12870                }),
12871            );
12872        })?;
12873        Ok(())
12874    }
12875
12876    fn take_text_document_sync_options(
12877        capabilities: &mut lsp::ServerCapabilities,
12878    ) -> lsp::TextDocumentSyncOptions {
12879        match capabilities.text_document_sync.take() {
12880            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12881            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12882                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12883                sync_options.change = Some(sync_kind);
12884                sync_options
12885            }
12886            None => lsp::TextDocumentSyncOptions::default(),
12887        }
12888    }
12889
12890    #[cfg(any(test, feature = "test-support"))]
12891    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12892        Some(
12893            self.lsp_data
12894                .get_mut(&buffer_id)?
12895                .code_lens
12896                .take()?
12897                .update
12898                .take()?
12899                .1,
12900        )
12901    }
12902
12903    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12904        self.downstream_client.clone()
12905    }
12906
12907    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12908        self.worktree_store.clone()
12909    }
12910
12911    /// Gets what's stored in the LSP data for the given buffer.
12912    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12913        self.lsp_data.get_mut(&buffer_id)
12914    }
12915
12916    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12917    /// new [`BufferLspData`] will be created to replace the previous state.
12918    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12919        let (buffer_id, buffer_version) =
12920            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12921        let lsp_data = self
12922            .lsp_data
12923            .entry(buffer_id)
12924            .or_insert_with(|| BufferLspData::new(buffer, cx));
12925        if buffer_version.changed_since(&lsp_data.buffer_version) {
12926            *lsp_data = BufferLspData::new(buffer, cx);
12927        }
12928        lsp_data
12929    }
12930}
12931
12932// Registration with registerOptions as null, should fallback to true.
12933// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12934fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12935    reg: lsp::Registration,
12936) -> Result<OneOf<bool, T>> {
12937    Ok(match reg.register_options {
12938        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12939        None => OneOf::Left(true),
12940    })
12941}
12942
12943fn subscribe_to_binary_statuses(
12944    languages: &Arc<LanguageRegistry>,
12945    cx: &mut Context<'_, LspStore>,
12946) -> Task<()> {
12947    let mut server_statuses = languages.language_server_binary_statuses();
12948    cx.spawn(async move |lsp_store, cx| {
12949        while let Some((server_name, binary_status)) = server_statuses.next().await {
12950            if lsp_store
12951                .update(cx, |_, cx| {
12952                    let mut message = None;
12953                    let binary_status = match binary_status {
12954                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12955                        BinaryStatus::CheckingForUpdate => {
12956                            proto::ServerBinaryStatus::CheckingForUpdate
12957                        }
12958                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12959                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12960                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12961                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12962                        BinaryStatus::Failed { error } => {
12963                            message = Some(error);
12964                            proto::ServerBinaryStatus::Failed
12965                        }
12966                    };
12967                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12968                        // Binary updates are about the binary that might not have any language server id at that point.
12969                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12970                        language_server_id: LanguageServerId(0),
12971                        name: Some(server_name),
12972                        message: proto::update_language_server::Variant::StatusUpdate(
12973                            proto::StatusUpdate {
12974                                message,
12975                                status: Some(proto::status_update::Status::Binary(
12976                                    binary_status as i32,
12977                                )),
12978                            },
12979                        ),
12980                    });
12981                })
12982                .is_err()
12983            {
12984                break;
12985            }
12986        }
12987    })
12988}
12989
12990fn lsp_workspace_diagnostics_refresh(
12991    registration_id: Option<String>,
12992    options: DiagnosticServerCapabilities,
12993    server: Arc<LanguageServer>,
12994    cx: &mut Context<'_, LspStore>,
12995) -> Option<WorkspaceRefreshTask> {
12996    let identifier = workspace_diagnostic_identifier(&options)?;
12997    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
12998
12999    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13000    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13001    refresh_tx.try_send(()).ok();
13002
13003    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13004        let mut attempts = 0;
13005        let max_attempts = 50;
13006        let mut requests = 0;
13007
13008        loop {
13009            let Some(()) = refresh_rx.recv().await else {
13010                return;
13011            };
13012
13013            'request: loop {
13014                requests += 1;
13015                if attempts > max_attempts {
13016                    log::error!(
13017                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13018                    );
13019                    return;
13020                }
13021                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13022                cx.background_executor()
13023                    .timer(Duration::from_millis(backoff_millis))
13024                    .await;
13025                attempts += 1;
13026
13027                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13028                    lsp_store
13029                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13030                        .into_iter()
13031                        .filter_map(|(abs_path, result_id)| {
13032                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13033                            Some(lsp::PreviousResultId {
13034                                uri,
13035                                value: result_id.to_string(),
13036                            })
13037                        })
13038                        .collect()
13039                }) else {
13040                    return;
13041                };
13042
13043                let token = if let Some(registration_id) = &registration_id {
13044                    format!(
13045                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13046                        server.server_id(),
13047                    )
13048                } else {
13049                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13050                };
13051
13052                progress_rx.try_recv().ok();
13053                let timer =
13054                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13055                let progress = pin!(progress_rx.recv().fuse());
13056                let response_result = server
13057                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13058                        lsp::WorkspaceDiagnosticParams {
13059                            previous_result_ids,
13060                            identifier: identifier.clone(),
13061                            work_done_progress_params: Default::default(),
13062                            partial_result_params: lsp::PartialResultParams {
13063                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13064                            },
13065                        },
13066                        select(timer, progress).then(|either| match either {
13067                            Either::Left((message, ..)) => ready(message).left_future(),
13068                            Either::Right(..) => pending::<String>().right_future(),
13069                        }),
13070                    )
13071                    .await;
13072
13073                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13074                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13075                match response_result {
13076                    ConnectionResult::Timeout => {
13077                        log::error!("Timeout during workspace diagnostics pull");
13078                        continue 'request;
13079                    }
13080                    ConnectionResult::ConnectionReset => {
13081                        log::error!("Server closed a workspace diagnostics pull request");
13082                        continue 'request;
13083                    }
13084                    ConnectionResult::Result(Err(e)) => {
13085                        log::error!("Error during workspace diagnostics pull: {e:#}");
13086                        break 'request;
13087                    }
13088                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13089                        attempts = 0;
13090                        if lsp_store
13091                            .update(cx, |lsp_store, cx| {
13092                                lsp_store.apply_workspace_diagnostic_report(
13093                                    server.server_id(),
13094                                    pulled_diagnostics,
13095                                    registration_id_shared.clone(),
13096                                    cx,
13097                                )
13098                            })
13099                            .is_err()
13100                        {
13101                            return;
13102                        }
13103                        break 'request;
13104                    }
13105                }
13106            }
13107        }
13108    });
13109
13110    Some(WorkspaceRefreshTask {
13111        refresh_tx,
13112        progress_tx,
13113        task: workspace_query_language_server,
13114    })
13115}
13116
13117fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13118    match &options {
13119        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13120            diagnostic_options.identifier.clone()
13121        }
13122        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13123            let diagnostic_options = &registration_options.diagnostic_options;
13124            diagnostic_options.identifier.clone()
13125        }
13126    }
13127}
13128
13129fn workspace_diagnostic_identifier(
13130    options: &DiagnosticServerCapabilities,
13131) -> Option<Option<String>> {
13132    match &options {
13133        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13134            if !diagnostic_options.workspace_diagnostics {
13135                return None;
13136            }
13137            Some(diagnostic_options.identifier.clone())
13138        }
13139        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13140            let diagnostic_options = &registration_options.diagnostic_options;
13141            if !diagnostic_options.workspace_diagnostics {
13142                return None;
13143            }
13144            Some(diagnostic_options.identifier.clone())
13145        }
13146    }
13147}
13148
13149fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13150    let CompletionSource::BufferWord {
13151        word_range,
13152        resolved,
13153    } = &mut completion.source
13154    else {
13155        return;
13156    };
13157    if *resolved {
13158        return;
13159    }
13160
13161    if completion.new_text
13162        != snapshot
13163            .text_for_range(word_range.clone())
13164            .collect::<String>()
13165    {
13166        return;
13167    }
13168
13169    let mut offset = 0;
13170    for chunk in snapshot.chunks(word_range.clone(), true) {
13171        let end_offset = offset + chunk.text.len();
13172        if let Some(highlight_id) = chunk.syntax_highlight_id {
13173            completion
13174                .label
13175                .runs
13176                .push((offset..end_offset, highlight_id));
13177        }
13178        offset = end_offset;
13179    }
13180    *resolved = true;
13181}
13182
13183impl EventEmitter<LspStoreEvent> for LspStore {}
13184
13185fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13186    hover
13187        .contents
13188        .retain(|hover_block| !hover_block.text.trim().is_empty());
13189    if hover.contents.is_empty() {
13190        None
13191    } else {
13192        Some(hover)
13193    }
13194}
13195
13196async fn populate_labels_for_completions(
13197    new_completions: Vec<CoreCompletion>,
13198    language: Option<Arc<Language>>,
13199    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13200) -> Vec<Completion> {
13201    let lsp_completions = new_completions
13202        .iter()
13203        .filter_map(|new_completion| {
13204            new_completion
13205                .source
13206                .lsp_completion(true)
13207                .map(|lsp_completion| lsp_completion.into_owned())
13208        })
13209        .collect::<Vec<_>>();
13210
13211    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13212        lsp_adapter
13213            .labels_for_completions(&lsp_completions, language)
13214            .await
13215            .log_err()
13216            .unwrap_or_default()
13217    } else {
13218        Vec::new()
13219    }
13220    .into_iter()
13221    .fuse();
13222
13223    let mut completions = Vec::new();
13224    for completion in new_completions {
13225        match completion.source.lsp_completion(true) {
13226            Some(lsp_completion) => {
13227                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13228
13229                let mut label = labels.next().flatten().unwrap_or_else(|| {
13230                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13231                });
13232                ensure_uniform_list_compatible_label(&mut label);
13233                completions.push(Completion {
13234                    label,
13235                    documentation,
13236                    replace_range: completion.replace_range,
13237                    new_text: completion.new_text,
13238                    insert_text_mode: lsp_completion.insert_text_mode,
13239                    source: completion.source,
13240                    icon_path: None,
13241                    confirm: None,
13242                    match_start: None,
13243                    snippet_deduplication_key: None,
13244                });
13245            }
13246            None => {
13247                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13248                ensure_uniform_list_compatible_label(&mut label);
13249                completions.push(Completion {
13250                    label,
13251                    documentation: None,
13252                    replace_range: completion.replace_range,
13253                    new_text: completion.new_text,
13254                    source: completion.source,
13255                    insert_text_mode: None,
13256                    icon_path: None,
13257                    confirm: None,
13258                    match_start: None,
13259                    snippet_deduplication_key: None,
13260                });
13261            }
13262        }
13263    }
13264    completions
13265}
13266
13267#[derive(Debug)]
13268pub enum LanguageServerToQuery {
13269    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13270    FirstCapable,
13271    /// Query a specific language server.
13272    Other(LanguageServerId),
13273}
13274
13275#[derive(Default)]
13276struct RenamePathsWatchedForServer {
13277    did_rename: Vec<RenameActionPredicate>,
13278    will_rename: Vec<RenameActionPredicate>,
13279}
13280
13281impl RenamePathsWatchedForServer {
13282    fn with_did_rename_patterns(
13283        mut self,
13284        did_rename: Option<&FileOperationRegistrationOptions>,
13285    ) -> Self {
13286        if let Some(did_rename) = did_rename {
13287            self.did_rename = did_rename
13288                .filters
13289                .iter()
13290                .filter_map(|filter| filter.try_into().log_err())
13291                .collect();
13292        }
13293        self
13294    }
13295    fn with_will_rename_patterns(
13296        mut self,
13297        will_rename: Option<&FileOperationRegistrationOptions>,
13298    ) -> Self {
13299        if let Some(will_rename) = will_rename {
13300            self.will_rename = will_rename
13301                .filters
13302                .iter()
13303                .filter_map(|filter| filter.try_into().log_err())
13304                .collect();
13305        }
13306        self
13307    }
13308
13309    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13310        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13311    }
13312    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13313        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13314    }
13315}
13316
13317impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13318    type Error = globset::Error;
13319    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13320        Ok(Self {
13321            kind: ops.pattern.matches.clone(),
13322            glob: GlobBuilder::new(&ops.pattern.glob)
13323                .case_insensitive(
13324                    ops.pattern
13325                        .options
13326                        .as_ref()
13327                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13328                )
13329                .build()?
13330                .compile_matcher(),
13331        })
13332    }
13333}
13334struct RenameActionPredicate {
13335    glob: GlobMatcher,
13336    kind: Option<FileOperationPatternKind>,
13337}
13338
13339impl RenameActionPredicate {
13340    // Returns true if language server should be notified
13341    fn eval(&self, path: &str, is_dir: bool) -> bool {
13342        self.kind.as_ref().is_none_or(|kind| {
13343            let expected_kind = if is_dir {
13344                FileOperationPatternKind::Folder
13345            } else {
13346                FileOperationPatternKind::File
13347            };
13348            kind == &expected_kind
13349        }) && self.glob.is_match(path)
13350    }
13351}
13352
13353#[derive(Default)]
13354struct LanguageServerWatchedPaths {
13355    worktree_paths: HashMap<WorktreeId, GlobSet>,
13356    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13357}
13358
13359#[derive(Default)]
13360struct LanguageServerWatchedPathsBuilder {
13361    worktree_paths: HashMap<WorktreeId, GlobSet>,
13362    abs_paths: HashMap<Arc<Path>, GlobSet>,
13363}
13364
13365impl LanguageServerWatchedPathsBuilder {
13366    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13367        self.worktree_paths.insert(worktree_id, glob_set);
13368    }
13369    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13370        self.abs_paths.insert(path, glob_set);
13371    }
13372    fn build(
13373        self,
13374        fs: Arc<dyn Fs>,
13375        language_server_id: LanguageServerId,
13376        cx: &mut Context<LspStore>,
13377    ) -> LanguageServerWatchedPaths {
13378        let lsp_store = cx.weak_entity();
13379
13380        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13381        let abs_paths = self
13382            .abs_paths
13383            .into_iter()
13384            .map(|(abs_path, globset)| {
13385                let task = cx.spawn({
13386                    let abs_path = abs_path.clone();
13387                    let fs = fs.clone();
13388
13389                    let lsp_store = lsp_store.clone();
13390                    async move |_, cx| {
13391                        maybe!(async move {
13392                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13393                            while let Some(update) = push_updates.0.next().await {
13394                                let action = lsp_store
13395                                    .update(cx, |this, _| {
13396                                        let Some(local) = this.as_local() else {
13397                                            return ControlFlow::Break(());
13398                                        };
13399                                        let Some(watcher) = local
13400                                            .language_server_watched_paths
13401                                            .get(&language_server_id)
13402                                        else {
13403                                            return ControlFlow::Break(());
13404                                        };
13405                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13406                                            "Watched abs path is not registered with a watcher",
13407                                        );
13408                                        let matching_entries = update
13409                                            .into_iter()
13410                                            .filter(|event| globs.is_match(&event.path))
13411                                            .collect::<Vec<_>>();
13412                                        this.lsp_notify_abs_paths_changed(
13413                                            language_server_id,
13414                                            matching_entries,
13415                                        );
13416                                        ControlFlow::Continue(())
13417                                    })
13418                                    .ok()?;
13419
13420                                if action.is_break() {
13421                                    break;
13422                                }
13423                            }
13424                            Some(())
13425                        })
13426                        .await;
13427                    }
13428                });
13429                (abs_path, (globset, task))
13430            })
13431            .collect();
13432        LanguageServerWatchedPaths {
13433            worktree_paths: self.worktree_paths,
13434            abs_paths,
13435        }
13436    }
13437}
13438
13439struct LspBufferSnapshot {
13440    version: i32,
13441    snapshot: TextBufferSnapshot,
13442}
13443
13444/// A prompt requested by LSP server.
13445#[derive(Clone, Debug)]
13446pub struct LanguageServerPromptRequest {
13447    pub level: PromptLevel,
13448    pub message: String,
13449    pub actions: Vec<MessageActionItem>,
13450    pub lsp_name: String,
13451    pub(crate) response_channel: Sender<MessageActionItem>,
13452}
13453
13454impl LanguageServerPromptRequest {
13455    pub async fn respond(self, index: usize) -> Option<()> {
13456        if let Some(response) = self.actions.into_iter().nth(index) {
13457            self.response_channel.send(response).await.ok()
13458        } else {
13459            None
13460        }
13461    }
13462}
13463impl PartialEq for LanguageServerPromptRequest {
13464    fn eq(&self, other: &Self) -> bool {
13465        self.message == other.message && self.actions == other.actions
13466    }
13467}
13468
13469#[derive(Clone, Debug, PartialEq)]
13470pub enum LanguageServerLogType {
13471    Log(MessageType),
13472    Trace { verbose_info: Option<String> },
13473    Rpc { received: bool },
13474}
13475
13476impl LanguageServerLogType {
13477    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13478        match self {
13479            Self::Log(log_type) => {
13480                use proto::log_message::LogLevel;
13481                let level = match *log_type {
13482                    MessageType::ERROR => LogLevel::Error,
13483                    MessageType::WARNING => LogLevel::Warning,
13484                    MessageType::INFO => LogLevel::Info,
13485                    MessageType::LOG => LogLevel::Log,
13486                    other => {
13487                        log::warn!("Unknown lsp log message type: {other:?}");
13488                        LogLevel::Log
13489                    }
13490                };
13491                proto::language_server_log::LogType::Log(proto::LogMessage {
13492                    level: level as i32,
13493                })
13494            }
13495            Self::Trace { verbose_info } => {
13496                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13497                    verbose_info: verbose_info.to_owned(),
13498                })
13499            }
13500            Self::Rpc { received } => {
13501                let kind = if *received {
13502                    proto::rpc_message::Kind::Received
13503                } else {
13504                    proto::rpc_message::Kind::Sent
13505                };
13506                let kind = kind as i32;
13507                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13508            }
13509        }
13510    }
13511
13512    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13513        use proto::log_message::LogLevel;
13514        use proto::rpc_message;
13515        match log_type {
13516            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13517                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13518                    LogLevel::Error => MessageType::ERROR,
13519                    LogLevel::Warning => MessageType::WARNING,
13520                    LogLevel::Info => MessageType::INFO,
13521                    LogLevel::Log => MessageType::LOG,
13522                },
13523            ),
13524            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13525                verbose_info: trace_message.verbose_info,
13526            },
13527            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13528                received: match rpc_message::Kind::from_i32(message.kind)
13529                    .unwrap_or(rpc_message::Kind::Received)
13530                {
13531                    rpc_message::Kind::Received => true,
13532                    rpc_message::Kind::Sent => false,
13533                },
13534            },
13535        }
13536    }
13537}
13538
13539pub struct WorkspaceRefreshTask {
13540    refresh_tx: mpsc::Sender<()>,
13541    progress_tx: mpsc::Sender<()>,
13542    #[allow(dead_code)]
13543    task: Task<()>,
13544}
13545
13546pub enum LanguageServerState {
13547    Starting {
13548        startup: Task<Option<Arc<LanguageServer>>>,
13549        /// List of language servers that will be added to the workspace once it's initialization completes.
13550        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13551    },
13552
13553    Running {
13554        adapter: Arc<CachedLspAdapter>,
13555        server: Arc<LanguageServer>,
13556        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13557        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13558    },
13559}
13560
13561impl LanguageServerState {
13562    fn add_workspace_folder(&self, uri: Uri) {
13563        match self {
13564            LanguageServerState::Starting {
13565                pending_workspace_folders,
13566                ..
13567            } => {
13568                pending_workspace_folders.lock().insert(uri);
13569            }
13570            LanguageServerState::Running { server, .. } => {
13571                server.add_workspace_folder(uri);
13572            }
13573        }
13574    }
13575    fn _remove_workspace_folder(&self, uri: Uri) {
13576        match self {
13577            LanguageServerState::Starting {
13578                pending_workspace_folders,
13579                ..
13580            } => {
13581                pending_workspace_folders.lock().remove(&uri);
13582            }
13583            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13584        }
13585    }
13586}
13587
13588impl std::fmt::Debug for LanguageServerState {
13589    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13590        match self {
13591            LanguageServerState::Starting { .. } => {
13592                f.debug_struct("LanguageServerState::Starting").finish()
13593            }
13594            LanguageServerState::Running { .. } => {
13595                f.debug_struct("LanguageServerState::Running").finish()
13596            }
13597        }
13598    }
13599}
13600
13601#[derive(Clone, Debug, Serialize)]
13602pub struct LanguageServerProgress {
13603    pub is_disk_based_diagnostics_progress: bool,
13604    pub is_cancellable: bool,
13605    pub title: Option<String>,
13606    pub message: Option<String>,
13607    pub percentage: Option<usize>,
13608    #[serde(skip_serializing)]
13609    pub last_update_at: Instant,
13610}
13611
13612#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13613pub struct DiagnosticSummary {
13614    pub error_count: usize,
13615    pub warning_count: usize,
13616}
13617
13618impl DiagnosticSummary {
13619    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13620        let mut this = Self {
13621            error_count: 0,
13622            warning_count: 0,
13623        };
13624
13625        for entry in diagnostics {
13626            if entry.diagnostic.is_primary {
13627                match entry.diagnostic.severity {
13628                    DiagnosticSeverity::ERROR => this.error_count += 1,
13629                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13630                    _ => {}
13631                }
13632            }
13633        }
13634
13635        this
13636    }
13637
13638    pub fn is_empty(&self) -> bool {
13639        self.error_count == 0 && self.warning_count == 0
13640    }
13641
13642    pub fn to_proto(
13643        self,
13644        language_server_id: LanguageServerId,
13645        path: &RelPath,
13646    ) -> proto::DiagnosticSummary {
13647        proto::DiagnosticSummary {
13648            path: path.to_proto(),
13649            language_server_id: language_server_id.0 as u64,
13650            error_count: self.error_count as u32,
13651            warning_count: self.warning_count as u32,
13652        }
13653    }
13654}
13655
13656#[derive(Clone, Debug)]
13657pub enum CompletionDocumentation {
13658    /// There is no documentation for this completion.
13659    Undocumented,
13660    /// A single line of documentation.
13661    SingleLine(SharedString),
13662    /// Multiple lines of plain text documentation.
13663    MultiLinePlainText(SharedString),
13664    /// Markdown documentation.
13665    MultiLineMarkdown(SharedString),
13666    /// Both single line and multiple lines of plain text documentation.
13667    SingleLineAndMultiLinePlainText {
13668        single_line: SharedString,
13669        plain_text: Option<SharedString>,
13670    },
13671}
13672
13673impl CompletionDocumentation {
13674    #[cfg(any(test, feature = "test-support"))]
13675    pub fn text(&self) -> SharedString {
13676        match self {
13677            CompletionDocumentation::Undocumented => "".into(),
13678            CompletionDocumentation::SingleLine(s) => s.clone(),
13679            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13680            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13681            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13682                single_line.clone()
13683            }
13684        }
13685    }
13686}
13687
13688impl From<lsp::Documentation> for CompletionDocumentation {
13689    fn from(docs: lsp::Documentation) -> Self {
13690        match docs {
13691            lsp::Documentation::String(text) => {
13692                if text.lines().count() <= 1 {
13693                    CompletionDocumentation::SingleLine(text.into())
13694                } else {
13695                    CompletionDocumentation::MultiLinePlainText(text.into())
13696                }
13697            }
13698
13699            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13700                lsp::MarkupKind::PlainText => {
13701                    if value.lines().count() <= 1 {
13702                        CompletionDocumentation::SingleLine(value.into())
13703                    } else {
13704                        CompletionDocumentation::MultiLinePlainText(value.into())
13705                    }
13706                }
13707
13708                lsp::MarkupKind::Markdown => {
13709                    CompletionDocumentation::MultiLineMarkdown(value.into())
13710                }
13711            },
13712        }
13713    }
13714}
13715
13716pub enum ResolvedHint {
13717    Resolved(InlayHint),
13718    Resolving(Shared<Task<()>>),
13719}
13720
13721fn glob_literal_prefix(glob: &Path) -> PathBuf {
13722    glob.components()
13723        .take_while(|component| match component {
13724            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13725            _ => true,
13726        })
13727        .collect()
13728}
13729
13730pub struct SshLspAdapter {
13731    name: LanguageServerName,
13732    binary: LanguageServerBinary,
13733    initialization_options: Option<String>,
13734    code_action_kinds: Option<Vec<CodeActionKind>>,
13735}
13736
13737impl SshLspAdapter {
13738    pub fn new(
13739        name: LanguageServerName,
13740        binary: LanguageServerBinary,
13741        initialization_options: Option<String>,
13742        code_action_kinds: Option<String>,
13743    ) -> Self {
13744        Self {
13745            name,
13746            binary,
13747            initialization_options,
13748            code_action_kinds: code_action_kinds
13749                .as_ref()
13750                .and_then(|c| serde_json::from_str(c).ok()),
13751        }
13752    }
13753}
13754
13755impl LspInstaller for SshLspAdapter {
13756    type BinaryVersion = ();
13757    async fn check_if_user_installed(
13758        &self,
13759        _: &dyn LspAdapterDelegate,
13760        _: Option<Toolchain>,
13761        _: &AsyncApp,
13762    ) -> Option<LanguageServerBinary> {
13763        Some(self.binary.clone())
13764    }
13765
13766    async fn cached_server_binary(
13767        &self,
13768        _: PathBuf,
13769        _: &dyn LspAdapterDelegate,
13770    ) -> Option<LanguageServerBinary> {
13771        None
13772    }
13773
13774    async fn fetch_latest_server_version(
13775        &self,
13776        _: &dyn LspAdapterDelegate,
13777        _: bool,
13778        _: &mut AsyncApp,
13779    ) -> Result<()> {
13780        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13781    }
13782
13783    async fn fetch_server_binary(
13784        &self,
13785        _: (),
13786        _: PathBuf,
13787        _: &dyn LspAdapterDelegate,
13788    ) -> Result<LanguageServerBinary> {
13789        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13790    }
13791}
13792
13793#[async_trait(?Send)]
13794impl LspAdapter for SshLspAdapter {
13795    fn name(&self) -> LanguageServerName {
13796        self.name.clone()
13797    }
13798
13799    async fn initialization_options(
13800        self: Arc<Self>,
13801        _: &Arc<dyn LspAdapterDelegate>,
13802    ) -> Result<Option<serde_json::Value>> {
13803        let Some(options) = &self.initialization_options else {
13804            return Ok(None);
13805        };
13806        let result = serde_json::from_str(options)?;
13807        Ok(result)
13808    }
13809
13810    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13811        self.code_action_kinds.clone()
13812    }
13813}
13814
13815pub fn language_server_settings<'a>(
13816    delegate: &'a dyn LspAdapterDelegate,
13817    language: &LanguageServerName,
13818    cx: &'a App,
13819) -> Option<&'a LspSettings> {
13820    language_server_settings_for(
13821        SettingsLocation {
13822            worktree_id: delegate.worktree_id(),
13823            path: RelPath::empty(),
13824        },
13825        language,
13826        cx,
13827    )
13828}
13829
13830pub fn language_server_settings_for<'a>(
13831    location: SettingsLocation<'a>,
13832    language: &LanguageServerName,
13833    cx: &'a App,
13834) -> Option<&'a LspSettings> {
13835    ProjectSettings::get(Some(location), cx).lsp.get(language)
13836}
13837
13838pub struct LocalLspAdapterDelegate {
13839    lsp_store: WeakEntity<LspStore>,
13840    worktree: worktree::Snapshot,
13841    fs: Arc<dyn Fs>,
13842    http_client: Arc<dyn HttpClient>,
13843    language_registry: Arc<LanguageRegistry>,
13844    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13845}
13846
13847impl LocalLspAdapterDelegate {
13848    pub fn new(
13849        language_registry: Arc<LanguageRegistry>,
13850        environment: &Entity<ProjectEnvironment>,
13851        lsp_store: WeakEntity<LspStore>,
13852        worktree: &Entity<Worktree>,
13853        http_client: Arc<dyn HttpClient>,
13854        fs: Arc<dyn Fs>,
13855        cx: &mut App,
13856    ) -> Arc<Self> {
13857        let load_shell_env_task =
13858            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13859
13860        Arc::new(Self {
13861            lsp_store,
13862            worktree: worktree.read(cx).snapshot(),
13863            fs,
13864            http_client,
13865            language_registry,
13866            load_shell_env_task,
13867        })
13868    }
13869
13870    fn from_local_lsp(
13871        local: &LocalLspStore,
13872        worktree: &Entity<Worktree>,
13873        cx: &mut App,
13874    ) -> Arc<Self> {
13875        Self::new(
13876            local.languages.clone(),
13877            &local.environment,
13878            local.weak.clone(),
13879            worktree,
13880            local.http_client.clone(),
13881            local.fs.clone(),
13882            cx,
13883        )
13884    }
13885}
13886
13887#[async_trait]
13888impl LspAdapterDelegate for LocalLspAdapterDelegate {
13889    fn show_notification(&self, message: &str, cx: &mut App) {
13890        self.lsp_store
13891            .update(cx, |_, cx| {
13892                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13893            })
13894            .ok();
13895    }
13896
13897    fn http_client(&self) -> Arc<dyn HttpClient> {
13898        self.http_client.clone()
13899    }
13900
13901    fn worktree_id(&self) -> WorktreeId {
13902        self.worktree.id()
13903    }
13904
13905    fn worktree_root_path(&self) -> &Path {
13906        self.worktree.abs_path().as_ref()
13907    }
13908
13909    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13910        self.worktree.resolve_executable_path(path)
13911    }
13912
13913    async fn shell_env(&self) -> HashMap<String, String> {
13914        let task = self.load_shell_env_task.clone();
13915        task.await.unwrap_or_default()
13916    }
13917
13918    async fn npm_package_installed_version(
13919        &self,
13920        package_name: &str,
13921    ) -> Result<Option<(PathBuf, String)>> {
13922        let local_package_directory = self.worktree_root_path();
13923        let node_modules_directory = local_package_directory.join("node_modules");
13924
13925        if let Some(version) =
13926            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13927        {
13928            return Ok(Some((node_modules_directory, version)));
13929        }
13930        let Some(npm) = self.which("npm".as_ref()).await else {
13931            log::warn!(
13932                "Failed to find npm executable for {:?}",
13933                local_package_directory
13934            );
13935            return Ok(None);
13936        };
13937
13938        let env = self.shell_env().await;
13939        let output = util::command::new_smol_command(&npm)
13940            .args(["root", "-g"])
13941            .envs(env)
13942            .current_dir(local_package_directory)
13943            .output()
13944            .await?;
13945        let global_node_modules =
13946            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13947
13948        if let Some(version) =
13949            read_package_installed_version(global_node_modules.clone(), package_name).await?
13950        {
13951            return Ok(Some((global_node_modules, version)));
13952        }
13953        return Ok(None);
13954    }
13955
13956    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13957        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13958        if self.fs.is_file(&worktree_abs_path).await {
13959            worktree_abs_path.pop();
13960        }
13961
13962        let env = self.shell_env().await;
13963
13964        let shell_path = env.get("PATH").cloned();
13965
13966        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13967    }
13968
13969    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13970        let mut working_dir = self.worktree_root_path().to_path_buf();
13971        if self.fs.is_file(&working_dir).await {
13972            working_dir.pop();
13973        }
13974        let output = util::command::new_smol_command(&command.path)
13975            .args(command.arguments)
13976            .envs(command.env.clone().unwrap_or_default())
13977            .current_dir(working_dir)
13978            .output()
13979            .await?;
13980
13981        anyhow::ensure!(
13982            output.status.success(),
13983            "{}, stdout: {:?}, stderr: {:?}",
13984            output.status,
13985            String::from_utf8_lossy(&output.stdout),
13986            String::from_utf8_lossy(&output.stderr)
13987        );
13988        Ok(())
13989    }
13990
13991    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13992        self.language_registry
13993            .update_lsp_binary_status(server_name, status);
13994    }
13995
13996    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13997        self.language_registry
13998            .all_lsp_adapters()
13999            .into_iter()
14000            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14001            .collect()
14002    }
14003
14004    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14005        let dir = self.language_registry.language_server_download_dir(name)?;
14006
14007        if !dir.exists() {
14008            smol::fs::create_dir_all(&dir)
14009                .await
14010                .context("failed to create container directory")
14011                .log_err()?;
14012        }
14013
14014        Some(dir)
14015    }
14016
14017    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14018        let entry = self
14019            .worktree
14020            .entry_for_path(path)
14021            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14022        let abs_path = self.worktree.absolutize(&entry.path);
14023        self.fs.load(&abs_path).await
14024    }
14025}
14026
14027async fn populate_labels_for_symbols(
14028    symbols: Vec<CoreSymbol>,
14029    language_registry: &Arc<LanguageRegistry>,
14030    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14031    output: &mut Vec<Symbol>,
14032) {
14033    #[allow(clippy::mutable_key_type)]
14034    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14035
14036    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14037    for symbol in symbols {
14038        let Some(file_name) = symbol.path.file_name() else {
14039            continue;
14040        };
14041        let language = language_registry
14042            .load_language_for_file_path(Path::new(file_name))
14043            .await
14044            .ok()
14045            .or_else(|| {
14046                unknown_paths.insert(file_name.into());
14047                None
14048            });
14049        symbols_by_language
14050            .entry(language)
14051            .or_default()
14052            .push(symbol);
14053    }
14054
14055    for unknown_path in unknown_paths {
14056        log::info!("no language found for symbol in file {unknown_path:?}");
14057    }
14058
14059    let mut label_params = Vec::new();
14060    for (language, mut symbols) in symbols_by_language {
14061        label_params.clear();
14062        label_params.extend(
14063            symbols
14064                .iter_mut()
14065                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14066        );
14067
14068        let mut labels = Vec::new();
14069        if let Some(language) = language {
14070            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14071                language_registry
14072                    .lsp_adapters(&language.name())
14073                    .first()
14074                    .cloned()
14075            });
14076            if let Some(lsp_adapter) = lsp_adapter {
14077                labels = lsp_adapter
14078                    .labels_for_symbols(&label_params, &language)
14079                    .await
14080                    .log_err()
14081                    .unwrap_or_default();
14082            }
14083        }
14084
14085        for ((symbol, (name, _)), label) in symbols
14086            .into_iter()
14087            .zip(label_params.drain(..))
14088            .zip(labels.into_iter().chain(iter::repeat(None)))
14089        {
14090            output.push(Symbol {
14091                language_server_name: symbol.language_server_name,
14092                source_worktree_id: symbol.source_worktree_id,
14093                source_language_server_id: symbol.source_language_server_id,
14094                path: symbol.path,
14095                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14096                name,
14097                kind: symbol.kind,
14098                range: symbol.range,
14099            });
14100        }
14101    }
14102}
14103
14104fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14105    match server.capabilities().text_document_sync.as_ref()? {
14106        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14107            // Server wants didSave but didn't specify includeText.
14108            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14109            // Server doesn't want didSave at all.
14110            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14111            // Server provided SaveOptions.
14112            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14113                Some(save_options.include_text.unwrap_or(false))
14114            }
14115        },
14116        // We do not have any save info. Kind affects didChange only.
14117        lsp::TextDocumentSyncCapability::Kind(_) => None,
14118    }
14119}
14120
14121/// Completion items are displayed in a `UniformList`.
14122/// Usually, those items are single-line strings, but in LSP responses,
14123/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14124/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14125/// 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,
14126/// breaking the completions menu presentation.
14127///
14128/// 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.
14129fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14130    let mut new_text = String::with_capacity(label.text.len());
14131    let mut offset_map = vec![0; label.text.len() + 1];
14132    let mut last_char_was_space = false;
14133    let mut new_idx = 0;
14134    let chars = label.text.char_indices().fuse();
14135    let mut newlines_removed = false;
14136
14137    for (idx, c) in chars {
14138        offset_map[idx] = new_idx;
14139
14140        match c {
14141            '\n' if last_char_was_space => {
14142                newlines_removed = true;
14143            }
14144            '\t' | ' ' if last_char_was_space => {}
14145            '\n' if !last_char_was_space => {
14146                new_text.push(' ');
14147                new_idx += 1;
14148                last_char_was_space = true;
14149                newlines_removed = true;
14150            }
14151            ' ' | '\t' => {
14152                new_text.push(' ');
14153                new_idx += 1;
14154                last_char_was_space = true;
14155            }
14156            _ => {
14157                new_text.push(c);
14158                new_idx += c.len_utf8();
14159                last_char_was_space = false;
14160            }
14161        }
14162    }
14163    offset_map[label.text.len()] = new_idx;
14164
14165    // Only modify the label if newlines were removed.
14166    if !newlines_removed {
14167        return;
14168    }
14169
14170    let last_index = new_idx;
14171    let mut run_ranges_errors = Vec::new();
14172    label.runs.retain_mut(|(range, _)| {
14173        match offset_map.get(range.start) {
14174            Some(&start) => range.start = start,
14175            None => {
14176                run_ranges_errors.push(range.clone());
14177                return false;
14178            }
14179        }
14180
14181        match offset_map.get(range.end) {
14182            Some(&end) => range.end = end,
14183            None => {
14184                run_ranges_errors.push(range.clone());
14185                range.end = last_index;
14186            }
14187        }
14188        true
14189    });
14190    if !run_ranges_errors.is_empty() {
14191        log::error!(
14192            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14193            label.text
14194        );
14195    }
14196
14197    let mut wrong_filter_range = None;
14198    if label.filter_range == (0..label.text.len()) {
14199        label.filter_range = 0..new_text.len();
14200    } else {
14201        let mut original_filter_range = Some(label.filter_range.clone());
14202        match offset_map.get(label.filter_range.start) {
14203            Some(&start) => label.filter_range.start = start,
14204            None => {
14205                wrong_filter_range = original_filter_range.take();
14206                label.filter_range.start = last_index;
14207            }
14208        }
14209
14210        match offset_map.get(label.filter_range.end) {
14211            Some(&end) => label.filter_range.end = end,
14212            None => {
14213                wrong_filter_range = original_filter_range.take();
14214                label.filter_range.end = last_index;
14215            }
14216        }
14217    }
14218    if let Some(wrong_filter_range) = wrong_filter_range {
14219        log::error!(
14220            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14221            label.text
14222        );
14223    }
14224
14225    label.text = new_text;
14226}
14227
14228#[cfg(test)]
14229mod tests {
14230    use language::HighlightId;
14231
14232    use super::*;
14233
14234    #[test]
14235    fn test_glob_literal_prefix() {
14236        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14237        assert_eq!(
14238            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14239            Path::new("node_modules")
14240        );
14241        assert_eq!(
14242            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14243            Path::new("foo")
14244        );
14245        assert_eq!(
14246            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14247            Path::new("foo/bar/baz.js")
14248        );
14249
14250        #[cfg(target_os = "windows")]
14251        {
14252            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14253            assert_eq!(
14254                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14255                Path::new("node_modules")
14256            );
14257            assert_eq!(
14258                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14259                Path::new("foo")
14260            );
14261            assert_eq!(
14262                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14263                Path::new("foo/bar/baz.js")
14264            );
14265        }
14266    }
14267
14268    #[test]
14269    fn test_multi_len_chars_normalization() {
14270        let mut label = CodeLabel::new(
14271            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14272            0..6,
14273            vec![(0..6, HighlightId(1))],
14274        );
14275        ensure_uniform_list_compatible_label(&mut label);
14276        assert_eq!(
14277            label,
14278            CodeLabel::new(
14279                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14280                0..6,
14281                vec![(0..6, HighlightId(1))],
14282            )
14283        );
14284    }
14285}