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