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                .await
  429            }
  430        });
  431
  432        let startup = {
  433            let server_name = adapter.name.0.clone();
  434            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  435            let key = key.clone();
  436            let adapter = adapter.clone();
  437            let lsp_store = self.weak.clone();
  438            let pending_workspace_folders = pending_workspace_folders.clone();
  439
  440            let pull_diagnostics = ProjectSettings::get_global(cx)
  441                .diagnostics
  442                .lsp_pull_diagnostics
  443                .enabled;
  444            cx.spawn(async move |cx| {
  445                let result = async {
  446                    let language_server = pending_server.await?;
  447
  448                    let workspace_config = Self::workspace_configuration_for_adapter(
  449                        adapter.adapter.clone(),
  450                        &delegate,
  451                        toolchain,
  452                        None,
  453                        cx,
  454                    )
  455                    .await?;
  456
  457                    let mut initialization_options = Self::initialization_options_for_adapter(
  458                        adapter.adapter.clone(),
  459                        &delegate,
  460                    )
  461                    .await?;
  462
  463                    match (&mut initialization_options, override_options) {
  464                        (Some(initialization_options), Some(override_options)) => {
  465                            merge_json_value_into(override_options, initialization_options);
  466                        }
  467                        (None, override_options) => initialization_options = override_options,
  468                        _ => {}
  469                    }
  470
  471                    let initialization_params = cx.update(|cx| {
  472                        let mut params =
  473                            language_server.default_initialize_params(pull_diagnostics, cx);
  474                        params.initialization_options = initialization_options;
  475                        adapter.adapter.prepare_initialize_params(params, cx)
  476                    })??;
  477
  478                    Self::setup_lsp_messages(
  479                        lsp_store.clone(),
  480                        &language_server,
  481                        delegate.clone(),
  482                        adapter.clone(),
  483                    );
  484
  485                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  486                        settings: workspace_config,
  487                    };
  488                    let language_server = cx
  489                        .update(|cx| {
  490                            language_server.initialize(
  491                                initialization_params,
  492                                Arc::new(did_change_configuration_params.clone()),
  493                                cx,
  494                            )
  495                        })?
  496                        .await
  497                        .inspect_err(|_| {
  498                            if let Some(lsp_store) = lsp_store.upgrade() {
  499                                lsp_store
  500                                    .update(cx, |lsp_store, cx| {
  501                                        lsp_store.cleanup_lsp_data(server_id);
  502                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  503                                    })
  504                                    .ok();
  505                            }
  506                        })?;
  507
  508                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  509                        did_change_configuration_params,
  510                    )?;
  511
  512                    anyhow::Ok(language_server)
  513                }
  514                .await;
  515
  516                match result {
  517                    Ok(server) => {
  518                        lsp_store
  519                            .update(cx, |lsp_store, cx| {
  520                                lsp_store.insert_newly_running_language_server(
  521                                    adapter,
  522                                    server.clone(),
  523                                    server_id,
  524                                    key,
  525                                    pending_workspace_folders,
  526                                    cx,
  527                                );
  528                            })
  529                            .ok();
  530                        stderr_capture.lock().take();
  531                        Some(server)
  532                    }
  533
  534                    Err(err) => {
  535                        let log = stderr_capture.lock().take().unwrap_or_default();
  536                        delegate.update_status(
  537                            adapter.name(),
  538                            BinaryStatus::Failed {
  539                                error: if log.is_empty() {
  540                                    format!("{err:#}")
  541                                } else {
  542                                    format!("{err:#}\n-- stderr --\n{log}")
  543                                },
  544                            },
  545                        );
  546                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  547                        if !log.is_empty() {
  548                            log::error!("server stderr: {log}");
  549                        }
  550                        None
  551                    }
  552                }
  553            })
  554        };
  555        let state = LanguageServerState::Starting {
  556            startup,
  557            pending_workspace_folders,
  558        };
  559
  560        self.languages
  561            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  562
  563        self.language_servers.insert(server_id, state);
  564        self.language_server_ids
  565            .entry(key)
  566            .or_insert(UnifiedLanguageServer {
  567                id: server_id,
  568                project_roots: Default::default(),
  569            });
  570        server_id
  571    }
  572
  573    fn get_language_server_binary(
  574        &self,
  575        adapter: Arc<CachedLspAdapter>,
  576        settings: Arc<LspSettings>,
  577        toolchain: Option<Toolchain>,
  578        delegate: Arc<dyn LspAdapterDelegate>,
  579        allow_binary_download: bool,
  580        cx: &mut App,
  581    ) -> Task<Result<LanguageServerBinary>> {
  582        if let Some(settings) = &settings.binary
  583            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  584        {
  585            let settings = settings.clone();
  586
  587            return cx.background_spawn(async move {
  588                let mut env = delegate.shell_env().await;
  589                env.extend(settings.env.unwrap_or_default());
  590
  591                Ok(LanguageServerBinary {
  592                    path: delegate.resolve_executable_path(path),
  593                    env: Some(env),
  594                    arguments: settings
  595                        .arguments
  596                        .unwrap_or_default()
  597                        .iter()
  598                        .map(Into::into)
  599                        .collect(),
  600                })
  601            });
  602        }
  603        let lsp_binary_options = LanguageServerBinaryOptions {
  604            allow_path_lookup: !settings
  605                .binary
  606                .as_ref()
  607                .and_then(|b| b.ignore_system_version)
  608                .unwrap_or_default(),
  609            allow_binary_download,
  610            pre_release: settings
  611                .fetch
  612                .as_ref()
  613                .and_then(|f| f.pre_release)
  614                .unwrap_or(false),
  615        };
  616
  617        cx.spawn(async move |cx| {
  618            let (existing_binary, maybe_download_binary) = adapter
  619                .clone()
  620                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  621                .await
  622                .await;
  623
  624            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  625
  626            let mut binary = match (existing_binary, maybe_download_binary) {
  627                (binary, None) => binary?,
  628                (Err(_), Some(downloader)) => downloader.await?,
  629                (Ok(existing_binary), Some(downloader)) => {
  630                    let mut download_timeout = cx
  631                        .background_executor()
  632                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  633                        .fuse();
  634                    let mut downloader = downloader.fuse();
  635                    futures::select! {
  636                        _ = download_timeout => {
  637                            // Return existing binary and kick the existing work to the background.
  638                            cx.spawn(async move |_| downloader.await).detach();
  639                            Ok(existing_binary)
  640                        },
  641                        downloaded_or_existing_binary = downloader => {
  642                            // If download fails, this results in the existing binary.
  643                            downloaded_or_existing_binary
  644                        }
  645                    }?
  646                }
  647            };
  648            let mut shell_env = delegate.shell_env().await;
  649
  650            shell_env.extend(binary.env.unwrap_or_default());
  651
  652            if let Some(settings) = settings.binary.as_ref() {
  653                if let Some(arguments) = &settings.arguments {
  654                    binary.arguments = arguments.iter().map(Into::into).collect();
  655                }
  656                if let Some(env) = &settings.env {
  657                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  658                }
  659            }
  660
  661            binary.env = Some(shell_env);
  662            Ok(binary)
  663        })
  664    }
  665
  666    fn setup_lsp_messages(
  667        lsp_store: WeakEntity<LspStore>,
  668        language_server: &LanguageServer,
  669        delegate: Arc<dyn LspAdapterDelegate>,
  670        adapter: Arc<CachedLspAdapter>,
  671    ) {
  672        let name = language_server.name();
  673        let server_id = language_server.server_id();
  674        language_server
  675            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  676                let adapter = adapter.clone();
  677                let this = lsp_store.clone();
  678                move |mut params, cx| {
  679                    let adapter = adapter.clone();
  680                    if let Some(this) = this.upgrade() {
  681                        this.update(cx, |this, cx| {
  682                            {
  683                                let buffer = params
  684                                    .uri
  685                                    .to_file_path()
  686                                    .map(|file_path| this.get_buffer(&file_path, cx))
  687                                    .ok()
  688                                    .flatten();
  689                                adapter.process_diagnostics(&mut params, server_id, buffer);
  690                            }
  691
  692                            this.merge_lsp_diagnostics(
  693                                DiagnosticSourceKind::Pushed,
  694                                vec![DocumentDiagnosticsUpdate {
  695                                    server_id,
  696                                    diagnostics: params,
  697                                    result_id: None,
  698                                    disk_based_sources: Cow::Borrowed(
  699                                        &adapter.disk_based_diagnostic_sources,
  700                                    ),
  701                                    registration_id: None,
  702                                }],
  703                                |_, diagnostic, cx| match diagnostic.source_kind {
  704                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  705                                        adapter.retain_old_diagnostic(diagnostic, cx)
  706                                    }
  707                                    DiagnosticSourceKind::Pulled => true,
  708                                },
  709                                cx,
  710                            )
  711                            .log_err();
  712                        })
  713                        .ok();
  714                    }
  715                }
  716            })
  717            .detach();
  718        language_server
  719            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  720                let adapter = adapter.adapter.clone();
  721                let delegate = delegate.clone();
  722                let this = lsp_store.clone();
  723                move |params, cx| {
  724                    let adapter = adapter.clone();
  725                    let delegate = delegate.clone();
  726                    let this = this.clone();
  727                    let mut cx = cx.clone();
  728                    async move {
  729                        let toolchain_for_id = this
  730                            .update(&mut cx, |this, _| {
  731                                this.as_local()?.language_server_ids.iter().find_map(
  732                                    |(seed, value)| {
  733                                        (value.id == server_id).then(|| seed.toolchain.clone())
  734                                    },
  735                                )
  736                            })?
  737                            .context("Expected the LSP store to be in a local mode")?;
  738
  739                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  740                        for item in &params.items {
  741                            let scope_uri = item.scope_uri.clone();
  742                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  743                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  744                            else {
  745                                // We've already queried workspace configuration of this URI.
  746                                continue;
  747                            };
  748                            let workspace_config = Self::workspace_configuration_for_adapter(
  749                                adapter.clone(),
  750                                &delegate,
  751                                toolchain_for_id.clone(),
  752                                scope_uri,
  753                                &mut cx,
  754                            )
  755                            .await?;
  756                            new_scope_uri.insert(workspace_config);
  757                        }
  758
  759                        Ok(params
  760                            .items
  761                            .into_iter()
  762                            .filter_map(|item| {
  763                                let workspace_config =
  764                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  765                                if let Some(section) = &item.section {
  766                                    Some(
  767                                        workspace_config
  768                                            .get(section)
  769                                            .cloned()
  770                                            .unwrap_or(serde_json::Value::Null),
  771                                    )
  772                                } else {
  773                                    Some(workspace_config.clone())
  774                                }
  775                            })
  776                            .collect())
  777                    }
  778                }
  779            })
  780            .detach();
  781
  782        language_server
  783            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  784                let this = lsp_store.clone();
  785                move |_, cx| {
  786                    let this = this.clone();
  787                    let cx = cx.clone();
  788                    async move {
  789                        let Some(server) =
  790                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  791                        else {
  792                            return Ok(None);
  793                        };
  794                        let root = server.workspace_folders();
  795                        Ok(Some(
  796                            root.into_iter()
  797                                .map(|uri| WorkspaceFolder {
  798                                    uri,
  799                                    name: Default::default(),
  800                                })
  801                                .collect(),
  802                        ))
  803                    }
  804                }
  805            })
  806            .detach();
  807        // Even though we don't have handling for these requests, respond to them to
  808        // avoid stalling any language server like `gopls` which waits for a response
  809        // to these requests when initializing.
  810        language_server
  811            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  812                let this = lsp_store.clone();
  813                move |params, cx| {
  814                    let this = this.clone();
  815                    let mut cx = cx.clone();
  816                    async move {
  817                        this.update(&mut cx, |this, _| {
  818                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  819                            {
  820                                status
  821                                    .progress_tokens
  822                                    .insert(ProgressToken::from_lsp(params.token));
  823                            }
  824                        })?;
  825
  826                        Ok(())
  827                    }
  828                }
  829            })
  830            .detach();
  831
  832        language_server
  833            .on_request::<lsp::request::RegisterCapability, _, _>({
  834                let lsp_store = lsp_store.clone();
  835                move |params, cx| {
  836                    let lsp_store = lsp_store.clone();
  837                    let mut cx = cx.clone();
  838                    async move {
  839                        lsp_store
  840                            .update(&mut cx, |lsp_store, cx| {
  841                                if lsp_store.as_local().is_some() {
  842                                    match lsp_store
  843                                        .register_server_capabilities(server_id, params, cx)
  844                                    {
  845                                        Ok(()) => {}
  846                                        Err(e) => {
  847                                            log::error!(
  848                                                "Failed to register server capabilities: {e:#}"
  849                                            );
  850                                        }
  851                                    };
  852                                }
  853                            })
  854                            .ok();
  855                        Ok(())
  856                    }
  857                }
  858            })
  859            .detach();
  860
  861        language_server
  862            .on_request::<lsp::request::UnregisterCapability, _, _>({
  863                let lsp_store = lsp_store.clone();
  864                move |params, cx| {
  865                    let lsp_store = lsp_store.clone();
  866                    let mut cx = cx.clone();
  867                    async move {
  868                        lsp_store
  869                            .update(&mut cx, |lsp_store, cx| {
  870                                if lsp_store.as_local().is_some() {
  871                                    match lsp_store
  872                                        .unregister_server_capabilities(server_id, params, cx)
  873                                    {
  874                                        Ok(()) => {}
  875                                        Err(e) => {
  876                                            log::error!(
  877                                                "Failed to unregister server capabilities: {e:#}"
  878                                            );
  879                                        }
  880                                    }
  881                                }
  882                            })
  883                            .ok();
  884                        Ok(())
  885                    }
  886                }
  887            })
  888            .detach();
  889
  890        language_server
  891            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  892                let this = lsp_store.clone();
  893                move |params, cx| {
  894                    let mut cx = cx.clone();
  895                    let this = this.clone();
  896                    async move {
  897                        LocalLspStore::on_lsp_workspace_edit(
  898                            this.clone(),
  899                            params,
  900                            server_id,
  901                            &mut cx,
  902                        )
  903                        .await
  904                    }
  905                }
  906            })
  907            .detach();
  908
  909        language_server
  910            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  911                let lsp_store = lsp_store.clone();
  912                let request_id = Arc::new(AtomicUsize::new(0));
  913                move |(), cx| {
  914                    let lsp_store = lsp_store.clone();
  915                    let request_id = request_id.clone();
  916                    let mut cx = cx.clone();
  917                    async move {
  918                        lsp_store
  919                            .update(&mut cx, |lsp_store, cx| {
  920                                let request_id =
  921                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  922                                cx.emit(LspStoreEvent::RefreshInlayHints {
  923                                    server_id,
  924                                    request_id,
  925                                });
  926                                lsp_store
  927                                    .downstream_client
  928                                    .as_ref()
  929                                    .map(|(client, project_id)| {
  930                                        client.send(proto::RefreshInlayHints {
  931                                            project_id: *project_id,
  932                                            server_id: server_id.to_proto(),
  933                                            request_id: request_id.map(|id| id as u64),
  934                                        })
  935                                    })
  936                            })?
  937                            .transpose()?;
  938                        Ok(())
  939                    }
  940                }
  941            })
  942            .detach();
  943
  944        language_server
  945            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  946                let this = lsp_store.clone();
  947                move |(), cx| {
  948                    let this = this.clone();
  949                    let mut cx = cx.clone();
  950                    async move {
  951                        this.update(&mut cx, |this, cx| {
  952                            cx.emit(LspStoreEvent::RefreshCodeLens);
  953                            this.downstream_client.as_ref().map(|(client, project_id)| {
  954                                client.send(proto::RefreshCodeLens {
  955                                    project_id: *project_id,
  956                                })
  957                            })
  958                        })?
  959                        .transpose()?;
  960                        Ok(())
  961                    }
  962                }
  963            })
  964            .detach();
  965
  966        language_server
  967            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  968                let this = lsp_store.clone();
  969                move |(), cx| {
  970                    let this = this.clone();
  971                    let mut cx = cx.clone();
  972                    async move {
  973                        this.update(&mut cx, |lsp_store, _| {
  974                            lsp_store.pull_workspace_diagnostics(server_id);
  975                            lsp_store
  976                                .downstream_client
  977                                .as_ref()
  978                                .map(|(client, project_id)| {
  979                                    client.send(proto::PullWorkspaceDiagnostics {
  980                                        project_id: *project_id,
  981                                        server_id: server_id.to_proto(),
  982                                    })
  983                                })
  984                        })?
  985                        .transpose()?;
  986                        Ok(())
  987                    }
  988                }
  989            })
  990            .detach();
  991
  992        language_server
  993            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  994                let this = lsp_store.clone();
  995                let name = name.to_string();
  996                move |params, cx| {
  997                    let this = this.clone();
  998                    let name = name.to_string();
  999                    let mut cx = cx.clone();
 1000                    async move {
 1001                        let actions = params.actions.unwrap_or_default();
 1002                        let (tx, rx) = smol::channel::bounded(1);
 1003                        let request = LanguageServerPromptRequest {
 1004                            level: match params.typ {
 1005                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1006                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1007                                _ => PromptLevel::Info,
 1008                            },
 1009                            message: params.message,
 1010                            actions,
 1011                            response_channel: tx,
 1012                            lsp_name: name.clone(),
 1013                        };
 1014
 1015                        let did_update = this
 1016                            .update(&mut cx, |_, cx| {
 1017                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1018                            })
 1019                            .is_ok();
 1020                        if did_update {
 1021                            let response = rx.recv().await.ok();
 1022                            Ok(response)
 1023                        } else {
 1024                            Ok(None)
 1025                        }
 1026                    }
 1027                }
 1028            })
 1029            .detach();
 1030        language_server
 1031            .on_notification::<lsp::notification::ShowMessage, _>({
 1032                let this = lsp_store.clone();
 1033                let name = name.to_string();
 1034                move |params, cx| {
 1035                    let this = this.clone();
 1036                    let name = name.to_string();
 1037                    let mut cx = cx.clone();
 1038
 1039                    let (tx, _) = smol::channel::bounded(1);
 1040                    let request = LanguageServerPromptRequest {
 1041                        level: match params.typ {
 1042                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1043                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1044                            _ => PromptLevel::Info,
 1045                        },
 1046                        message: params.message,
 1047                        actions: vec![],
 1048                        response_channel: tx,
 1049                        lsp_name: name,
 1050                    };
 1051
 1052                    let _ = this.update(&mut cx, |_, cx| {
 1053                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1054                    });
 1055                }
 1056            })
 1057            .detach();
 1058
 1059        let disk_based_diagnostics_progress_token =
 1060            adapter.disk_based_diagnostics_progress_token.clone();
 1061
 1062        language_server
 1063            .on_notification::<lsp::notification::Progress, _>({
 1064                let this = lsp_store.clone();
 1065                move |params, cx| {
 1066                    if let Some(this) = this.upgrade() {
 1067                        this.update(cx, |this, cx| {
 1068                            this.on_lsp_progress(
 1069                                params,
 1070                                server_id,
 1071                                disk_based_diagnostics_progress_token.clone(),
 1072                                cx,
 1073                            );
 1074                        })
 1075                        .ok();
 1076                    }
 1077                }
 1078            })
 1079            .detach();
 1080
 1081        language_server
 1082            .on_notification::<lsp::notification::LogMessage, _>({
 1083                let this = lsp_store.clone();
 1084                move |params, cx| {
 1085                    if let Some(this) = this.upgrade() {
 1086                        this.update(cx, |_, cx| {
 1087                            cx.emit(LspStoreEvent::LanguageServerLog(
 1088                                server_id,
 1089                                LanguageServerLogType::Log(params.typ),
 1090                                params.message,
 1091                            ));
 1092                        })
 1093                        .ok();
 1094                    }
 1095                }
 1096            })
 1097            .detach();
 1098
 1099        language_server
 1100            .on_notification::<lsp::notification::LogTrace, _>({
 1101                let this = lsp_store.clone();
 1102                move |params, cx| {
 1103                    let mut cx = cx.clone();
 1104                    if let Some(this) = this.upgrade() {
 1105                        this.update(&mut cx, |_, cx| {
 1106                            cx.emit(LspStoreEvent::LanguageServerLog(
 1107                                server_id,
 1108                                LanguageServerLogType::Trace {
 1109                                    verbose_info: params.verbose,
 1110                                },
 1111                                params.message,
 1112                            ));
 1113                        })
 1114                        .ok();
 1115                    }
 1116                }
 1117            })
 1118            .detach();
 1119
 1120        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1121        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1122        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1123        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1124    }
 1125
 1126    fn shutdown_language_servers_on_quit(
 1127        &mut self,
 1128        _: &mut Context<LspStore>,
 1129    ) -> impl Future<Output = ()> + use<> {
 1130        let shutdown_futures = self
 1131            .language_servers
 1132            .drain()
 1133            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1134            .collect::<Vec<_>>();
 1135
 1136        async move {
 1137            join_all(shutdown_futures).await;
 1138        }
 1139    }
 1140
 1141    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1142        match server_state {
 1143            LanguageServerState::Running { server, .. } => {
 1144                if let Some(shutdown) = server.shutdown() {
 1145                    shutdown.await;
 1146                }
 1147            }
 1148            LanguageServerState::Starting { startup, .. } => {
 1149                if let Some(server) = startup.await
 1150                    && let Some(shutdown) = server.shutdown()
 1151                {
 1152                    shutdown.await;
 1153                }
 1154            }
 1155        }
 1156        Ok(())
 1157    }
 1158
 1159    fn language_servers_for_worktree(
 1160        &self,
 1161        worktree_id: WorktreeId,
 1162    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1163        self.language_server_ids
 1164            .iter()
 1165            .filter_map(move |(seed, state)| {
 1166                if seed.worktree_id != worktree_id {
 1167                    return None;
 1168                }
 1169
 1170                if let Some(LanguageServerState::Running { server, .. }) =
 1171                    self.language_servers.get(&state.id)
 1172                {
 1173                    Some(server)
 1174                } else {
 1175                    None
 1176                }
 1177            })
 1178    }
 1179
 1180    fn language_server_ids_for_project_path(
 1181        &self,
 1182        project_path: ProjectPath,
 1183        language: &Language,
 1184        cx: &mut App,
 1185    ) -> Vec<LanguageServerId> {
 1186        let Some(worktree) = self
 1187            .worktree_store
 1188            .read(cx)
 1189            .worktree_for_id(project_path.worktree_id, cx)
 1190        else {
 1191            return Vec::new();
 1192        };
 1193        let delegate: Arc<dyn ManifestDelegate> =
 1194            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1195
 1196        self.lsp_tree
 1197            .get(
 1198                project_path,
 1199                language.name(),
 1200                language.manifest(),
 1201                &delegate,
 1202                cx,
 1203            )
 1204            .collect::<Vec<_>>()
 1205    }
 1206
 1207    fn language_server_ids_for_buffer(
 1208        &self,
 1209        buffer: &Buffer,
 1210        cx: &mut App,
 1211    ) -> Vec<LanguageServerId> {
 1212        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1213            let worktree_id = file.worktree_id(cx);
 1214
 1215            let path: Arc<RelPath> = file
 1216                .path()
 1217                .parent()
 1218                .map(Arc::from)
 1219                .unwrap_or_else(|| file.path().clone());
 1220            let worktree_path = ProjectPath { worktree_id, path };
 1221            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1222        } else {
 1223            Vec::new()
 1224        }
 1225    }
 1226
 1227    fn language_servers_for_buffer<'a>(
 1228        &'a self,
 1229        buffer: &'a Buffer,
 1230        cx: &'a mut App,
 1231    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1232        self.language_server_ids_for_buffer(buffer, cx)
 1233            .into_iter()
 1234            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1235                LanguageServerState::Running {
 1236                    adapter, server, ..
 1237                } => Some((adapter, server)),
 1238                _ => None,
 1239            })
 1240    }
 1241
 1242    async fn execute_code_action_kind_locally(
 1243        lsp_store: WeakEntity<LspStore>,
 1244        mut buffers: Vec<Entity<Buffer>>,
 1245        kind: CodeActionKind,
 1246        push_to_history: bool,
 1247        cx: &mut AsyncApp,
 1248    ) -> anyhow::Result<ProjectTransaction> {
 1249        // Do not allow multiple concurrent code actions requests for the
 1250        // same buffer.
 1251        lsp_store.update(cx, |this, cx| {
 1252            let this = this.as_local_mut().unwrap();
 1253            buffers.retain(|buffer| {
 1254                this.buffers_being_formatted
 1255                    .insert(buffer.read(cx).remote_id())
 1256            });
 1257        })?;
 1258        let _cleanup = defer({
 1259            let this = lsp_store.clone();
 1260            let mut cx = cx.clone();
 1261            let buffers = &buffers;
 1262            move || {
 1263                this.update(&mut cx, |this, cx| {
 1264                    let this = this.as_local_mut().unwrap();
 1265                    for buffer in buffers {
 1266                        this.buffers_being_formatted
 1267                            .remove(&buffer.read(cx).remote_id());
 1268                    }
 1269                })
 1270                .ok();
 1271            }
 1272        });
 1273        let mut project_transaction = ProjectTransaction::default();
 1274
 1275        for buffer in &buffers {
 1276            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1277                buffer.update(cx, |buffer, cx| {
 1278                    lsp_store
 1279                        .as_local()
 1280                        .unwrap()
 1281                        .language_servers_for_buffer(buffer, cx)
 1282                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1283                        .collect::<Vec<_>>()
 1284                })
 1285            })?;
 1286            for (_, language_server) in adapters_and_servers.iter() {
 1287                let actions = Self::get_server_code_actions_from_action_kinds(
 1288                    &lsp_store,
 1289                    language_server.server_id(),
 1290                    vec![kind.clone()],
 1291                    buffer,
 1292                    cx,
 1293                )
 1294                .await?;
 1295                Self::execute_code_actions_on_server(
 1296                    &lsp_store,
 1297                    language_server,
 1298                    actions,
 1299                    push_to_history,
 1300                    &mut project_transaction,
 1301                    cx,
 1302                )
 1303                .await?;
 1304            }
 1305        }
 1306        Ok(project_transaction)
 1307    }
 1308
 1309    async fn format_locally(
 1310        lsp_store: WeakEntity<LspStore>,
 1311        mut buffers: Vec<FormattableBuffer>,
 1312        push_to_history: bool,
 1313        trigger: FormatTrigger,
 1314        logger: zlog::Logger,
 1315        cx: &mut AsyncApp,
 1316    ) -> anyhow::Result<ProjectTransaction> {
 1317        // Do not allow multiple concurrent formatting requests for the
 1318        // same buffer.
 1319        lsp_store.update(cx, |this, cx| {
 1320            let this = this.as_local_mut().unwrap();
 1321            buffers.retain(|buffer| {
 1322                this.buffers_being_formatted
 1323                    .insert(buffer.handle.read(cx).remote_id())
 1324            });
 1325        })?;
 1326
 1327        let _cleanup = defer({
 1328            let this = lsp_store.clone();
 1329            let mut cx = cx.clone();
 1330            let buffers = &buffers;
 1331            move || {
 1332                this.update(&mut cx, |this, cx| {
 1333                    let this = this.as_local_mut().unwrap();
 1334                    for buffer in buffers {
 1335                        this.buffers_being_formatted
 1336                            .remove(&buffer.handle.read(cx).remote_id());
 1337                    }
 1338                })
 1339                .ok();
 1340            }
 1341        });
 1342
 1343        let mut project_transaction = ProjectTransaction::default();
 1344
 1345        for buffer in &buffers {
 1346            zlog::debug!(
 1347                logger =>
 1348                "formatting buffer '{:?}'",
 1349                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1350            );
 1351            // Create an empty transaction to hold all of the formatting edits.
 1352            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1353                // ensure no transactions created while formatting are
 1354                // grouped with the previous transaction in the history
 1355                // based on the transaction group interval
 1356                buffer.finalize_last_transaction();
 1357                buffer
 1358                    .start_transaction()
 1359                    .context("transaction already open")?;
 1360                buffer.end_transaction(cx);
 1361                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1362                buffer.finalize_last_transaction();
 1363                anyhow::Ok(transaction_id)
 1364            })??;
 1365
 1366            let result = Self::format_buffer_locally(
 1367                lsp_store.clone(),
 1368                buffer,
 1369                formatting_transaction_id,
 1370                trigger,
 1371                logger,
 1372                cx,
 1373            )
 1374            .await;
 1375
 1376            buffer.handle.update(cx, |buffer, cx| {
 1377                let Some(formatting_transaction) =
 1378                    buffer.get_transaction(formatting_transaction_id).cloned()
 1379                else {
 1380                    zlog::warn!(logger => "no formatting transaction");
 1381                    return;
 1382                };
 1383                if formatting_transaction.edit_ids.is_empty() {
 1384                    zlog::debug!(logger => "no changes made while formatting");
 1385                    buffer.forget_transaction(formatting_transaction_id);
 1386                    return;
 1387                }
 1388                if !push_to_history {
 1389                    zlog::trace!(logger => "forgetting format transaction");
 1390                    buffer.forget_transaction(formatting_transaction.id);
 1391                }
 1392                project_transaction
 1393                    .0
 1394                    .insert(cx.entity(), formatting_transaction);
 1395            })?;
 1396
 1397            result?;
 1398        }
 1399
 1400        Ok(project_transaction)
 1401    }
 1402
 1403    async fn format_buffer_locally(
 1404        lsp_store: WeakEntity<LspStore>,
 1405        buffer: &FormattableBuffer,
 1406        formatting_transaction_id: clock::Lamport,
 1407        trigger: FormatTrigger,
 1408        logger: zlog::Logger,
 1409        cx: &mut AsyncApp,
 1410    ) -> Result<()> {
 1411        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1412            buffer.handle.update(cx, |buffer, cx| {
 1413                let adapters_and_servers = lsp_store
 1414                    .as_local()
 1415                    .unwrap()
 1416                    .language_servers_for_buffer(buffer, cx)
 1417                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1418                    .collect::<Vec<_>>();
 1419                let settings =
 1420                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1421                        .into_owned();
 1422                (adapters_and_servers, settings)
 1423            })
 1424        })?;
 1425
 1426        /// Apply edits to the buffer that will become part of the formatting transaction.
 1427        /// Fails if the buffer has been edited since the start of that transaction.
 1428        fn extend_formatting_transaction(
 1429            buffer: &FormattableBuffer,
 1430            formatting_transaction_id: text::TransactionId,
 1431            cx: &mut AsyncApp,
 1432            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1433        ) -> anyhow::Result<()> {
 1434            buffer.handle.update(cx, |buffer, cx| {
 1435                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1436                if last_transaction_id != Some(formatting_transaction_id) {
 1437                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1438                }
 1439                buffer.start_transaction();
 1440                operation(buffer, cx);
 1441                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1442                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1443                }
 1444                Ok(())
 1445            })?
 1446        }
 1447
 1448        // handle whitespace formatting
 1449        if settings.remove_trailing_whitespace_on_save {
 1450            zlog::trace!(logger => "removing trailing whitespace");
 1451            let diff = buffer
 1452                .handle
 1453                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1454                .await;
 1455            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1456                buffer.apply_diff(diff, cx);
 1457            })?;
 1458        }
 1459
 1460        if settings.ensure_final_newline_on_save {
 1461            zlog::trace!(logger => "ensuring final newline");
 1462            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1463                buffer.ensure_final_newline(cx);
 1464            })?;
 1465        }
 1466
 1467        // Formatter for `code_actions_on_format` that runs before
 1468        // the rest of the formatters
 1469        let mut code_actions_on_format_formatters = None;
 1470        let should_run_code_actions_on_format = !matches!(
 1471            (trigger, &settings.format_on_save),
 1472            (FormatTrigger::Save, &FormatOnSave::Off)
 1473        );
 1474        if should_run_code_actions_on_format {
 1475            let have_code_actions_to_run_on_format = settings
 1476                .code_actions_on_format
 1477                .values()
 1478                .any(|enabled| *enabled);
 1479            if have_code_actions_to_run_on_format {
 1480                zlog::trace!(logger => "going to run code actions on format");
 1481                code_actions_on_format_formatters = Some(
 1482                    settings
 1483                        .code_actions_on_format
 1484                        .iter()
 1485                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1486                        .cloned()
 1487                        .map(Formatter::CodeAction)
 1488                        .collect::<Vec<_>>(),
 1489                );
 1490            }
 1491        }
 1492
 1493        let formatters = match (trigger, &settings.format_on_save) {
 1494            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1495            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1496                settings.formatter.as_ref()
 1497            }
 1498        };
 1499
 1500        let formatters = code_actions_on_format_formatters
 1501            .iter()
 1502            .flatten()
 1503            .chain(formatters);
 1504
 1505        for formatter in formatters {
 1506            let formatter = if formatter == &Formatter::Auto {
 1507                if settings.prettier.allowed {
 1508                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1509                    &Formatter::Prettier
 1510                } else {
 1511                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1512                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1513                }
 1514            } else {
 1515                formatter
 1516            };
 1517            match formatter {
 1518                Formatter::Auto => unreachable!("Auto resolved above"),
 1519                Formatter::Prettier => {
 1520                    let logger = zlog::scoped!(logger => "prettier");
 1521                    zlog::trace!(logger => "formatting");
 1522                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1523
 1524                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1525                        lsp_store.prettier_store().unwrap().downgrade()
 1526                    })?;
 1527                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1528                        .await
 1529                        .transpose()?;
 1530                    let Some(diff) = diff else {
 1531                        zlog::trace!(logger => "No changes");
 1532                        continue;
 1533                    };
 1534
 1535                    extend_formatting_transaction(
 1536                        buffer,
 1537                        formatting_transaction_id,
 1538                        cx,
 1539                        |buffer, cx| {
 1540                            buffer.apply_diff(diff, cx);
 1541                        },
 1542                    )?;
 1543                }
 1544                Formatter::External { command, arguments } => {
 1545                    let logger = zlog::scoped!(logger => "command");
 1546                    zlog::trace!(logger => "formatting");
 1547                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1548
 1549                    let diff = Self::format_via_external_command(
 1550                        buffer,
 1551                        command.as_ref(),
 1552                        arguments.as_deref(),
 1553                        cx,
 1554                    )
 1555                    .await
 1556                    .with_context(|| {
 1557                        format!("Failed to format buffer via external command: {}", command)
 1558                    })?;
 1559                    let Some(diff) = diff else {
 1560                        zlog::trace!(logger => "No changes");
 1561                        continue;
 1562                    };
 1563
 1564                    extend_formatting_transaction(
 1565                        buffer,
 1566                        formatting_transaction_id,
 1567                        cx,
 1568                        |buffer, cx| {
 1569                            buffer.apply_diff(diff, cx);
 1570                        },
 1571                    )?;
 1572                }
 1573                Formatter::LanguageServer(specifier) => {
 1574                    let logger = zlog::scoped!(logger => "language-server");
 1575                    zlog::trace!(logger => "formatting");
 1576                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1577
 1578                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1579                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1580                        continue;
 1581                    };
 1582
 1583                    let language_server = match specifier {
 1584                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1585                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1586                                if adapter.name.0.as_ref() == name {
 1587                                    Some(server.clone())
 1588                                } else {
 1589                                    None
 1590                                }
 1591                            })
 1592                        }
 1593                        settings::LanguageServerFormatterSpecifier::Current => {
 1594                            adapters_and_servers.first().map(|e| e.1.clone())
 1595                        }
 1596                    };
 1597
 1598                    let Some(language_server) = language_server else {
 1599                        log::debug!(
 1600                            "No language server found to format buffer '{:?}'. Skipping",
 1601                            buffer_path_abs.as_path().to_string_lossy()
 1602                        );
 1603                        continue;
 1604                    };
 1605
 1606                    zlog::trace!(
 1607                        logger =>
 1608                        "Formatting buffer '{:?}' using language server '{:?}'",
 1609                        buffer_path_abs.as_path().to_string_lossy(),
 1610                        language_server.name()
 1611                    );
 1612
 1613                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1614                        zlog::trace!(logger => "formatting ranges");
 1615                        Self::format_ranges_via_lsp(
 1616                            &lsp_store,
 1617                            &buffer.handle,
 1618                            ranges,
 1619                            buffer_path_abs,
 1620                            &language_server,
 1621                            &settings,
 1622                            cx,
 1623                        )
 1624                        .await
 1625                        .context("Failed to format ranges via language server")?
 1626                    } else {
 1627                        zlog::trace!(logger => "formatting full");
 1628                        Self::format_via_lsp(
 1629                            &lsp_store,
 1630                            &buffer.handle,
 1631                            buffer_path_abs,
 1632                            &language_server,
 1633                            &settings,
 1634                            cx,
 1635                        )
 1636                        .await
 1637                        .context("failed to format via language server")?
 1638                    };
 1639
 1640                    if edits.is_empty() {
 1641                        zlog::trace!(logger => "No changes");
 1642                        continue;
 1643                    }
 1644                    extend_formatting_transaction(
 1645                        buffer,
 1646                        formatting_transaction_id,
 1647                        cx,
 1648                        |buffer, cx| {
 1649                            buffer.edit(edits, None, cx);
 1650                        },
 1651                    )?;
 1652                }
 1653                Formatter::CodeAction(code_action_name) => {
 1654                    let logger = zlog::scoped!(logger => "code-actions");
 1655                    zlog::trace!(logger => "formatting");
 1656                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1657
 1658                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1659                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1660                        continue;
 1661                    };
 1662
 1663                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1664                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1665
 1666                    let mut actions_and_servers = Vec::new();
 1667
 1668                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1669                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1670                            &lsp_store,
 1671                            language_server.server_id(),
 1672                            vec![code_action_kind.clone()],
 1673                            &buffer.handle,
 1674                            cx,
 1675                        )
 1676                        .await
 1677                        .with_context(|| {
 1678                            format!(
 1679                                "Failed to resolve code action {:?} with language server {}",
 1680                                code_action_kind,
 1681                                language_server.name()
 1682                            )
 1683                        });
 1684                        let Ok(actions) = actions_result else {
 1685                            // note: it may be better to set result to the error and break formatters here
 1686                            // but for now we try to execute the actions that we can resolve and skip the rest
 1687                            zlog::error!(
 1688                                logger =>
 1689                                "Failed to resolve code action {:?} with language server {}",
 1690                                code_action_kind,
 1691                                language_server.name()
 1692                            );
 1693                            continue;
 1694                        };
 1695                        for action in actions {
 1696                            actions_and_servers.push((action, index));
 1697                        }
 1698                    }
 1699
 1700                    if actions_and_servers.is_empty() {
 1701                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1702                        continue;
 1703                    }
 1704
 1705                    'actions: for (mut action, server_index) in actions_and_servers {
 1706                        let server = &adapters_and_servers[server_index].1;
 1707
 1708                        let describe_code_action = |action: &CodeAction| {
 1709                            format!(
 1710                                "code action '{}' with title \"{}\" on server {}",
 1711                                action
 1712                                    .lsp_action
 1713                                    .action_kind()
 1714                                    .unwrap_or("unknown".into())
 1715                                    .as_str(),
 1716                                action.lsp_action.title(),
 1717                                server.name(),
 1718                            )
 1719                        };
 1720
 1721                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1722
 1723                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1724                            zlog::error!(
 1725                                logger =>
 1726                                "Failed to resolve {}. Error: {}",
 1727                                describe_code_action(&action),
 1728                                err
 1729                            );
 1730                            continue;
 1731                        }
 1732
 1733                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1734                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1735                            // but filters out and logs warnings for code actions that require unreasonably
 1736                            // difficult handling on our part, such as:
 1737                            // - applying edits that call commands
 1738                            //   which can result in arbitrary workspace edits being sent from the server that
 1739                            //   have no way of being tied back to the command that initiated them (i.e. we
 1740                            //   can't know which edits are part of the format request, or if the server is done sending
 1741                            //   actions in response to the command)
 1742                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1743                            //   as we then would need to handle such changes correctly in the local history as well
 1744                            //   as the remote history through the ProjectTransaction
 1745                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1746                            // Supporting these actions is not impossible, but not supported as of yet.
 1747                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1748                                zlog::trace!(
 1749                                    logger =>
 1750                                    "No changes for code action. Skipping {}",
 1751                                    describe_code_action(&action),
 1752                                );
 1753                                continue;
 1754                            }
 1755
 1756                            let mut operations = Vec::new();
 1757                            if let Some(document_changes) = edit.document_changes {
 1758                                match document_changes {
 1759                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1760                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1761                                    ),
 1762                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1763                                }
 1764                            } else if let Some(changes) = edit.changes {
 1765                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1766                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1767                                        text_document:
 1768                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1769                                                uri,
 1770                                                version: None,
 1771                                            },
 1772                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1773                                    })
 1774                                }));
 1775                            }
 1776
 1777                            let mut edits = Vec::with_capacity(operations.len());
 1778
 1779                            if operations.is_empty() {
 1780                                zlog::trace!(
 1781                                    logger =>
 1782                                    "No changes for code action. Skipping {}",
 1783                                    describe_code_action(&action),
 1784                                );
 1785                                continue;
 1786                            }
 1787                            for operation in operations {
 1788                                let op = match operation {
 1789                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1790                                    lsp::DocumentChangeOperation::Op(_) => {
 1791                                        zlog::warn!(
 1792                                            logger =>
 1793                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1794                                            describe_code_action(&action),
 1795                                        );
 1796                                        continue 'actions;
 1797                                    }
 1798                                };
 1799                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1800                                    zlog::warn!(
 1801                                        logger =>
 1802                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1803                                        &op.text_document.uri,
 1804                                        describe_code_action(&action),
 1805                                    );
 1806                                    continue 'actions;
 1807                                };
 1808                                if &file_path != buffer_path_abs {
 1809                                    zlog::warn!(
 1810                                        logger =>
 1811                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1812                                        file_path,
 1813                                        buffer_path_abs,
 1814                                        describe_code_action(&action),
 1815                                    );
 1816                                    continue 'actions;
 1817                                }
 1818
 1819                                let mut lsp_edits = Vec::new();
 1820                                for edit in op.edits {
 1821                                    match edit {
 1822                                        Edit::Plain(edit) => {
 1823                                            if !lsp_edits.contains(&edit) {
 1824                                                lsp_edits.push(edit);
 1825                                            }
 1826                                        }
 1827                                        Edit::Annotated(edit) => {
 1828                                            if !lsp_edits.contains(&edit.text_edit) {
 1829                                                lsp_edits.push(edit.text_edit);
 1830                                            }
 1831                                        }
 1832                                        Edit::Snippet(_) => {
 1833                                            zlog::warn!(
 1834                                                logger =>
 1835                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1836                                                describe_code_action(&action),
 1837                                            );
 1838                                            continue 'actions;
 1839                                        }
 1840                                    }
 1841                                }
 1842                                let edits_result = lsp_store
 1843                                    .update(cx, |lsp_store, cx| {
 1844                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1845                                            &buffer.handle,
 1846                                            lsp_edits,
 1847                                            server.server_id(),
 1848                                            op.text_document.version,
 1849                                            cx,
 1850                                        )
 1851                                    })?
 1852                                    .await;
 1853                                let Ok(resolved_edits) = edits_result else {
 1854                                    zlog::warn!(
 1855                                        logger =>
 1856                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1857                                        buffer_path_abs.as_path(),
 1858                                        describe_code_action(&action),
 1859                                    );
 1860                                    continue 'actions;
 1861                                };
 1862                                edits.extend(resolved_edits);
 1863                            }
 1864
 1865                            if edits.is_empty() {
 1866                                zlog::warn!(logger => "No edits resolved from LSP");
 1867                                continue;
 1868                            }
 1869
 1870                            extend_formatting_transaction(
 1871                                buffer,
 1872                                formatting_transaction_id,
 1873                                cx,
 1874                                |buffer, cx| {
 1875                                    zlog::info!(
 1876                                        "Applying edits {edits:?}. Content: {:?}",
 1877                                        buffer.text()
 1878                                    );
 1879                                    buffer.edit(edits, None, cx);
 1880                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1881                                },
 1882                            )?;
 1883                        }
 1884
 1885                        if let Some(command) = action.lsp_action.command() {
 1886                            zlog::warn!(
 1887                                logger =>
 1888                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1889                                &command.command,
 1890                            );
 1891
 1892                            // bail early if command is invalid
 1893                            let server_capabilities = server.capabilities();
 1894                            let available_commands = server_capabilities
 1895                                .execute_command_provider
 1896                                .as_ref()
 1897                                .map(|options| options.commands.as_slice())
 1898                                .unwrap_or_default();
 1899                            if !available_commands.contains(&command.command) {
 1900                                zlog::warn!(
 1901                                    logger =>
 1902                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1903                                    command.command,
 1904                                    server.name(),
 1905                                );
 1906                                continue;
 1907                            }
 1908
 1909                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1910                            extend_formatting_transaction(
 1911                                buffer,
 1912                                formatting_transaction_id,
 1913                                cx,
 1914                                |_, _| {},
 1915                            )?;
 1916                            zlog::info!(logger => "Executing command {}", &command.command);
 1917
 1918                            lsp_store.update(cx, |this, _| {
 1919                                this.as_local_mut()
 1920                                    .unwrap()
 1921                                    .last_workspace_edits_by_language_server
 1922                                    .remove(&server.server_id());
 1923                            })?;
 1924
 1925                            let execute_command_result = server
 1926                                .request::<lsp::request::ExecuteCommand>(
 1927                                    lsp::ExecuteCommandParams {
 1928                                        command: command.command.clone(),
 1929                                        arguments: command.arguments.clone().unwrap_or_default(),
 1930                                        ..Default::default()
 1931                                    },
 1932                                )
 1933                                .await
 1934                                .into_response();
 1935
 1936                            if execute_command_result.is_err() {
 1937                                zlog::error!(
 1938                                    logger =>
 1939                                    "Failed to execute command '{}' as part of {}",
 1940                                    &command.command,
 1941                                    describe_code_action(&action),
 1942                                );
 1943                                continue 'actions;
 1944                            }
 1945
 1946                            let mut project_transaction_command =
 1947                                lsp_store.update(cx, |this, _| {
 1948                                    this.as_local_mut()
 1949                                        .unwrap()
 1950                                        .last_workspace_edits_by_language_server
 1951                                        .remove(&server.server_id())
 1952                                        .unwrap_or_default()
 1953                                })?;
 1954
 1955                            if let Some(transaction) =
 1956                                project_transaction_command.0.remove(&buffer.handle)
 1957                            {
 1958                                zlog::trace!(
 1959                                    logger =>
 1960                                    "Successfully captured {} edits that resulted from command {}",
 1961                                    transaction.edit_ids.len(),
 1962                                    &command.command,
 1963                                );
 1964                                let transaction_id_project_transaction = transaction.id;
 1965                                buffer.handle.update(cx, |buffer, _| {
 1966                                    // it may have been removed from history if push_to_history was
 1967                                    // false in deserialize_workspace_edit. If so push it so we
 1968                                    // can merge it with the format transaction
 1969                                    // and pop the combined transaction off the history stack
 1970                                    // later if push_to_history is false
 1971                                    if buffer.get_transaction(transaction.id).is_none() {
 1972                                        buffer.push_transaction(transaction, Instant::now());
 1973                                    }
 1974                                    buffer.merge_transactions(
 1975                                        transaction_id_project_transaction,
 1976                                        formatting_transaction_id,
 1977                                    );
 1978                                })?;
 1979                            }
 1980
 1981                            if !project_transaction_command.0.is_empty() {
 1982                                let mut extra_buffers = String::new();
 1983                                for buffer in project_transaction_command.0.keys() {
 1984                                    buffer
 1985                                        .read_with(cx, |b, cx| {
 1986                                            if let Some(path) = b.project_path(cx) {
 1987                                                if !extra_buffers.is_empty() {
 1988                                                    extra_buffers.push_str(", ");
 1989                                                }
 1990                                                extra_buffers.push_str(path.path.as_unix_str());
 1991                                            }
 1992                                        })
 1993                                        .ok();
 1994                                }
 1995                                zlog::warn!(
 1996                                    logger =>
 1997                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1998                                    &command.command,
 1999                                    extra_buffers,
 2000                                );
 2001                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2002                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2003                                // add it so it's included, and merge it into the format transaction when its created later
 2004                            }
 2005                        }
 2006                    }
 2007                }
 2008            }
 2009        }
 2010
 2011        Ok(())
 2012    }
 2013
 2014    pub async fn format_ranges_via_lsp(
 2015        this: &WeakEntity<LspStore>,
 2016        buffer_handle: &Entity<Buffer>,
 2017        ranges: &[Range<Anchor>],
 2018        abs_path: &Path,
 2019        language_server: &Arc<LanguageServer>,
 2020        settings: &LanguageSettings,
 2021        cx: &mut AsyncApp,
 2022    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2023        let capabilities = &language_server.capabilities();
 2024        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2025        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2026            anyhow::bail!(
 2027                "{} language server does not support range formatting",
 2028                language_server.name()
 2029            );
 2030        }
 2031
 2032        let uri = file_path_to_lsp_url(abs_path)?;
 2033        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2034
 2035        let lsp_edits = {
 2036            let mut lsp_ranges = Vec::new();
 2037            this.update(cx, |_this, cx| {
 2038                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2039                // not have been sent to the language server. This seems like a fairly systemic
 2040                // issue, though, the resolution probably is not specific to formatting.
 2041                //
 2042                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2043                // LSP.
 2044                let snapshot = buffer_handle.read(cx).snapshot();
 2045                for range in ranges {
 2046                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2047                }
 2048                anyhow::Ok(())
 2049            })??;
 2050
 2051            let mut edits = None;
 2052            for range in lsp_ranges {
 2053                if let Some(mut edit) = language_server
 2054                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2055                        text_document: text_document.clone(),
 2056                        range,
 2057                        options: lsp_command::lsp_formatting_options(settings),
 2058                        work_done_progress_params: Default::default(),
 2059                    })
 2060                    .await
 2061                    .into_response()?
 2062                {
 2063                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2064                }
 2065            }
 2066            edits
 2067        };
 2068
 2069        if let Some(lsp_edits) = lsp_edits {
 2070            this.update(cx, |this, cx| {
 2071                this.as_local_mut().unwrap().edits_from_lsp(
 2072                    buffer_handle,
 2073                    lsp_edits,
 2074                    language_server.server_id(),
 2075                    None,
 2076                    cx,
 2077                )
 2078            })?
 2079            .await
 2080        } else {
 2081            Ok(Vec::with_capacity(0))
 2082        }
 2083    }
 2084
 2085    async fn format_via_lsp(
 2086        this: &WeakEntity<LspStore>,
 2087        buffer: &Entity<Buffer>,
 2088        abs_path: &Path,
 2089        language_server: &Arc<LanguageServer>,
 2090        settings: &LanguageSettings,
 2091        cx: &mut AsyncApp,
 2092    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2093        let logger = zlog::scoped!("lsp_format");
 2094        zlog::debug!(logger => "Formatting via LSP");
 2095
 2096        let uri = file_path_to_lsp_url(abs_path)?;
 2097        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2098        let capabilities = &language_server.capabilities();
 2099
 2100        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2101        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2102
 2103        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2104            let _timer = zlog::time!(logger => "format-full");
 2105            language_server
 2106                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2107                    text_document,
 2108                    options: lsp_command::lsp_formatting_options(settings),
 2109                    work_done_progress_params: Default::default(),
 2110                })
 2111                .await
 2112                .into_response()?
 2113        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2114            let _timer = zlog::time!(logger => "format-range");
 2115            let buffer_start = lsp::Position::new(0, 0);
 2116            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2117            language_server
 2118                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2119                    text_document: text_document.clone(),
 2120                    range: lsp::Range::new(buffer_start, buffer_end),
 2121                    options: lsp_command::lsp_formatting_options(settings),
 2122                    work_done_progress_params: Default::default(),
 2123                })
 2124                .await
 2125                .into_response()?
 2126        } else {
 2127            None
 2128        };
 2129
 2130        if let Some(lsp_edits) = lsp_edits {
 2131            this.update(cx, |this, cx| {
 2132                this.as_local_mut().unwrap().edits_from_lsp(
 2133                    buffer,
 2134                    lsp_edits,
 2135                    language_server.server_id(),
 2136                    None,
 2137                    cx,
 2138                )
 2139            })?
 2140            .await
 2141        } else {
 2142            Ok(Vec::with_capacity(0))
 2143        }
 2144    }
 2145
 2146    async fn format_via_external_command(
 2147        buffer: &FormattableBuffer,
 2148        command: &str,
 2149        arguments: Option<&[String]>,
 2150        cx: &mut AsyncApp,
 2151    ) -> Result<Option<Diff>> {
 2152        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2153            let file = File::from_dyn(buffer.file())?;
 2154            let worktree = file.worktree.read(cx);
 2155            let mut worktree_path = worktree.abs_path().to_path_buf();
 2156            if worktree.root_entry()?.is_file() {
 2157                worktree_path.pop();
 2158            }
 2159            Some(worktree_path)
 2160        })?;
 2161
 2162        let mut child = util::command::new_smol_command(command);
 2163
 2164        if let Some(buffer_env) = buffer.env.as_ref() {
 2165            child.envs(buffer_env);
 2166        }
 2167
 2168        if let Some(working_dir_path) = working_dir_path {
 2169            child.current_dir(working_dir_path);
 2170        }
 2171
 2172        if let Some(arguments) = arguments {
 2173            child.args(arguments.iter().map(|arg| {
 2174                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2175                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2176                } else {
 2177                    arg.replace("{buffer_path}", "Untitled")
 2178                }
 2179            }));
 2180        }
 2181
 2182        let mut child = child
 2183            .stdin(smol::process::Stdio::piped())
 2184            .stdout(smol::process::Stdio::piped())
 2185            .stderr(smol::process::Stdio::piped())
 2186            .spawn()?;
 2187
 2188        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2189        let text = buffer
 2190            .handle
 2191            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2192        for chunk in text.chunks() {
 2193            stdin.write_all(chunk.as_bytes()).await?;
 2194        }
 2195        stdin.flush().await?;
 2196
 2197        let output = child.output().await?;
 2198        anyhow::ensure!(
 2199            output.status.success(),
 2200            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2201            output.status.code(),
 2202            String::from_utf8_lossy(&output.stdout),
 2203            String::from_utf8_lossy(&output.stderr),
 2204        );
 2205
 2206        let stdout = String::from_utf8(output.stdout)?;
 2207        Ok(Some(
 2208            buffer
 2209                .handle
 2210                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2211                .await,
 2212        ))
 2213    }
 2214
 2215    async fn try_resolve_code_action(
 2216        lang_server: &LanguageServer,
 2217        action: &mut CodeAction,
 2218    ) -> anyhow::Result<()> {
 2219        match &mut action.lsp_action {
 2220            LspAction::Action(lsp_action) => {
 2221                if !action.resolved
 2222                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2223                    && lsp_action.data.is_some()
 2224                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2225                {
 2226                    *lsp_action = Box::new(
 2227                        lang_server
 2228                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2229                            .await
 2230                            .into_response()?,
 2231                    );
 2232                }
 2233            }
 2234            LspAction::CodeLens(lens) => {
 2235                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2236                    *lens = lang_server
 2237                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2238                        .await
 2239                        .into_response()?;
 2240                }
 2241            }
 2242            LspAction::Command(_) => {}
 2243        }
 2244
 2245        action.resolved = true;
 2246        anyhow::Ok(())
 2247    }
 2248
 2249    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2250        let buffer = buffer_handle.read(cx);
 2251
 2252        let file = buffer.file().cloned();
 2253
 2254        let Some(file) = File::from_dyn(file.as_ref()) else {
 2255            return;
 2256        };
 2257        if !file.is_local() {
 2258            return;
 2259        }
 2260        let path = ProjectPath::from_file(file, cx);
 2261        let worktree_id = file.worktree_id(cx);
 2262        let language = buffer.language().cloned();
 2263
 2264        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2265            for (server_id, diagnostics) in
 2266                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2267            {
 2268                self.update_buffer_diagnostics(
 2269                    buffer_handle,
 2270                    server_id,
 2271                    None,
 2272                    None,
 2273                    None,
 2274                    Vec::new(),
 2275                    diagnostics,
 2276                    cx,
 2277                )
 2278                .log_err();
 2279            }
 2280        }
 2281        let Some(language) = language else {
 2282            return;
 2283        };
 2284        let Some(snapshot) = self
 2285            .worktree_store
 2286            .read(cx)
 2287            .worktree_for_id(worktree_id, cx)
 2288            .map(|worktree| worktree.read(cx).snapshot())
 2289        else {
 2290            return;
 2291        };
 2292        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2293
 2294        for server_id in
 2295            self.lsp_tree
 2296                .get(path, language.name(), language.manifest(), &delegate, cx)
 2297        {
 2298            let server = self
 2299                .language_servers
 2300                .get(&server_id)
 2301                .and_then(|server_state| {
 2302                    if let LanguageServerState::Running { server, .. } = server_state {
 2303                        Some(server.clone())
 2304                    } else {
 2305                        None
 2306                    }
 2307                });
 2308            let server = match server {
 2309                Some(server) => server,
 2310                None => continue,
 2311            };
 2312
 2313            buffer_handle.update(cx, |buffer, cx| {
 2314                buffer.set_completion_triggers(
 2315                    server.server_id(),
 2316                    server
 2317                        .capabilities()
 2318                        .completion_provider
 2319                        .as_ref()
 2320                        .and_then(|provider| {
 2321                            provider
 2322                                .trigger_characters
 2323                                .as_ref()
 2324                                .map(|characters| characters.iter().cloned().collect())
 2325                        })
 2326                        .unwrap_or_default(),
 2327                    cx,
 2328                );
 2329            });
 2330        }
 2331    }
 2332
 2333    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2334        buffer.update(cx, |buffer, cx| {
 2335            let Some(language) = buffer.language() else {
 2336                return;
 2337            };
 2338            let path = ProjectPath {
 2339                worktree_id: old_file.worktree_id(cx),
 2340                path: old_file.path.clone(),
 2341            };
 2342            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2343                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2344                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2345            }
 2346        });
 2347    }
 2348
 2349    fn update_buffer_diagnostics(
 2350        &mut self,
 2351        buffer: &Entity<Buffer>,
 2352        server_id: LanguageServerId,
 2353        registration_id: Option<Option<SharedString>>,
 2354        result_id: Option<SharedString>,
 2355        version: Option<i32>,
 2356        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2357        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2358        cx: &mut Context<LspStore>,
 2359    ) -> Result<()> {
 2360        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2361            Ordering::Equal
 2362                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2363                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2364                .then_with(|| a.severity.cmp(&b.severity))
 2365                .then_with(|| a.message.cmp(&b.message))
 2366        }
 2367
 2368        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2369        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2370        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2371
 2372        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2373            Ordering::Equal
 2374                .then_with(|| a.range.start.cmp(&b.range.start))
 2375                .then_with(|| b.range.end.cmp(&a.range.end))
 2376                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2377        });
 2378
 2379        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2380
 2381        let edits_since_save = std::cell::LazyCell::new(|| {
 2382            let saved_version = buffer.read(cx).saved_version();
 2383            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2384        });
 2385
 2386        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2387
 2388        for (new_diagnostic, entry) in diagnostics {
 2389            let start;
 2390            let end;
 2391            if new_diagnostic && entry.diagnostic.is_disk_based {
 2392                // Some diagnostics are based on files on disk instead of buffers'
 2393                // current contents. Adjust these diagnostics' ranges to reflect
 2394                // any unsaved edits.
 2395                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2396                // and were properly adjusted on reuse.
 2397                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2398                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2399            } else {
 2400                start = entry.range.start;
 2401                end = entry.range.end;
 2402            }
 2403
 2404            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2405                ..snapshot.clip_point_utf16(end, Bias::Right);
 2406
 2407            // Expand empty ranges by one codepoint
 2408            if range.start == range.end {
 2409                // This will be go to the next boundary when being clipped
 2410                range.end.column += 1;
 2411                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2412                if range.start == range.end && range.end.column > 0 {
 2413                    range.start.column -= 1;
 2414                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2415                }
 2416            }
 2417
 2418            sanitized_diagnostics.push(DiagnosticEntry {
 2419                range,
 2420                diagnostic: entry.diagnostic,
 2421            });
 2422        }
 2423        drop(edits_since_save);
 2424
 2425        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2426        buffer.update(cx, |buffer, cx| {
 2427            if let Some(registration_id) = registration_id {
 2428                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2429                    self.buffer_pull_diagnostics_result_ids
 2430                        .entry(server_id)
 2431                        .or_default()
 2432                        .entry(registration_id)
 2433                        .or_default()
 2434                        .insert(abs_path, result_id);
 2435                }
 2436            }
 2437
 2438            buffer.update_diagnostics(server_id, set, cx)
 2439        });
 2440
 2441        Ok(())
 2442    }
 2443
 2444    fn register_language_server_for_invisible_worktree(
 2445        &mut self,
 2446        worktree: &Entity<Worktree>,
 2447        language_server_id: LanguageServerId,
 2448        cx: &mut App,
 2449    ) {
 2450        let worktree = worktree.read(cx);
 2451        let worktree_id = worktree.id();
 2452        debug_assert!(!worktree.is_visible());
 2453        let Some(mut origin_seed) = self
 2454            .language_server_ids
 2455            .iter()
 2456            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2457        else {
 2458            return;
 2459        };
 2460        origin_seed.worktree_id = worktree_id;
 2461        self.language_server_ids
 2462            .entry(origin_seed)
 2463            .or_insert_with(|| UnifiedLanguageServer {
 2464                id: language_server_id,
 2465                project_roots: Default::default(),
 2466            });
 2467    }
 2468
 2469    fn register_buffer_with_language_servers(
 2470        &mut self,
 2471        buffer_handle: &Entity<Buffer>,
 2472        only_register_servers: HashSet<LanguageServerSelector>,
 2473        cx: &mut Context<LspStore>,
 2474    ) {
 2475        let buffer = buffer_handle.read(cx);
 2476        let buffer_id = buffer.remote_id();
 2477
 2478        let Some(file) = File::from_dyn(buffer.file()) else {
 2479            return;
 2480        };
 2481        if !file.is_local() {
 2482            return;
 2483        }
 2484
 2485        let abs_path = file.abs_path(cx);
 2486        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2487            return;
 2488        };
 2489        let initial_snapshot = buffer.text_snapshot();
 2490        let worktree_id = file.worktree_id(cx);
 2491
 2492        let Some(language) = buffer.language().cloned() else {
 2493            return;
 2494        };
 2495        let path: Arc<RelPath> = file
 2496            .path()
 2497            .parent()
 2498            .map(Arc::from)
 2499            .unwrap_or_else(|| file.path().clone());
 2500        let Some(worktree) = self
 2501            .worktree_store
 2502            .read(cx)
 2503            .worktree_for_id(worktree_id, cx)
 2504        else {
 2505            return;
 2506        };
 2507        let language_name = language.name();
 2508        let (reused, delegate, servers) = self
 2509            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2510            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2511            .unwrap_or_else(|| {
 2512                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2513                let delegate: Arc<dyn ManifestDelegate> =
 2514                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2515
 2516                let servers = self
 2517                    .lsp_tree
 2518                    .walk(
 2519                        ProjectPath { worktree_id, path },
 2520                        language.name(),
 2521                        language.manifest(),
 2522                        &delegate,
 2523                        cx,
 2524                    )
 2525                    .collect::<Vec<_>>();
 2526                (false, lsp_delegate, servers)
 2527            });
 2528        let servers_and_adapters = servers
 2529            .into_iter()
 2530            .filter_map(|server_node| {
 2531                if reused && server_node.server_id().is_none() {
 2532                    return None;
 2533                }
 2534                if !only_register_servers.is_empty() {
 2535                    if let Some(server_id) = server_node.server_id()
 2536                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2537                    {
 2538                        return None;
 2539                    }
 2540                    if let Some(name) = server_node.name()
 2541                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2542                    {
 2543                        return None;
 2544                    }
 2545                }
 2546
 2547                let server_id = server_node.server_id_or_init(|disposition| {
 2548                    let path = &disposition.path;
 2549
 2550                    {
 2551                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2552
 2553                        let server_id = self.get_or_insert_language_server(
 2554                            &worktree,
 2555                            delegate.clone(),
 2556                            disposition,
 2557                            &language_name,
 2558                            cx,
 2559                        );
 2560
 2561                        if let Some(state) = self.language_servers.get(&server_id)
 2562                            && let Ok(uri) = uri
 2563                        {
 2564                            state.add_workspace_folder(uri);
 2565                        };
 2566                        server_id
 2567                    }
 2568                })?;
 2569                let server_state = self.language_servers.get(&server_id)?;
 2570                if let LanguageServerState::Running {
 2571                    server, adapter, ..
 2572                } = server_state
 2573                {
 2574                    Some((server.clone(), adapter.clone()))
 2575                } else {
 2576                    None
 2577                }
 2578            })
 2579            .collect::<Vec<_>>();
 2580        for (server, adapter) in servers_and_adapters {
 2581            buffer_handle.update(cx, |buffer, cx| {
 2582                buffer.set_completion_triggers(
 2583                    server.server_id(),
 2584                    server
 2585                        .capabilities()
 2586                        .completion_provider
 2587                        .as_ref()
 2588                        .and_then(|provider| {
 2589                            provider
 2590                                .trigger_characters
 2591                                .as_ref()
 2592                                .map(|characters| characters.iter().cloned().collect())
 2593                        })
 2594                        .unwrap_or_default(),
 2595                    cx,
 2596                );
 2597            });
 2598
 2599            let snapshot = LspBufferSnapshot {
 2600                version: 0,
 2601                snapshot: initial_snapshot.clone(),
 2602            };
 2603
 2604            let mut registered = false;
 2605            self.buffer_snapshots
 2606                .entry(buffer_id)
 2607                .or_default()
 2608                .entry(server.server_id())
 2609                .or_insert_with(|| {
 2610                    registered = true;
 2611                    server.register_buffer(
 2612                        uri.clone(),
 2613                        adapter.language_id(&language.name()),
 2614                        0,
 2615                        initial_snapshot.text(),
 2616                    );
 2617
 2618                    vec![snapshot]
 2619                });
 2620
 2621            self.buffers_opened_in_servers
 2622                .entry(buffer_id)
 2623                .or_default()
 2624                .insert(server.server_id());
 2625            if registered {
 2626                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2627                    language_server_id: server.server_id(),
 2628                    name: None,
 2629                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2630                        proto::RegisteredForBuffer {
 2631                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2632                            buffer_id: buffer_id.to_proto(),
 2633                        },
 2634                    ),
 2635                });
 2636            }
 2637        }
 2638    }
 2639
 2640    fn reuse_existing_language_server<'lang_name>(
 2641        &self,
 2642        server_tree: &LanguageServerTree,
 2643        worktree: &Entity<Worktree>,
 2644        language_name: &'lang_name LanguageName,
 2645        cx: &mut App,
 2646    ) -> Option<(
 2647        Arc<LocalLspAdapterDelegate>,
 2648        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2649    )> {
 2650        if worktree.read(cx).is_visible() {
 2651            return None;
 2652        }
 2653
 2654        let worktree_store = self.worktree_store.read(cx);
 2655        let servers = server_tree
 2656            .instances
 2657            .iter()
 2658            .filter(|(worktree_id, _)| {
 2659                worktree_store
 2660                    .worktree_for_id(**worktree_id, cx)
 2661                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2662            })
 2663            .flat_map(|(worktree_id, servers)| {
 2664                servers
 2665                    .roots
 2666                    .iter()
 2667                    .flat_map(|(_, language_servers)| language_servers)
 2668                    .map(move |(_, (server_node, server_languages))| {
 2669                        (worktree_id, server_node, server_languages)
 2670                    })
 2671                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2672                    .map(|(worktree_id, server_node, _)| {
 2673                        (
 2674                            *worktree_id,
 2675                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2676                        )
 2677                    })
 2678            })
 2679            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2680                acc.entry(worktree_id)
 2681                    .or_insert_with(Vec::new)
 2682                    .push(server_node);
 2683                acc
 2684            })
 2685            .into_values()
 2686            .max_by_key(|servers| servers.len())?;
 2687
 2688        let worktree_id = worktree.read(cx).id();
 2689        let apply = move |tree: &mut LanguageServerTree| {
 2690            for server_node in &servers {
 2691                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2692            }
 2693            servers
 2694        };
 2695
 2696        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2697        Some((delegate, apply))
 2698    }
 2699
 2700    pub(crate) fn unregister_old_buffer_from_language_servers(
 2701        &mut self,
 2702        buffer: &Entity<Buffer>,
 2703        old_file: &File,
 2704        cx: &mut App,
 2705    ) {
 2706        let old_path = match old_file.as_local() {
 2707            Some(local) => local.abs_path(cx),
 2708            None => return,
 2709        };
 2710
 2711        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2712            debug_panic!("{old_path:?} is not parseable as an URI");
 2713            return;
 2714        };
 2715        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2716    }
 2717
 2718    pub(crate) fn unregister_buffer_from_language_servers(
 2719        &mut self,
 2720        buffer: &Entity<Buffer>,
 2721        file_url: &lsp::Uri,
 2722        cx: &mut App,
 2723    ) {
 2724        buffer.update(cx, |buffer, cx| {
 2725            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2726
 2727            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2728                if snapshots
 2729                    .as_mut()
 2730                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2731                {
 2732                    language_server.unregister_buffer(file_url.clone());
 2733                }
 2734            }
 2735        });
 2736    }
 2737
 2738    fn buffer_snapshot_for_lsp_version(
 2739        &mut self,
 2740        buffer: &Entity<Buffer>,
 2741        server_id: LanguageServerId,
 2742        version: Option<i32>,
 2743        cx: &App,
 2744    ) -> Result<TextBufferSnapshot> {
 2745        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2746
 2747        if let Some(version) = version {
 2748            let buffer_id = buffer.read(cx).remote_id();
 2749            let snapshots = if let Some(snapshots) = self
 2750                .buffer_snapshots
 2751                .get_mut(&buffer_id)
 2752                .and_then(|m| m.get_mut(&server_id))
 2753            {
 2754                snapshots
 2755            } else if version == 0 {
 2756                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2757                // We detect this case and treat it as if the version was `None`.
 2758                return Ok(buffer.read(cx).text_snapshot());
 2759            } else {
 2760                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2761            };
 2762
 2763            let found_snapshot = snapshots
 2764                    .binary_search_by_key(&version, |e| e.version)
 2765                    .map(|ix| snapshots[ix].snapshot.clone())
 2766                    .map_err(|_| {
 2767                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2768                    })?;
 2769
 2770            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2771            Ok(found_snapshot)
 2772        } else {
 2773            Ok((buffer.read(cx)).text_snapshot())
 2774        }
 2775    }
 2776
 2777    async fn get_server_code_actions_from_action_kinds(
 2778        lsp_store: &WeakEntity<LspStore>,
 2779        language_server_id: LanguageServerId,
 2780        code_action_kinds: Vec<lsp::CodeActionKind>,
 2781        buffer: &Entity<Buffer>,
 2782        cx: &mut AsyncApp,
 2783    ) -> Result<Vec<CodeAction>> {
 2784        let actions = lsp_store
 2785            .update(cx, move |this, cx| {
 2786                let request = GetCodeActions {
 2787                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2788                    kinds: Some(code_action_kinds),
 2789                };
 2790                let server = LanguageServerToQuery::Other(language_server_id);
 2791                this.request_lsp(buffer.clone(), server, request, cx)
 2792            })?
 2793            .await?;
 2794        Ok(actions)
 2795    }
 2796
 2797    pub async fn execute_code_actions_on_server(
 2798        lsp_store: &WeakEntity<LspStore>,
 2799        language_server: &Arc<LanguageServer>,
 2800
 2801        actions: Vec<CodeAction>,
 2802        push_to_history: bool,
 2803        project_transaction: &mut ProjectTransaction,
 2804        cx: &mut AsyncApp,
 2805    ) -> anyhow::Result<()> {
 2806        for mut action in actions {
 2807            Self::try_resolve_code_action(language_server, &mut action)
 2808                .await
 2809                .context("resolving a formatting code action")?;
 2810
 2811            if let Some(edit) = action.lsp_action.edit() {
 2812                if edit.changes.is_none() && edit.document_changes.is_none() {
 2813                    continue;
 2814                }
 2815
 2816                let new = Self::deserialize_workspace_edit(
 2817                    lsp_store.upgrade().context("project dropped")?,
 2818                    edit.clone(),
 2819                    push_to_history,
 2820                    language_server.clone(),
 2821                    cx,
 2822                )
 2823                .await?;
 2824                project_transaction.0.extend(new.0);
 2825            }
 2826
 2827            if let Some(command) = action.lsp_action.command() {
 2828                let server_capabilities = language_server.capabilities();
 2829                let available_commands = server_capabilities
 2830                    .execute_command_provider
 2831                    .as_ref()
 2832                    .map(|options| options.commands.as_slice())
 2833                    .unwrap_or_default();
 2834                if available_commands.contains(&command.command) {
 2835                    lsp_store.update(cx, |lsp_store, _| {
 2836                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2837                            mode.last_workspace_edits_by_language_server
 2838                                .remove(&language_server.server_id());
 2839                        }
 2840                    })?;
 2841
 2842                    language_server
 2843                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2844                            command: command.command.clone(),
 2845                            arguments: command.arguments.clone().unwrap_or_default(),
 2846                            ..Default::default()
 2847                        })
 2848                        .await
 2849                        .into_response()
 2850                        .context("execute command")?;
 2851
 2852                    lsp_store.update(cx, |this, _| {
 2853                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2854                            project_transaction.0.extend(
 2855                                mode.last_workspace_edits_by_language_server
 2856                                    .remove(&language_server.server_id())
 2857                                    .unwrap_or_default()
 2858                                    .0,
 2859                            )
 2860                        }
 2861                    })?;
 2862                } else {
 2863                    log::warn!(
 2864                        "Cannot execute a command {} not listed in the language server capabilities",
 2865                        command.command
 2866                    )
 2867                }
 2868            }
 2869        }
 2870        Ok(())
 2871    }
 2872
 2873    pub async fn deserialize_text_edits(
 2874        this: Entity<LspStore>,
 2875        buffer_to_edit: Entity<Buffer>,
 2876        edits: Vec<lsp::TextEdit>,
 2877        push_to_history: bool,
 2878        _: Arc<CachedLspAdapter>,
 2879        language_server: Arc<LanguageServer>,
 2880        cx: &mut AsyncApp,
 2881    ) -> Result<Option<Transaction>> {
 2882        let edits = this
 2883            .update(cx, |this, cx| {
 2884                this.as_local_mut().unwrap().edits_from_lsp(
 2885                    &buffer_to_edit,
 2886                    edits,
 2887                    language_server.server_id(),
 2888                    None,
 2889                    cx,
 2890                )
 2891            })?
 2892            .await?;
 2893
 2894        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2895            buffer.finalize_last_transaction();
 2896            buffer.start_transaction();
 2897            for (range, text) in edits {
 2898                buffer.edit([(range, text)], None, cx);
 2899            }
 2900
 2901            if buffer.end_transaction(cx).is_some() {
 2902                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2903                if !push_to_history {
 2904                    buffer.forget_transaction(transaction.id);
 2905                }
 2906                Some(transaction)
 2907            } else {
 2908                None
 2909            }
 2910        })?;
 2911
 2912        Ok(transaction)
 2913    }
 2914
 2915    #[allow(clippy::type_complexity)]
 2916    pub(crate) fn edits_from_lsp(
 2917        &mut self,
 2918        buffer: &Entity<Buffer>,
 2919        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2920        server_id: LanguageServerId,
 2921        version: Option<i32>,
 2922        cx: &mut Context<LspStore>,
 2923    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2924        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2925        cx.background_spawn(async move {
 2926            let snapshot = snapshot?;
 2927            let mut lsp_edits = lsp_edits
 2928                .into_iter()
 2929                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2930                .collect::<Vec<_>>();
 2931
 2932            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2933
 2934            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2935            let mut edits = Vec::new();
 2936            while let Some((range, mut new_text)) = lsp_edits.next() {
 2937                // Clip invalid ranges provided by the language server.
 2938                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2939                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2940
 2941                // Combine any LSP edits that are adjacent.
 2942                //
 2943                // Also, combine LSP edits that are separated from each other by only
 2944                // a newline. This is important because for some code actions,
 2945                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2946                // are separated by unchanged newline characters.
 2947                //
 2948                // In order for the diffing logic below to work properly, any edits that
 2949                // cancel each other out must be combined into one.
 2950                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2951                    if next_range.start.0 > range.end {
 2952                        if next_range.start.0.row > range.end.row + 1
 2953                            || next_range.start.0.column > 0
 2954                            || snapshot.clip_point_utf16(
 2955                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2956                                Bias::Left,
 2957                            ) > range.end
 2958                        {
 2959                            break;
 2960                        }
 2961                        new_text.push('\n');
 2962                    }
 2963                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2964                    new_text.push_str(next_text);
 2965                    lsp_edits.next();
 2966                }
 2967
 2968                // For multiline edits, perform a diff of the old and new text so that
 2969                // we can identify the changes more precisely, preserving the locations
 2970                // of any anchors positioned in the unchanged regions.
 2971                if range.end.row > range.start.row {
 2972                    let offset = range.start.to_offset(&snapshot);
 2973                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2974                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2975                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2976                        (
 2977                            snapshot.anchor_after(offset + range.start)
 2978                                ..snapshot.anchor_before(offset + range.end),
 2979                            replacement,
 2980                        )
 2981                    }));
 2982                } else if range.end == range.start {
 2983                    let anchor = snapshot.anchor_after(range.start);
 2984                    edits.push((anchor..anchor, new_text.into()));
 2985                } else {
 2986                    let edit_start = snapshot.anchor_after(range.start);
 2987                    let edit_end = snapshot.anchor_before(range.end);
 2988                    edits.push((edit_start..edit_end, new_text.into()));
 2989                }
 2990            }
 2991
 2992            Ok(edits)
 2993        })
 2994    }
 2995
 2996    pub(crate) async fn deserialize_workspace_edit(
 2997        this: Entity<LspStore>,
 2998        edit: lsp::WorkspaceEdit,
 2999        push_to_history: bool,
 3000        language_server: Arc<LanguageServer>,
 3001        cx: &mut AsyncApp,
 3002    ) -> Result<ProjectTransaction> {
 3003        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3004
 3005        let mut operations = Vec::new();
 3006        if let Some(document_changes) = edit.document_changes {
 3007            match document_changes {
 3008                lsp::DocumentChanges::Edits(edits) => {
 3009                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3010                }
 3011                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3012            }
 3013        } else if let Some(changes) = edit.changes {
 3014            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3015                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3016                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3017                        uri,
 3018                        version: None,
 3019                    },
 3020                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3021                })
 3022            }));
 3023        }
 3024
 3025        let mut project_transaction = ProjectTransaction::default();
 3026        for operation in operations {
 3027            match operation {
 3028                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3029                    let abs_path = op
 3030                        .uri
 3031                        .to_file_path()
 3032                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3033
 3034                    if let Some(parent_path) = abs_path.parent() {
 3035                        fs.create_dir(parent_path).await?;
 3036                    }
 3037                    if abs_path.ends_with("/") {
 3038                        fs.create_dir(&abs_path).await?;
 3039                    } else {
 3040                        fs.create_file(
 3041                            &abs_path,
 3042                            op.options
 3043                                .map(|options| fs::CreateOptions {
 3044                                    overwrite: options.overwrite.unwrap_or(false),
 3045                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3046                                })
 3047                                .unwrap_or_default(),
 3048                        )
 3049                        .await?;
 3050                    }
 3051                }
 3052
 3053                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3054                    let source_abs_path = op
 3055                        .old_uri
 3056                        .to_file_path()
 3057                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3058                    let target_abs_path = op
 3059                        .new_uri
 3060                        .to_file_path()
 3061                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3062
 3063                    let options = fs::RenameOptions {
 3064                        overwrite: op
 3065                            .options
 3066                            .as_ref()
 3067                            .and_then(|options| options.overwrite)
 3068                            .unwrap_or(false),
 3069                        ignore_if_exists: op
 3070                            .options
 3071                            .as_ref()
 3072                            .and_then(|options| options.ignore_if_exists)
 3073                            .unwrap_or(false),
 3074                        create_parents: true,
 3075                    };
 3076
 3077                    fs.rename(&source_abs_path, &target_abs_path, options)
 3078                        .await?;
 3079                }
 3080
 3081                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3082                    let abs_path = op
 3083                        .uri
 3084                        .to_file_path()
 3085                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3086                    let options = op
 3087                        .options
 3088                        .map(|options| fs::RemoveOptions {
 3089                            recursive: options.recursive.unwrap_or(false),
 3090                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3091                        })
 3092                        .unwrap_or_default();
 3093                    if abs_path.ends_with("/") {
 3094                        fs.remove_dir(&abs_path, options).await?;
 3095                    } else {
 3096                        fs.remove_file(&abs_path, options).await?;
 3097                    }
 3098                }
 3099
 3100                lsp::DocumentChangeOperation::Edit(op) => {
 3101                    let buffer_to_edit = this
 3102                        .update(cx, |this, cx| {
 3103                            this.open_local_buffer_via_lsp(
 3104                                op.text_document.uri.clone(),
 3105                                language_server.server_id(),
 3106                                cx,
 3107                            )
 3108                        })?
 3109                        .await?;
 3110
 3111                    let edits = this
 3112                        .update(cx, |this, cx| {
 3113                            let path = buffer_to_edit.read(cx).project_path(cx);
 3114                            let active_entry = this.active_entry;
 3115                            let is_active_entry = path.is_some_and(|project_path| {
 3116                                this.worktree_store
 3117                                    .read(cx)
 3118                                    .entry_for_path(&project_path, cx)
 3119                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3120                            });
 3121                            let local = this.as_local_mut().unwrap();
 3122
 3123                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3124                            for edit in op.edits {
 3125                                match edit {
 3126                                    Edit::Plain(edit) => {
 3127                                        if !edits.contains(&edit) {
 3128                                            edits.push(edit)
 3129                                        }
 3130                                    }
 3131                                    Edit::Annotated(edit) => {
 3132                                        if !edits.contains(&edit.text_edit) {
 3133                                            edits.push(edit.text_edit)
 3134                                        }
 3135                                    }
 3136                                    Edit::Snippet(edit) => {
 3137                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3138                                        else {
 3139                                            continue;
 3140                                        };
 3141
 3142                                        if is_active_entry {
 3143                                            snippet_edits.push((edit.range, snippet));
 3144                                        } else {
 3145                                            // Since this buffer is not focused, apply a normal edit.
 3146                                            let new_edit = TextEdit {
 3147                                                range: edit.range,
 3148                                                new_text: snippet.text,
 3149                                            };
 3150                                            if !edits.contains(&new_edit) {
 3151                                                edits.push(new_edit);
 3152                                            }
 3153                                        }
 3154                                    }
 3155                                }
 3156                            }
 3157                            if !snippet_edits.is_empty() {
 3158                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3159                                let version = if let Some(buffer_version) = op.text_document.version
 3160                                {
 3161                                    local
 3162                                        .buffer_snapshot_for_lsp_version(
 3163                                            &buffer_to_edit,
 3164                                            language_server.server_id(),
 3165                                            Some(buffer_version),
 3166                                            cx,
 3167                                        )
 3168                                        .ok()
 3169                                        .map(|snapshot| snapshot.version)
 3170                                } else {
 3171                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3172                                };
 3173
 3174                                let most_recent_edit =
 3175                                    version.and_then(|version| version.most_recent());
 3176                                // Check if the edit that triggered that edit has been made by this participant.
 3177
 3178                                if let Some(most_recent_edit) = most_recent_edit {
 3179                                    cx.emit(LspStoreEvent::SnippetEdit {
 3180                                        buffer_id,
 3181                                        edits: snippet_edits,
 3182                                        most_recent_edit,
 3183                                    });
 3184                                }
 3185                            }
 3186
 3187                            local.edits_from_lsp(
 3188                                &buffer_to_edit,
 3189                                edits,
 3190                                language_server.server_id(),
 3191                                op.text_document.version,
 3192                                cx,
 3193                            )
 3194                        })?
 3195                        .await?;
 3196
 3197                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3198                        buffer.finalize_last_transaction();
 3199                        buffer.start_transaction();
 3200                        for (range, text) in edits {
 3201                            buffer.edit([(range, text)], None, cx);
 3202                        }
 3203
 3204                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3205                            if push_to_history {
 3206                                buffer.finalize_last_transaction();
 3207                                buffer.get_transaction(transaction_id).cloned()
 3208                            } else {
 3209                                buffer.forget_transaction(transaction_id)
 3210                            }
 3211                        })
 3212                    })?;
 3213                    if let Some(transaction) = transaction {
 3214                        project_transaction.0.insert(buffer_to_edit, transaction);
 3215                    }
 3216                }
 3217            }
 3218        }
 3219
 3220        Ok(project_transaction)
 3221    }
 3222
 3223    async fn on_lsp_workspace_edit(
 3224        this: WeakEntity<LspStore>,
 3225        params: lsp::ApplyWorkspaceEditParams,
 3226        server_id: LanguageServerId,
 3227        cx: &mut AsyncApp,
 3228    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3229        let this = this.upgrade().context("project project closed")?;
 3230        let language_server = this
 3231            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3232            .context("language server not found")?;
 3233        let transaction = Self::deserialize_workspace_edit(
 3234            this.clone(),
 3235            params.edit,
 3236            true,
 3237            language_server.clone(),
 3238            cx,
 3239        )
 3240        .await
 3241        .log_err();
 3242        this.update(cx, |this, _| {
 3243            if let Some(transaction) = transaction {
 3244                this.as_local_mut()
 3245                    .unwrap()
 3246                    .last_workspace_edits_by_language_server
 3247                    .insert(server_id, transaction);
 3248            }
 3249        })?;
 3250        Ok(lsp::ApplyWorkspaceEditResponse {
 3251            applied: true,
 3252            failed_change: None,
 3253            failure_reason: None,
 3254        })
 3255    }
 3256
 3257    fn remove_worktree(
 3258        &mut self,
 3259        id_to_remove: WorktreeId,
 3260        cx: &mut Context<LspStore>,
 3261    ) -> Vec<LanguageServerId> {
 3262        self.diagnostics.remove(&id_to_remove);
 3263        self.prettier_store.update(cx, |prettier_store, cx| {
 3264            prettier_store.remove_worktree(id_to_remove, cx);
 3265        });
 3266
 3267        let mut servers_to_remove = BTreeSet::default();
 3268        let mut servers_to_preserve = HashSet::default();
 3269        for (seed, state) in &self.language_server_ids {
 3270            if seed.worktree_id == id_to_remove {
 3271                servers_to_remove.insert(state.id);
 3272            } else {
 3273                servers_to_preserve.insert(state.id);
 3274            }
 3275        }
 3276        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3277        self.language_server_ids
 3278            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3279        for server_id_to_remove in &servers_to_remove {
 3280            self.language_server_watched_paths
 3281                .remove(server_id_to_remove);
 3282            self.language_server_paths_watched_for_rename
 3283                .remove(server_id_to_remove);
 3284            self.last_workspace_edits_by_language_server
 3285                .remove(server_id_to_remove);
 3286            self.language_servers.remove(server_id_to_remove);
 3287            self.buffer_pull_diagnostics_result_ids
 3288                .remove(server_id_to_remove);
 3289            self.workspace_pull_diagnostics_result_ids
 3290                .remove(server_id_to_remove);
 3291            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3292                buffer_servers.remove(server_id_to_remove);
 3293            }
 3294            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3295        }
 3296        servers_to_remove.into_iter().collect()
 3297    }
 3298
 3299    fn rebuild_watched_paths_inner<'a>(
 3300        &'a self,
 3301        language_server_id: LanguageServerId,
 3302        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3303        cx: &mut Context<LspStore>,
 3304    ) -> LanguageServerWatchedPathsBuilder {
 3305        let worktrees = self
 3306            .worktree_store
 3307            .read(cx)
 3308            .worktrees()
 3309            .filter_map(|worktree| {
 3310                self.language_servers_for_worktree(worktree.read(cx).id())
 3311                    .find(|server| server.server_id() == language_server_id)
 3312                    .map(|_| worktree)
 3313            })
 3314            .collect::<Vec<_>>();
 3315
 3316        let mut worktree_globs = HashMap::default();
 3317        let mut abs_globs = HashMap::default();
 3318        log::trace!(
 3319            "Processing new watcher paths for language server with id {}",
 3320            language_server_id
 3321        );
 3322
 3323        for watcher in watchers {
 3324            if let Some((worktree, literal_prefix, pattern)) =
 3325                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3326            {
 3327                worktree.update(cx, |worktree, _| {
 3328                    if let Some((tree, glob)) =
 3329                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3330                    {
 3331                        tree.add_path_prefix_to_scan(literal_prefix);
 3332                        worktree_globs
 3333                            .entry(tree.id())
 3334                            .or_insert_with(GlobSetBuilder::new)
 3335                            .add(glob);
 3336                    }
 3337                });
 3338            } else {
 3339                let (path, pattern) = match &watcher.glob_pattern {
 3340                    lsp::GlobPattern::String(s) => {
 3341                        let watcher_path = SanitizedPath::new(s);
 3342                        let path = glob_literal_prefix(watcher_path.as_path());
 3343                        let pattern = watcher_path
 3344                            .as_path()
 3345                            .strip_prefix(&path)
 3346                            .map(|p| p.to_string_lossy().into_owned())
 3347                            .unwrap_or_else(|e| {
 3348                                debug_panic!(
 3349                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3350                                    s,
 3351                                    path.display(),
 3352                                    e
 3353                                );
 3354                                watcher_path.as_path().to_string_lossy().into_owned()
 3355                            });
 3356                        (path, pattern)
 3357                    }
 3358                    lsp::GlobPattern::Relative(rp) => {
 3359                        let Ok(mut base_uri) = match &rp.base_uri {
 3360                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3361                            lsp::OneOf::Right(base_uri) => base_uri,
 3362                        }
 3363                        .to_file_path() else {
 3364                            continue;
 3365                        };
 3366
 3367                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3368                        let pattern = Path::new(&rp.pattern)
 3369                            .strip_prefix(&path)
 3370                            .map(|p| p.to_string_lossy().into_owned())
 3371                            .unwrap_or_else(|e| {
 3372                                debug_panic!(
 3373                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3374                                    rp.pattern,
 3375                                    path.display(),
 3376                                    e
 3377                                );
 3378                                rp.pattern.clone()
 3379                            });
 3380                        base_uri.push(path);
 3381                        (base_uri, pattern)
 3382                    }
 3383                };
 3384
 3385                if let Some(glob) = Glob::new(&pattern).log_err() {
 3386                    if !path
 3387                        .components()
 3388                        .any(|c| matches!(c, path::Component::Normal(_)))
 3389                    {
 3390                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3391                        // rather than adding a new watcher for `/`.
 3392                        for worktree in &worktrees {
 3393                            worktree_globs
 3394                                .entry(worktree.read(cx).id())
 3395                                .or_insert_with(GlobSetBuilder::new)
 3396                                .add(glob.clone());
 3397                        }
 3398                    } else {
 3399                        abs_globs
 3400                            .entry(path.into())
 3401                            .or_insert_with(GlobSetBuilder::new)
 3402                            .add(glob);
 3403                    }
 3404                }
 3405            }
 3406        }
 3407
 3408        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3409        for (worktree_id, builder) in worktree_globs {
 3410            if let Ok(globset) = builder.build() {
 3411                watch_builder.watch_worktree(worktree_id, globset);
 3412            }
 3413        }
 3414        for (abs_path, builder) in abs_globs {
 3415            if let Ok(globset) = builder.build() {
 3416                watch_builder.watch_abs_path(abs_path, globset);
 3417            }
 3418        }
 3419        watch_builder
 3420    }
 3421
 3422    fn worktree_and_path_for_file_watcher(
 3423        worktrees: &[Entity<Worktree>],
 3424        watcher: &FileSystemWatcher,
 3425        cx: &App,
 3426    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3427        worktrees.iter().find_map(|worktree| {
 3428            let tree = worktree.read(cx);
 3429            let worktree_root_path = tree.abs_path();
 3430            let path_style = tree.path_style();
 3431            match &watcher.glob_pattern {
 3432                lsp::GlobPattern::String(s) => {
 3433                    let watcher_path = SanitizedPath::new(s);
 3434                    let relative = watcher_path
 3435                        .as_path()
 3436                        .strip_prefix(&worktree_root_path)
 3437                        .ok()?;
 3438                    let literal_prefix = glob_literal_prefix(relative);
 3439                    Some((
 3440                        worktree.clone(),
 3441                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3442                        relative.to_string_lossy().into_owned(),
 3443                    ))
 3444                }
 3445                lsp::GlobPattern::Relative(rp) => {
 3446                    let base_uri = match &rp.base_uri {
 3447                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3448                        lsp::OneOf::Right(base_uri) => base_uri,
 3449                    }
 3450                    .to_file_path()
 3451                    .ok()?;
 3452                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3453                    let mut literal_prefix = relative.to_owned();
 3454                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3455                    Some((
 3456                        worktree.clone(),
 3457                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3458                        rp.pattern.clone(),
 3459                    ))
 3460                }
 3461            }
 3462        })
 3463    }
 3464
 3465    fn rebuild_watched_paths(
 3466        &mut self,
 3467        language_server_id: LanguageServerId,
 3468        cx: &mut Context<LspStore>,
 3469    ) {
 3470        let Some(registrations) = self
 3471            .language_server_dynamic_registrations
 3472            .get(&language_server_id)
 3473        else {
 3474            return;
 3475        };
 3476
 3477        let watch_builder = self.rebuild_watched_paths_inner(
 3478            language_server_id,
 3479            registrations.did_change_watched_files.values().flatten(),
 3480            cx,
 3481        );
 3482        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3483        self.language_server_watched_paths
 3484            .insert(language_server_id, watcher);
 3485
 3486        cx.notify();
 3487    }
 3488
 3489    fn on_lsp_did_change_watched_files(
 3490        &mut self,
 3491        language_server_id: LanguageServerId,
 3492        registration_id: &str,
 3493        params: DidChangeWatchedFilesRegistrationOptions,
 3494        cx: &mut Context<LspStore>,
 3495    ) {
 3496        let registrations = self
 3497            .language_server_dynamic_registrations
 3498            .entry(language_server_id)
 3499            .or_default();
 3500
 3501        registrations
 3502            .did_change_watched_files
 3503            .insert(registration_id.to_string(), params.watchers);
 3504
 3505        self.rebuild_watched_paths(language_server_id, cx);
 3506    }
 3507
 3508    fn on_lsp_unregister_did_change_watched_files(
 3509        &mut self,
 3510        language_server_id: LanguageServerId,
 3511        registration_id: &str,
 3512        cx: &mut Context<LspStore>,
 3513    ) {
 3514        let registrations = self
 3515            .language_server_dynamic_registrations
 3516            .entry(language_server_id)
 3517            .or_default();
 3518
 3519        if registrations
 3520            .did_change_watched_files
 3521            .remove(registration_id)
 3522            .is_some()
 3523        {
 3524            log::info!(
 3525                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3526                language_server_id,
 3527                registration_id
 3528            );
 3529        } else {
 3530            log::warn!(
 3531                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3532                language_server_id,
 3533                registration_id
 3534            );
 3535        }
 3536
 3537        self.rebuild_watched_paths(language_server_id, cx);
 3538    }
 3539
 3540    async fn initialization_options_for_adapter(
 3541        adapter: Arc<dyn LspAdapter>,
 3542        delegate: &Arc<dyn LspAdapterDelegate>,
 3543    ) -> Result<Option<serde_json::Value>> {
 3544        let Some(mut initialization_config) =
 3545            adapter.clone().initialization_options(delegate).await?
 3546        else {
 3547            return Ok(None);
 3548        };
 3549
 3550        for other_adapter in delegate.registered_lsp_adapters() {
 3551            if other_adapter.name() == adapter.name() {
 3552                continue;
 3553            }
 3554            if let Ok(Some(target_config)) = other_adapter
 3555                .clone()
 3556                .additional_initialization_options(adapter.name(), delegate)
 3557                .await
 3558            {
 3559                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3560            }
 3561        }
 3562
 3563        Ok(Some(initialization_config))
 3564    }
 3565
 3566    async fn workspace_configuration_for_adapter(
 3567        adapter: Arc<dyn LspAdapter>,
 3568        delegate: &Arc<dyn LspAdapterDelegate>,
 3569        toolchain: Option<Toolchain>,
 3570        requested_uri: Option<Uri>,
 3571        cx: &mut AsyncApp,
 3572    ) -> Result<serde_json::Value> {
 3573        let mut workspace_config = adapter
 3574            .clone()
 3575            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3576            .await?;
 3577
 3578        for other_adapter in delegate.registered_lsp_adapters() {
 3579            if other_adapter.name() == adapter.name() {
 3580                continue;
 3581            }
 3582            if let Ok(Some(target_config)) = other_adapter
 3583                .clone()
 3584                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3585                .await
 3586            {
 3587                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3588            }
 3589        }
 3590
 3591        Ok(workspace_config)
 3592    }
 3593
 3594    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3595        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3596            Some(server.clone())
 3597        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3598            Some(Arc::clone(server))
 3599        } else {
 3600            None
 3601        }
 3602    }
 3603}
 3604
 3605fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3606    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3607        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3608            language_server_id: server.server_id(),
 3609            name: Some(server.name()),
 3610            message: proto::update_language_server::Variant::MetadataUpdated(
 3611                proto::ServerMetadataUpdated {
 3612                    capabilities: Some(capabilities),
 3613                    binary: Some(proto::LanguageServerBinaryInfo {
 3614                        path: server.binary().path.to_string_lossy().into_owned(),
 3615                        arguments: server
 3616                            .binary()
 3617                            .arguments
 3618                            .iter()
 3619                            .map(|arg| arg.to_string_lossy().into_owned())
 3620                            .collect(),
 3621                    }),
 3622                    configuration: serde_json::to_string(server.configuration()).ok(),
 3623                    workspace_folders: server
 3624                        .workspace_folders()
 3625                        .iter()
 3626                        .map(|uri| uri.to_string())
 3627                        .collect(),
 3628                },
 3629            ),
 3630        });
 3631    }
 3632}
 3633
 3634#[derive(Debug)]
 3635pub struct FormattableBuffer {
 3636    handle: Entity<Buffer>,
 3637    abs_path: Option<PathBuf>,
 3638    env: Option<HashMap<String, String>>,
 3639    ranges: Option<Vec<Range<Anchor>>>,
 3640}
 3641
 3642pub struct RemoteLspStore {
 3643    upstream_client: Option<AnyProtoClient>,
 3644    upstream_project_id: u64,
 3645}
 3646
 3647pub(crate) enum LspStoreMode {
 3648    Local(LocalLspStore),   // ssh host and collab host
 3649    Remote(RemoteLspStore), // collab guest
 3650}
 3651
 3652impl LspStoreMode {
 3653    fn is_local(&self) -> bool {
 3654        matches!(self, LspStoreMode::Local(_))
 3655    }
 3656}
 3657
 3658pub struct LspStore {
 3659    mode: LspStoreMode,
 3660    last_formatting_failure: Option<String>,
 3661    downstream_client: Option<(AnyProtoClient, u64)>,
 3662    nonce: u128,
 3663    buffer_store: Entity<BufferStore>,
 3664    worktree_store: Entity<WorktreeStore>,
 3665    pub languages: Arc<LanguageRegistry>,
 3666    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3667    active_entry: Option<ProjectEntryId>,
 3668    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3669    _maintain_buffer_languages: Task<()>,
 3670    diagnostic_summaries:
 3671        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3672    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3673    lsp_data: HashMap<BufferId, BufferLspData>,
 3674    next_hint_id: Arc<AtomicUsize>,
 3675}
 3676
 3677#[derive(Debug)]
 3678pub struct BufferLspData {
 3679    buffer_version: Global,
 3680    document_colors: Option<DocumentColorData>,
 3681    code_lens: Option<CodeLensData>,
 3682    inlay_hints: BufferInlayHints,
 3683    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3684    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3685}
 3686
 3687#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3688struct LspKey {
 3689    request_type: TypeId,
 3690    server_queried: Option<LanguageServerId>,
 3691}
 3692
 3693impl BufferLspData {
 3694    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3695        Self {
 3696            buffer_version: buffer.read(cx).version(),
 3697            document_colors: None,
 3698            code_lens: None,
 3699            inlay_hints: BufferInlayHints::new(buffer, cx),
 3700            lsp_requests: HashMap::default(),
 3701            chunk_lsp_requests: HashMap::default(),
 3702        }
 3703    }
 3704
 3705    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3706        if let Some(document_colors) = &mut self.document_colors {
 3707            document_colors.colors.remove(&for_server);
 3708            document_colors.cache_version += 1;
 3709        }
 3710
 3711        if let Some(code_lens) = &mut self.code_lens {
 3712            code_lens.lens.remove(&for_server);
 3713        }
 3714
 3715        self.inlay_hints.remove_server_data(for_server);
 3716    }
 3717
 3718    #[cfg(any(test, feature = "test-support"))]
 3719    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3720        &self.inlay_hints
 3721    }
 3722}
 3723
 3724#[derive(Debug, Default, Clone)]
 3725pub struct DocumentColors {
 3726    pub colors: HashSet<DocumentColor>,
 3727    pub cache_version: Option<usize>,
 3728}
 3729
 3730type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3731type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3732
 3733#[derive(Debug, Default)]
 3734struct DocumentColorData {
 3735    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3736    cache_version: usize,
 3737    colors_update: Option<(Global, DocumentColorTask)>,
 3738}
 3739
 3740#[derive(Debug, Default)]
 3741struct CodeLensData {
 3742    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3743    update: Option<(Global, CodeLensTask)>,
 3744}
 3745
 3746#[derive(Debug)]
 3747pub enum LspStoreEvent {
 3748    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3749    LanguageServerRemoved(LanguageServerId),
 3750    LanguageServerUpdate {
 3751        language_server_id: LanguageServerId,
 3752        name: Option<LanguageServerName>,
 3753        message: proto::update_language_server::Variant,
 3754    },
 3755    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3756    LanguageServerPrompt(LanguageServerPromptRequest),
 3757    LanguageDetected {
 3758        buffer: Entity<Buffer>,
 3759        new_language: Option<Arc<Language>>,
 3760    },
 3761    Notification(String),
 3762    RefreshInlayHints {
 3763        server_id: LanguageServerId,
 3764        request_id: Option<usize>,
 3765    },
 3766    RefreshCodeLens,
 3767    DiagnosticsUpdated {
 3768        server_id: LanguageServerId,
 3769        paths: Vec<ProjectPath>,
 3770    },
 3771    DiskBasedDiagnosticsStarted {
 3772        language_server_id: LanguageServerId,
 3773    },
 3774    DiskBasedDiagnosticsFinished {
 3775        language_server_id: LanguageServerId,
 3776    },
 3777    SnippetEdit {
 3778        buffer_id: BufferId,
 3779        edits: Vec<(lsp::Range, Snippet)>,
 3780        most_recent_edit: clock::Lamport,
 3781    },
 3782}
 3783
 3784#[derive(Clone, Debug, Serialize)]
 3785pub struct LanguageServerStatus {
 3786    pub name: LanguageServerName,
 3787    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3788    pub has_pending_diagnostic_updates: bool,
 3789    pub progress_tokens: HashSet<ProgressToken>,
 3790    pub worktree: Option<WorktreeId>,
 3791    pub binary: Option<LanguageServerBinary>,
 3792    pub configuration: Option<Value>,
 3793    pub workspace_folders: BTreeSet<Uri>,
 3794}
 3795
 3796#[derive(Clone, Debug)]
 3797struct CoreSymbol {
 3798    pub language_server_name: LanguageServerName,
 3799    pub source_worktree_id: WorktreeId,
 3800    pub source_language_server_id: LanguageServerId,
 3801    pub path: SymbolLocation,
 3802    pub name: String,
 3803    pub kind: lsp::SymbolKind,
 3804    pub range: Range<Unclipped<PointUtf16>>,
 3805}
 3806
 3807#[derive(Clone, Debug, PartialEq, Eq)]
 3808pub enum SymbolLocation {
 3809    InProject(ProjectPath),
 3810    OutsideProject {
 3811        abs_path: Arc<Path>,
 3812        signature: [u8; 32],
 3813    },
 3814}
 3815
 3816impl SymbolLocation {
 3817    fn file_name(&self) -> Option<&str> {
 3818        match self {
 3819            Self::InProject(path) => path.path.file_name(),
 3820            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3821        }
 3822    }
 3823}
 3824
 3825impl LspStore {
 3826    pub fn init(client: &AnyProtoClient) {
 3827        client.add_entity_request_handler(Self::handle_lsp_query);
 3828        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3829        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3830        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3831        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3832        client.add_entity_message_handler(Self::handle_start_language_server);
 3833        client.add_entity_message_handler(Self::handle_update_language_server);
 3834        client.add_entity_message_handler(Self::handle_language_server_log);
 3835        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3836        client.add_entity_request_handler(Self::handle_format_buffers);
 3837        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3838        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3839        client.add_entity_request_handler(Self::handle_apply_code_action);
 3840        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3841        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3842        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3843        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3844        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3845        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3846        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3847        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3848        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3849        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3850        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3851        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3852        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3853        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3854        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3855        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3856        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3857
 3858        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3859        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3860        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3861        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3862        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3863        client.add_entity_request_handler(
 3864            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3865        );
 3866        client.add_entity_request_handler(
 3867            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3868        );
 3869        client.add_entity_request_handler(
 3870            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3871        );
 3872    }
 3873
 3874    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3875        match &self.mode {
 3876            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3877            _ => None,
 3878        }
 3879    }
 3880
 3881    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3882        match &self.mode {
 3883            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3884            _ => None,
 3885        }
 3886    }
 3887
 3888    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3889        match &mut self.mode {
 3890            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3891            _ => None,
 3892        }
 3893    }
 3894
 3895    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3896        match &self.mode {
 3897            LspStoreMode::Remote(RemoteLspStore {
 3898                upstream_client: Some(upstream_client),
 3899                upstream_project_id,
 3900                ..
 3901            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3902
 3903            LspStoreMode::Remote(RemoteLspStore {
 3904                upstream_client: None,
 3905                ..
 3906            }) => None,
 3907            LspStoreMode::Local(_) => None,
 3908        }
 3909    }
 3910
 3911    pub fn new_local(
 3912        buffer_store: Entity<BufferStore>,
 3913        worktree_store: Entity<WorktreeStore>,
 3914        prettier_store: Entity<PrettierStore>,
 3915        toolchain_store: Entity<LocalToolchainStore>,
 3916        environment: Entity<ProjectEnvironment>,
 3917        manifest_tree: Entity<ManifestTree>,
 3918        languages: Arc<LanguageRegistry>,
 3919        http_client: Arc<dyn HttpClient>,
 3920        fs: Arc<dyn Fs>,
 3921        cx: &mut Context<Self>,
 3922    ) -> Self {
 3923        let yarn = YarnPathStore::new(fs.clone(), cx);
 3924        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3925            .detach();
 3926        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3927            .detach();
 3928        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3929            .detach();
 3930        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3931            .detach();
 3932        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3933            .detach();
 3934        subscribe_to_binary_statuses(&languages, cx).detach();
 3935
 3936        let _maintain_workspace_config = {
 3937            let (sender, receiver) = watch::channel();
 3938            (Self::maintain_workspace_config(receiver, cx), sender)
 3939        };
 3940
 3941        Self {
 3942            mode: LspStoreMode::Local(LocalLspStore {
 3943                weak: cx.weak_entity(),
 3944                worktree_store: worktree_store.clone(),
 3945
 3946                supplementary_language_servers: Default::default(),
 3947                languages: languages.clone(),
 3948                language_server_ids: Default::default(),
 3949                language_servers: Default::default(),
 3950                last_workspace_edits_by_language_server: Default::default(),
 3951                language_server_watched_paths: Default::default(),
 3952                language_server_paths_watched_for_rename: Default::default(),
 3953                language_server_dynamic_registrations: Default::default(),
 3954                buffers_being_formatted: Default::default(),
 3955                buffer_snapshots: Default::default(),
 3956                prettier_store,
 3957                environment,
 3958                http_client,
 3959                fs,
 3960                yarn,
 3961                next_diagnostic_group_id: Default::default(),
 3962                diagnostics: Default::default(),
 3963                _subscription: cx.on_app_quit(|this, cx| {
 3964                    this.as_local_mut()
 3965                        .unwrap()
 3966                        .shutdown_language_servers_on_quit(cx)
 3967                }),
 3968                lsp_tree: LanguageServerTree::new(
 3969                    manifest_tree,
 3970                    languages.clone(),
 3971                    toolchain_store.clone(),
 3972                ),
 3973                toolchain_store,
 3974                registered_buffers: HashMap::default(),
 3975                buffers_opened_in_servers: HashMap::default(),
 3976                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3977                workspace_pull_diagnostics_result_ids: HashMap::default(),
 3978                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3979                    .manifest_file_names(),
 3980            }),
 3981            last_formatting_failure: None,
 3982            downstream_client: None,
 3983            buffer_store,
 3984            worktree_store,
 3985            languages: languages.clone(),
 3986            language_server_statuses: Default::default(),
 3987            nonce: StdRng::from_os_rng().random(),
 3988            diagnostic_summaries: HashMap::default(),
 3989            lsp_server_capabilities: HashMap::default(),
 3990            lsp_data: HashMap::default(),
 3991            next_hint_id: Arc::default(),
 3992            active_entry: None,
 3993            _maintain_workspace_config,
 3994            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3995        }
 3996    }
 3997
 3998    fn send_lsp_proto_request<R: LspCommand>(
 3999        &self,
 4000        buffer: Entity<Buffer>,
 4001        client: AnyProtoClient,
 4002        upstream_project_id: u64,
 4003        request: R,
 4004        cx: &mut Context<LspStore>,
 4005    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4006        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4007            return Task::ready(Ok(R::Response::default()));
 4008        }
 4009        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4010        cx.spawn(async move |this, cx| {
 4011            let response = client.request(message).await?;
 4012            let this = this.upgrade().context("project dropped")?;
 4013            request
 4014                .response_from_proto(response, this, buffer, cx.clone())
 4015                .await
 4016        })
 4017    }
 4018
 4019    pub(super) fn new_remote(
 4020        buffer_store: Entity<BufferStore>,
 4021        worktree_store: Entity<WorktreeStore>,
 4022        languages: Arc<LanguageRegistry>,
 4023        upstream_client: AnyProtoClient,
 4024        project_id: u64,
 4025        cx: &mut Context<Self>,
 4026    ) -> Self {
 4027        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4028            .detach();
 4029        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4030            .detach();
 4031        subscribe_to_binary_statuses(&languages, cx).detach();
 4032        let _maintain_workspace_config = {
 4033            let (sender, receiver) = watch::channel();
 4034            (Self::maintain_workspace_config(receiver, cx), sender)
 4035        };
 4036        Self {
 4037            mode: LspStoreMode::Remote(RemoteLspStore {
 4038                upstream_client: Some(upstream_client),
 4039                upstream_project_id: project_id,
 4040            }),
 4041            downstream_client: None,
 4042            last_formatting_failure: None,
 4043            buffer_store,
 4044            worktree_store,
 4045            languages: languages.clone(),
 4046            language_server_statuses: Default::default(),
 4047            nonce: StdRng::from_os_rng().random(),
 4048            diagnostic_summaries: HashMap::default(),
 4049            lsp_server_capabilities: HashMap::default(),
 4050            next_hint_id: Arc::default(),
 4051            lsp_data: HashMap::default(),
 4052            active_entry: None,
 4053
 4054            _maintain_workspace_config,
 4055            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4056        }
 4057    }
 4058
 4059    fn on_buffer_store_event(
 4060        &mut self,
 4061        _: Entity<BufferStore>,
 4062        event: &BufferStoreEvent,
 4063        cx: &mut Context<Self>,
 4064    ) {
 4065        match event {
 4066            BufferStoreEvent::BufferAdded(buffer) => {
 4067                self.on_buffer_added(buffer, cx).log_err();
 4068            }
 4069            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4070                let buffer_id = buffer.read(cx).remote_id();
 4071                if let Some(local) = self.as_local_mut()
 4072                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4073                {
 4074                    local.reset_buffer(buffer, old_file, cx);
 4075
 4076                    if local.registered_buffers.contains_key(&buffer_id) {
 4077                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4078                    }
 4079                }
 4080
 4081                self.detect_language_for_buffer(buffer, cx);
 4082                if let Some(local) = self.as_local_mut() {
 4083                    local.initialize_buffer(buffer, cx);
 4084                    if local.registered_buffers.contains_key(&buffer_id) {
 4085                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4086                    }
 4087                }
 4088            }
 4089            _ => {}
 4090        }
 4091    }
 4092
 4093    fn on_worktree_store_event(
 4094        &mut self,
 4095        _: Entity<WorktreeStore>,
 4096        event: &WorktreeStoreEvent,
 4097        cx: &mut Context<Self>,
 4098    ) {
 4099        match event {
 4100            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4101                if !worktree.read(cx).is_local() {
 4102                    return;
 4103                }
 4104                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4105                    worktree::Event::UpdatedEntries(changes) => {
 4106                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4107                    }
 4108                    worktree::Event::UpdatedGitRepositories(_)
 4109                    | worktree::Event::DeletedEntry(_) => {}
 4110                })
 4111                .detach()
 4112            }
 4113            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4114            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4115                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4116            }
 4117            WorktreeStoreEvent::WorktreeReleased(..)
 4118            | WorktreeStoreEvent::WorktreeOrderChanged
 4119            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4120            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4121            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4122        }
 4123    }
 4124
 4125    fn on_prettier_store_event(
 4126        &mut self,
 4127        _: Entity<PrettierStore>,
 4128        event: &PrettierStoreEvent,
 4129        cx: &mut Context<Self>,
 4130    ) {
 4131        match event {
 4132            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4133                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4134            }
 4135            PrettierStoreEvent::LanguageServerAdded {
 4136                new_server_id,
 4137                name,
 4138                prettier_server,
 4139            } => {
 4140                self.register_supplementary_language_server(
 4141                    *new_server_id,
 4142                    name.clone(),
 4143                    prettier_server.clone(),
 4144                    cx,
 4145                );
 4146            }
 4147        }
 4148    }
 4149
 4150    fn on_toolchain_store_event(
 4151        &mut self,
 4152        _: Entity<LocalToolchainStore>,
 4153        event: &ToolchainStoreEvent,
 4154        _: &mut Context<Self>,
 4155    ) {
 4156        if let ToolchainStoreEvent::ToolchainActivated = event {
 4157            self.request_workspace_config_refresh()
 4158        }
 4159    }
 4160
 4161    fn request_workspace_config_refresh(&mut self) {
 4162        *self._maintain_workspace_config.1.borrow_mut() = ();
 4163    }
 4164
 4165    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4166        self.as_local().map(|local| local.prettier_store.clone())
 4167    }
 4168
 4169    fn on_buffer_event(
 4170        &mut self,
 4171        buffer: Entity<Buffer>,
 4172        event: &language::BufferEvent,
 4173        cx: &mut Context<Self>,
 4174    ) {
 4175        match event {
 4176            language::BufferEvent::Edited => {
 4177                self.on_buffer_edited(buffer, cx);
 4178            }
 4179
 4180            language::BufferEvent::Saved => {
 4181                self.on_buffer_saved(buffer, cx);
 4182            }
 4183
 4184            _ => {}
 4185        }
 4186    }
 4187
 4188    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4189        buffer
 4190            .read(cx)
 4191            .set_language_registry(self.languages.clone());
 4192
 4193        cx.subscribe(buffer, |this, buffer, event, cx| {
 4194            this.on_buffer_event(buffer, event, cx);
 4195        })
 4196        .detach();
 4197
 4198        self.detect_language_for_buffer(buffer, cx);
 4199        if let Some(local) = self.as_local_mut() {
 4200            local.initialize_buffer(buffer, cx);
 4201        }
 4202
 4203        Ok(())
 4204    }
 4205
 4206    pub(crate) fn register_buffer_with_language_servers(
 4207        &mut self,
 4208        buffer: &Entity<Buffer>,
 4209        only_register_servers: HashSet<LanguageServerSelector>,
 4210        ignore_refcounts: bool,
 4211        cx: &mut Context<Self>,
 4212    ) -> OpenLspBufferHandle {
 4213        let buffer_id = buffer.read(cx).remote_id();
 4214        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4215        if let Some(local) = self.as_local_mut() {
 4216            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4217            if !ignore_refcounts {
 4218                *refcount += 1;
 4219            }
 4220
 4221            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4222            // 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
 4223            // 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
 4224            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4225            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4226                return handle;
 4227            };
 4228            if !file.is_local() {
 4229                return handle;
 4230            }
 4231
 4232            if ignore_refcounts || *refcount == 1 {
 4233                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4234            }
 4235            if !ignore_refcounts {
 4236                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4237                    let refcount = {
 4238                        let local = lsp_store.as_local_mut().unwrap();
 4239                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4240                            debug_panic!("bad refcounting");
 4241                            return;
 4242                        };
 4243
 4244                        *refcount -= 1;
 4245                        *refcount
 4246                    };
 4247                    if refcount == 0 {
 4248                        lsp_store.lsp_data.remove(&buffer_id);
 4249                        let local = lsp_store.as_local_mut().unwrap();
 4250                        local.registered_buffers.remove(&buffer_id);
 4251
 4252                        local.buffers_opened_in_servers.remove(&buffer_id);
 4253                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4254                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4255
 4256                            let buffer_abs_path = file.abs_path(cx);
 4257                            for (_, buffer_pull_diagnostics_result_ids) in
 4258                                &mut local.buffer_pull_diagnostics_result_ids
 4259                            {
 4260                                buffer_pull_diagnostics_result_ids.retain(
 4261                                    |_, buffer_result_ids| {
 4262                                        buffer_result_ids.remove(&buffer_abs_path);
 4263                                        !buffer_result_ids.is_empty()
 4264                                    },
 4265                                );
 4266                            }
 4267
 4268                            let diagnostic_updates = local
 4269                                .language_servers
 4270                                .keys()
 4271                                .cloned()
 4272                                .map(|server_id| DocumentDiagnosticsUpdate {
 4273                                    diagnostics: DocumentDiagnostics {
 4274                                        document_abs_path: buffer_abs_path.clone(),
 4275                                        version: None,
 4276                                        diagnostics: Vec::new(),
 4277                                    },
 4278                                    result_id: None,
 4279                                    registration_id: None,
 4280                                    server_id: server_id,
 4281                                    disk_based_sources: Cow::Borrowed(&[]),
 4282                                })
 4283                                .collect::<Vec<_>>();
 4284
 4285                            lsp_store
 4286                                .merge_diagnostic_entries(
 4287                                    diagnostic_updates,
 4288                                    |_, diagnostic, _| {
 4289                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4290                                    },
 4291                                    cx,
 4292                                )
 4293                                .context("Clearing diagnostics for the closed buffer")
 4294                                .log_err();
 4295                        }
 4296                    }
 4297                })
 4298                .detach();
 4299            }
 4300        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4301            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4302            cx.background_spawn(async move {
 4303                upstream_client
 4304                    .request(proto::RegisterBufferWithLanguageServers {
 4305                        project_id: upstream_project_id,
 4306                        buffer_id,
 4307                        only_servers: only_register_servers
 4308                            .into_iter()
 4309                            .map(|selector| {
 4310                                let selector = match selector {
 4311                                    LanguageServerSelector::Id(language_server_id) => {
 4312                                        proto::language_server_selector::Selector::ServerId(
 4313                                            language_server_id.to_proto(),
 4314                                        )
 4315                                    }
 4316                                    LanguageServerSelector::Name(language_server_name) => {
 4317                                        proto::language_server_selector::Selector::Name(
 4318                                            language_server_name.to_string(),
 4319                                        )
 4320                                    }
 4321                                };
 4322                                proto::LanguageServerSelector {
 4323                                    selector: Some(selector),
 4324                                }
 4325                            })
 4326                            .collect(),
 4327                    })
 4328                    .await
 4329            })
 4330            .detach();
 4331        } else {
 4332            // Our remote connection got closed
 4333        }
 4334        handle
 4335    }
 4336
 4337    fn maintain_buffer_languages(
 4338        languages: Arc<LanguageRegistry>,
 4339        cx: &mut Context<Self>,
 4340    ) -> Task<()> {
 4341        let mut subscription = languages.subscribe();
 4342        let mut prev_reload_count = languages.reload_count();
 4343        cx.spawn(async move |this, cx| {
 4344            while let Some(()) = subscription.next().await {
 4345                if let Some(this) = this.upgrade() {
 4346                    // If the language registry has been reloaded, then remove and
 4347                    // re-assign the languages on all open buffers.
 4348                    let reload_count = languages.reload_count();
 4349                    if reload_count > prev_reload_count {
 4350                        prev_reload_count = reload_count;
 4351                        this.update(cx, |this, cx| {
 4352                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4353                                for buffer in buffer_store.buffers() {
 4354                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4355                                    {
 4356                                        buffer.update(cx, |buffer, cx| {
 4357                                            buffer.set_language_async(None, cx)
 4358                                        });
 4359                                        if let Some(local) = this.as_local_mut() {
 4360                                            local.reset_buffer(&buffer, &f, cx);
 4361
 4362                                            if local
 4363                                                .registered_buffers
 4364                                                .contains_key(&buffer.read(cx).remote_id())
 4365                                                && let Some(file_url) =
 4366                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4367                                            {
 4368                                                local.unregister_buffer_from_language_servers(
 4369                                                    &buffer, &file_url, cx,
 4370                                                );
 4371                                            }
 4372                                        }
 4373                                    }
 4374                                }
 4375                            });
 4376                        })
 4377                        .ok();
 4378                    }
 4379
 4380                    this.update(cx, |this, cx| {
 4381                        let mut plain_text_buffers = Vec::new();
 4382                        let mut buffers_with_unknown_injections = Vec::new();
 4383                        for handle in this.buffer_store.read(cx).buffers() {
 4384                            let buffer = handle.read(cx);
 4385                            if buffer.language().is_none()
 4386                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4387                            {
 4388                                plain_text_buffers.push(handle);
 4389                            } else if buffer.contains_unknown_injections() {
 4390                                buffers_with_unknown_injections.push(handle);
 4391                            }
 4392                        }
 4393
 4394                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4395                        // and reused later in the invisible worktrees.
 4396                        plain_text_buffers.sort_by_key(|buffer| {
 4397                            Reverse(
 4398                                File::from_dyn(buffer.read(cx).file())
 4399                                    .map(|file| file.worktree.read(cx).is_visible()),
 4400                            )
 4401                        });
 4402
 4403                        for buffer in plain_text_buffers {
 4404                            this.detect_language_for_buffer(&buffer, cx);
 4405                            if let Some(local) = this.as_local_mut() {
 4406                                local.initialize_buffer(&buffer, cx);
 4407                                if local
 4408                                    .registered_buffers
 4409                                    .contains_key(&buffer.read(cx).remote_id())
 4410                                {
 4411                                    local.register_buffer_with_language_servers(
 4412                                        &buffer,
 4413                                        HashSet::default(),
 4414                                        cx,
 4415                                    );
 4416                                }
 4417                            }
 4418                        }
 4419
 4420                        for buffer in buffers_with_unknown_injections {
 4421                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4422                        }
 4423                    })
 4424                    .ok();
 4425                }
 4426            }
 4427        })
 4428    }
 4429
 4430    fn detect_language_for_buffer(
 4431        &mut self,
 4432        buffer_handle: &Entity<Buffer>,
 4433        cx: &mut Context<Self>,
 4434    ) -> Option<language::AvailableLanguage> {
 4435        // If the buffer has a language, set it and start the language server if we haven't already.
 4436        let buffer = buffer_handle.read(cx);
 4437        let file = buffer.file()?;
 4438
 4439        let content = buffer.as_rope();
 4440        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4441        if let Some(available_language) = &available_language {
 4442            if let Some(Ok(Ok(new_language))) = self
 4443                .languages
 4444                .load_language(available_language)
 4445                .now_or_never()
 4446            {
 4447                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4448            }
 4449        } else {
 4450            cx.emit(LspStoreEvent::LanguageDetected {
 4451                buffer: buffer_handle.clone(),
 4452                new_language: None,
 4453            });
 4454        }
 4455
 4456        available_language
 4457    }
 4458
 4459    pub(crate) fn set_language_for_buffer(
 4460        &mut self,
 4461        buffer_entity: &Entity<Buffer>,
 4462        new_language: Arc<Language>,
 4463        cx: &mut Context<Self>,
 4464    ) {
 4465        let buffer = buffer_entity.read(cx);
 4466        let buffer_file = buffer.file().cloned();
 4467        let buffer_id = buffer.remote_id();
 4468        if let Some(local_store) = self.as_local_mut()
 4469            && local_store.registered_buffers.contains_key(&buffer_id)
 4470            && let Some(abs_path) =
 4471                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4472            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4473        {
 4474            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4475        }
 4476        buffer_entity.update(cx, |buffer, cx| {
 4477            if buffer
 4478                .language()
 4479                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4480            {
 4481                buffer.set_language_async(Some(new_language.clone()), cx);
 4482            }
 4483        });
 4484
 4485        let settings =
 4486            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4487        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4488
 4489        let worktree_id = if let Some(file) = buffer_file {
 4490            let worktree = file.worktree.clone();
 4491
 4492            if let Some(local) = self.as_local_mut()
 4493                && local.registered_buffers.contains_key(&buffer_id)
 4494            {
 4495                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4496            }
 4497            Some(worktree.read(cx).id())
 4498        } else {
 4499            None
 4500        };
 4501
 4502        if settings.prettier.allowed
 4503            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4504        {
 4505            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4506            if let Some(prettier_store) = prettier_store {
 4507                prettier_store.update(cx, |prettier_store, cx| {
 4508                    prettier_store.install_default_prettier(
 4509                        worktree_id,
 4510                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4511                        cx,
 4512                    )
 4513                })
 4514            }
 4515        }
 4516
 4517        cx.emit(LspStoreEvent::LanguageDetected {
 4518            buffer: buffer_entity.clone(),
 4519            new_language: Some(new_language),
 4520        })
 4521    }
 4522
 4523    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4524        self.buffer_store.clone()
 4525    }
 4526
 4527    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4528        self.active_entry = active_entry;
 4529    }
 4530
 4531    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4532        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4533            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4534        {
 4535            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4536                summaries
 4537                    .iter()
 4538                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4539            });
 4540            if let Some(summary) = summaries.next() {
 4541                client
 4542                    .send(proto::UpdateDiagnosticSummary {
 4543                        project_id: downstream_project_id,
 4544                        worktree_id: worktree.id().to_proto(),
 4545                        summary: Some(summary),
 4546                        more_summaries: summaries.collect(),
 4547                    })
 4548                    .log_err();
 4549            }
 4550        }
 4551    }
 4552
 4553    fn is_capable_for_proto_request<R>(
 4554        &self,
 4555        buffer: &Entity<Buffer>,
 4556        request: &R,
 4557        cx: &App,
 4558    ) -> bool
 4559    where
 4560        R: LspCommand,
 4561    {
 4562        self.check_if_capable_for_proto_request(
 4563            buffer,
 4564            |capabilities| {
 4565                request.check_capabilities(AdapterServerCapabilities {
 4566                    server_capabilities: capabilities.clone(),
 4567                    code_action_kinds: None,
 4568                })
 4569            },
 4570            cx,
 4571        )
 4572    }
 4573
 4574    fn check_if_capable_for_proto_request<F>(
 4575        &self,
 4576        buffer: &Entity<Buffer>,
 4577        check: F,
 4578        cx: &App,
 4579    ) -> bool
 4580    where
 4581        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4582    {
 4583        let Some(language) = buffer.read(cx).language().cloned() else {
 4584            return false;
 4585        };
 4586        let relevant_language_servers = self
 4587            .languages
 4588            .lsp_adapters(&language.name())
 4589            .into_iter()
 4590            .map(|lsp_adapter| lsp_adapter.name())
 4591            .collect::<HashSet<_>>();
 4592        self.language_server_statuses
 4593            .iter()
 4594            .filter_map(|(server_id, server_status)| {
 4595                relevant_language_servers
 4596                    .contains(&server_status.name)
 4597                    .then_some(server_id)
 4598            })
 4599            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4600            .any(check)
 4601    }
 4602
 4603    fn all_capable_for_proto_request<F>(
 4604        &self,
 4605        buffer: &Entity<Buffer>,
 4606        mut check: F,
 4607        cx: &App,
 4608    ) -> Vec<lsp::LanguageServerId>
 4609    where
 4610        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4611    {
 4612        let Some(language) = buffer.read(cx).language().cloned() else {
 4613            return Vec::default();
 4614        };
 4615        let relevant_language_servers = self
 4616            .languages
 4617            .lsp_adapters(&language.name())
 4618            .into_iter()
 4619            .map(|lsp_adapter| lsp_adapter.name())
 4620            .collect::<HashSet<_>>();
 4621        self.language_server_statuses
 4622            .iter()
 4623            .filter_map(|(server_id, server_status)| {
 4624                relevant_language_servers
 4625                    .contains(&server_status.name)
 4626                    .then_some((server_id, &server_status.name))
 4627            })
 4628            .filter_map(|(server_id, server_name)| {
 4629                self.lsp_server_capabilities
 4630                    .get(server_id)
 4631                    .map(|c| (server_id, server_name, c))
 4632            })
 4633            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4634            .map(|(server_id, _, _)| *server_id)
 4635            .collect()
 4636    }
 4637
 4638    pub fn request_lsp<R>(
 4639        &mut self,
 4640        buffer: Entity<Buffer>,
 4641        server: LanguageServerToQuery,
 4642        request: R,
 4643        cx: &mut Context<Self>,
 4644    ) -> Task<Result<R::Response>>
 4645    where
 4646        R: LspCommand,
 4647        <R::LspRequest as lsp::request::Request>::Result: Send,
 4648        <R::LspRequest as lsp::request::Request>::Params: Send,
 4649    {
 4650        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4651            return self.send_lsp_proto_request(
 4652                buffer,
 4653                upstream_client,
 4654                upstream_project_id,
 4655                request,
 4656                cx,
 4657            );
 4658        }
 4659
 4660        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4661            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4662                local
 4663                    .language_servers_for_buffer(buffer, cx)
 4664                    .find(|(_, server)| {
 4665                        request.check_capabilities(server.adapter_server_capabilities())
 4666                    })
 4667                    .map(|(_, server)| server.clone())
 4668            }),
 4669            LanguageServerToQuery::Other(id) => self
 4670                .language_server_for_local_buffer(buffer, id, cx)
 4671                .and_then(|(_, server)| {
 4672                    request
 4673                        .check_capabilities(server.adapter_server_capabilities())
 4674                        .then(|| Arc::clone(server))
 4675                }),
 4676        }) else {
 4677            return Task::ready(Ok(Default::default()));
 4678        };
 4679
 4680        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4681
 4682        let Some(file) = file else {
 4683            return Task::ready(Ok(Default::default()));
 4684        };
 4685
 4686        let lsp_params = match request.to_lsp_params_or_response(
 4687            &file.abs_path(cx),
 4688            buffer.read(cx),
 4689            &language_server,
 4690            cx,
 4691        ) {
 4692            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4693            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4694            Err(err) => {
 4695                let message = format!(
 4696                    "{} via {} failed: {}",
 4697                    request.display_name(),
 4698                    language_server.name(),
 4699                    err
 4700                );
 4701                // rust-analyzer likes to error with this when its still loading up
 4702                if !message.ends_with("content modified") {
 4703                    log::warn!("{message}");
 4704                }
 4705                return Task::ready(Err(anyhow!(message)));
 4706            }
 4707        };
 4708
 4709        let status = request.status();
 4710        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4711            return Task::ready(Ok(Default::default()));
 4712        }
 4713        cx.spawn(async move |this, cx| {
 4714            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4715
 4716            let id = lsp_request.id();
 4717            let _cleanup = if status.is_some() {
 4718                cx.update(|cx| {
 4719                    this.update(cx, |this, cx| {
 4720                        this.on_lsp_work_start(
 4721                            language_server.server_id(),
 4722                            ProgressToken::Number(id),
 4723                            LanguageServerProgress {
 4724                                is_disk_based_diagnostics_progress: false,
 4725                                is_cancellable: false,
 4726                                title: None,
 4727                                message: status.clone(),
 4728                                percentage: None,
 4729                                last_update_at: cx.background_executor().now(),
 4730                            },
 4731                            cx,
 4732                        );
 4733                    })
 4734                })
 4735                .log_err();
 4736
 4737                Some(defer(|| {
 4738                    cx.update(|cx| {
 4739                        this.update(cx, |this, cx| {
 4740                            this.on_lsp_work_end(
 4741                                language_server.server_id(),
 4742                                ProgressToken::Number(id),
 4743                                cx,
 4744                            );
 4745                        })
 4746                    })
 4747                    .log_err();
 4748                }))
 4749            } else {
 4750                None
 4751            };
 4752
 4753            let result = lsp_request.await.into_response();
 4754
 4755            let response = result.map_err(|err| {
 4756                let message = format!(
 4757                    "{} via {} failed: {}",
 4758                    request.display_name(),
 4759                    language_server.name(),
 4760                    err
 4761                );
 4762                // rust-analyzer likes to error with this when its still loading up
 4763                if !message.ends_with("content modified") {
 4764                    log::warn!("{message}");
 4765                }
 4766                anyhow::anyhow!(message)
 4767            })?;
 4768
 4769            request
 4770                .response_from_lsp(
 4771                    response,
 4772                    this.upgrade().context("no app context")?,
 4773                    buffer,
 4774                    language_server.server_id(),
 4775                    cx.clone(),
 4776                )
 4777                .await
 4778        })
 4779    }
 4780
 4781    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4782        let mut language_formatters_to_check = Vec::new();
 4783        for buffer in self.buffer_store.read(cx).buffers() {
 4784            let buffer = buffer.read(cx);
 4785            let buffer_file = File::from_dyn(buffer.file());
 4786            let buffer_language = buffer.language();
 4787            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4788            if buffer_language.is_some() {
 4789                language_formatters_to_check.push((
 4790                    buffer_file.map(|f| f.worktree_id(cx)),
 4791                    settings.into_owned(),
 4792                ));
 4793            }
 4794        }
 4795
 4796        self.request_workspace_config_refresh();
 4797
 4798        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4799            prettier_store.update(cx, |prettier_store, cx| {
 4800                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4801            })
 4802        }
 4803
 4804        cx.notify();
 4805    }
 4806
 4807    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4808        let buffer_store = self.buffer_store.clone();
 4809        let Some(local) = self.as_local_mut() else {
 4810            return;
 4811        };
 4812        let mut adapters = BTreeMap::default();
 4813        let get_adapter = {
 4814            let languages = local.languages.clone();
 4815            let environment = local.environment.clone();
 4816            let weak = local.weak.clone();
 4817            let worktree_store = local.worktree_store.clone();
 4818            let http_client = local.http_client.clone();
 4819            let fs = local.fs.clone();
 4820            move |worktree_id, cx: &mut App| {
 4821                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4822                Some(LocalLspAdapterDelegate::new(
 4823                    languages.clone(),
 4824                    &environment,
 4825                    weak.clone(),
 4826                    &worktree,
 4827                    http_client.clone(),
 4828                    fs.clone(),
 4829                    cx,
 4830                ))
 4831            }
 4832        };
 4833
 4834        let mut messages_to_report = Vec::new();
 4835        let (new_tree, to_stop) = {
 4836            let mut rebase = local.lsp_tree.rebase();
 4837            let buffers = buffer_store
 4838                .read(cx)
 4839                .buffers()
 4840                .filter_map(|buffer| {
 4841                    let raw_buffer = buffer.read(cx);
 4842                    if !local
 4843                        .registered_buffers
 4844                        .contains_key(&raw_buffer.remote_id())
 4845                    {
 4846                        return None;
 4847                    }
 4848                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4849                    let language = raw_buffer.language().cloned()?;
 4850                    Some((file, language, raw_buffer.remote_id()))
 4851                })
 4852                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4853            for (file, language, buffer_id) in buffers {
 4854                let worktree_id = file.worktree_id(cx);
 4855                let Some(worktree) = local
 4856                    .worktree_store
 4857                    .read(cx)
 4858                    .worktree_for_id(worktree_id, cx)
 4859                else {
 4860                    continue;
 4861                };
 4862
 4863                if let Some((_, apply)) = local.reuse_existing_language_server(
 4864                    rebase.server_tree(),
 4865                    &worktree,
 4866                    &language.name(),
 4867                    cx,
 4868                ) {
 4869                    (apply)(rebase.server_tree());
 4870                } else if let Some(lsp_delegate) = adapters
 4871                    .entry(worktree_id)
 4872                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4873                    .clone()
 4874                {
 4875                    let delegate =
 4876                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4877                    let path = file
 4878                        .path()
 4879                        .parent()
 4880                        .map(Arc::from)
 4881                        .unwrap_or_else(|| file.path().clone());
 4882                    let worktree_path = ProjectPath { worktree_id, path };
 4883                    let abs_path = file.abs_path(cx);
 4884                    let nodes = rebase
 4885                        .walk(
 4886                            worktree_path,
 4887                            language.name(),
 4888                            language.manifest(),
 4889                            delegate.clone(),
 4890                            cx,
 4891                        )
 4892                        .collect::<Vec<_>>();
 4893                    for node in nodes {
 4894                        let server_id = node.server_id_or_init(|disposition| {
 4895                            let path = &disposition.path;
 4896                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4897                            let key = LanguageServerSeed {
 4898                                worktree_id,
 4899                                name: disposition.server_name.clone(),
 4900                                settings: disposition.settings.clone(),
 4901                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4902                                    path.worktree_id,
 4903                                    &path.path,
 4904                                    language.name(),
 4905                                ),
 4906                            };
 4907                            local.language_server_ids.remove(&key);
 4908
 4909                            let server_id = local.get_or_insert_language_server(
 4910                                &worktree,
 4911                                lsp_delegate.clone(),
 4912                                disposition,
 4913                                &language.name(),
 4914                                cx,
 4915                            );
 4916                            if let Some(state) = local.language_servers.get(&server_id)
 4917                                && let Ok(uri) = uri
 4918                            {
 4919                                state.add_workspace_folder(uri);
 4920                            };
 4921                            server_id
 4922                        });
 4923
 4924                        if let Some(language_server_id) = server_id {
 4925                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4926                                language_server_id,
 4927                                name: node.name(),
 4928                                message:
 4929                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4930                                        proto::RegisteredForBuffer {
 4931                                            buffer_abs_path: abs_path
 4932                                                .to_string_lossy()
 4933                                                .into_owned(),
 4934                                            buffer_id: buffer_id.to_proto(),
 4935                                        },
 4936                                    ),
 4937                            });
 4938                        }
 4939                    }
 4940                } else {
 4941                    continue;
 4942                }
 4943            }
 4944            rebase.finish()
 4945        };
 4946        for message in messages_to_report {
 4947            cx.emit(message);
 4948        }
 4949        local.lsp_tree = new_tree;
 4950        for (id, _) in to_stop {
 4951            self.stop_local_language_server(id, cx).detach();
 4952        }
 4953    }
 4954
 4955    pub fn apply_code_action(
 4956        &self,
 4957        buffer_handle: Entity<Buffer>,
 4958        mut action: CodeAction,
 4959        push_to_history: bool,
 4960        cx: &mut Context<Self>,
 4961    ) -> Task<Result<ProjectTransaction>> {
 4962        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4963            let request = proto::ApplyCodeAction {
 4964                project_id,
 4965                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4966                action: Some(Self::serialize_code_action(&action)),
 4967            };
 4968            let buffer_store = self.buffer_store();
 4969            cx.spawn(async move |_, cx| {
 4970                let response = upstream_client
 4971                    .request(request)
 4972                    .await?
 4973                    .transaction
 4974                    .context("missing transaction")?;
 4975
 4976                buffer_store
 4977                    .update(cx, |buffer_store, cx| {
 4978                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4979                    })?
 4980                    .await
 4981            })
 4982        } else if self.mode.is_local() {
 4983            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4984                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4985                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4986            }) else {
 4987                return Task::ready(Ok(ProjectTransaction::default()));
 4988            };
 4989            cx.spawn(async move |this,  cx| {
 4990                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4991                    .await
 4992                    .context("resolving a code action")?;
 4993                if let Some(edit) = action.lsp_action.edit()
 4994                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4995                        return LocalLspStore::deserialize_workspace_edit(
 4996                            this.upgrade().context("no app present")?,
 4997                            edit.clone(),
 4998                            push_to_history,
 4999
 5000                            lang_server.clone(),
 5001                            cx,
 5002                        )
 5003                        .await;
 5004                    }
 5005
 5006                if let Some(command) = action.lsp_action.command() {
 5007                    let server_capabilities = lang_server.capabilities();
 5008                    let available_commands = server_capabilities
 5009                        .execute_command_provider
 5010                        .as_ref()
 5011                        .map(|options| options.commands.as_slice())
 5012                        .unwrap_or_default();
 5013                    if available_commands.contains(&command.command) {
 5014                        this.update(cx, |this, _| {
 5015                            this.as_local_mut()
 5016                                .unwrap()
 5017                                .last_workspace_edits_by_language_server
 5018                                .remove(&lang_server.server_id());
 5019                        })?;
 5020
 5021                        let _result = lang_server
 5022                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5023                                command: command.command.clone(),
 5024                                arguments: command.arguments.clone().unwrap_or_default(),
 5025                                ..lsp::ExecuteCommandParams::default()
 5026                            })
 5027                            .await.into_response()
 5028                            .context("execute command")?;
 5029
 5030                        return this.update(cx, |this, _| {
 5031                            this.as_local_mut()
 5032                                .unwrap()
 5033                                .last_workspace_edits_by_language_server
 5034                                .remove(&lang_server.server_id())
 5035                                .unwrap_or_default()
 5036                        });
 5037                    } else {
 5038                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5039                    }
 5040                }
 5041
 5042                Ok(ProjectTransaction::default())
 5043            })
 5044        } else {
 5045            Task::ready(Err(anyhow!("no upstream client and not local")))
 5046        }
 5047    }
 5048
 5049    pub fn apply_code_action_kind(
 5050        &mut self,
 5051        buffers: HashSet<Entity<Buffer>>,
 5052        kind: CodeActionKind,
 5053        push_to_history: bool,
 5054        cx: &mut Context<Self>,
 5055    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5056        if self.as_local().is_some() {
 5057            cx.spawn(async move |lsp_store, cx| {
 5058                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5059                let result = LocalLspStore::execute_code_action_kind_locally(
 5060                    lsp_store.clone(),
 5061                    buffers,
 5062                    kind,
 5063                    push_to_history,
 5064                    cx,
 5065                )
 5066                .await;
 5067                lsp_store.update(cx, |lsp_store, _| {
 5068                    lsp_store.update_last_formatting_failure(&result);
 5069                })?;
 5070                result
 5071            })
 5072        } else if let Some((client, project_id)) = self.upstream_client() {
 5073            let buffer_store = self.buffer_store();
 5074            cx.spawn(async move |lsp_store, cx| {
 5075                let result = client
 5076                    .request(proto::ApplyCodeActionKind {
 5077                        project_id,
 5078                        kind: kind.as_str().to_owned(),
 5079                        buffer_ids: buffers
 5080                            .iter()
 5081                            .map(|buffer| {
 5082                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5083                            })
 5084                            .collect::<Result<_>>()?,
 5085                    })
 5086                    .await
 5087                    .and_then(|result| result.transaction.context("missing transaction"));
 5088                lsp_store.update(cx, |lsp_store, _| {
 5089                    lsp_store.update_last_formatting_failure(&result);
 5090                })?;
 5091
 5092                let transaction_response = result?;
 5093                buffer_store
 5094                    .update(cx, |buffer_store, cx| {
 5095                        buffer_store.deserialize_project_transaction(
 5096                            transaction_response,
 5097                            push_to_history,
 5098                            cx,
 5099                        )
 5100                    })?
 5101                    .await
 5102            })
 5103        } else {
 5104            Task::ready(Ok(ProjectTransaction::default()))
 5105        }
 5106    }
 5107
 5108    pub fn resolved_hint(
 5109        &mut self,
 5110        buffer_id: BufferId,
 5111        id: InlayId,
 5112        cx: &mut Context<Self>,
 5113    ) -> Option<ResolvedHint> {
 5114        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5115
 5116        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5117        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5118        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5119        let (server_id, resolve_data) = match &hint.resolve_state {
 5120            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5121            ResolveState::Resolving => {
 5122                return Some(ResolvedHint::Resolving(
 5123                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5124                ));
 5125            }
 5126            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5127        };
 5128
 5129        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5130        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5131        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5132            id,
 5133            cx.spawn(async move |lsp_store, cx| {
 5134                let resolved_hint = resolve_task.await;
 5135                lsp_store
 5136                    .update(cx, |lsp_store, _| {
 5137                        if let Some(old_inlay_hint) = lsp_store
 5138                            .lsp_data
 5139                            .get_mut(&buffer_id)
 5140                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5141                        {
 5142                            match resolved_hint {
 5143                                Ok(resolved_hint) => {
 5144                                    *old_inlay_hint = resolved_hint;
 5145                                }
 5146                                Err(e) => {
 5147                                    old_inlay_hint.resolve_state =
 5148                                        ResolveState::CanResolve(server_id, resolve_data);
 5149                                    log::error!("Inlay hint resolve failed: {e:#}");
 5150                                }
 5151                            }
 5152                        }
 5153                    })
 5154                    .ok();
 5155            })
 5156            .shared(),
 5157        );
 5158        debug_assert!(
 5159            previous_task.is_none(),
 5160            "Did not change hint's resolve state after spawning its resolve"
 5161        );
 5162        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5163        None
 5164    }
 5165
 5166    fn resolve_inlay_hint(
 5167        &self,
 5168        mut hint: InlayHint,
 5169        buffer: Entity<Buffer>,
 5170        server_id: LanguageServerId,
 5171        cx: &mut Context<Self>,
 5172    ) -> Task<anyhow::Result<InlayHint>> {
 5173        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5174            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5175            {
 5176                hint.resolve_state = ResolveState::Resolved;
 5177                return Task::ready(Ok(hint));
 5178            }
 5179            let request = proto::ResolveInlayHint {
 5180                project_id,
 5181                buffer_id: buffer.read(cx).remote_id().into(),
 5182                language_server_id: server_id.0 as u64,
 5183                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5184            };
 5185            cx.background_spawn(async move {
 5186                let response = upstream_client
 5187                    .request(request)
 5188                    .await
 5189                    .context("inlay hints proto request")?;
 5190                match response.hint {
 5191                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5192                        .context("inlay hints proto resolve response conversion"),
 5193                    None => Ok(hint),
 5194                }
 5195            })
 5196        } else {
 5197            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5198                self.language_server_for_local_buffer(buffer, server_id, cx)
 5199                    .map(|(_, server)| server.clone())
 5200            }) else {
 5201                return Task::ready(Ok(hint));
 5202            };
 5203            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5204                return Task::ready(Ok(hint));
 5205            }
 5206            let buffer_snapshot = buffer.read(cx).snapshot();
 5207            cx.spawn(async move |_, cx| {
 5208                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5209                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5210                );
 5211                let resolved_hint = resolve_task
 5212                    .await
 5213                    .into_response()
 5214                    .context("inlay hint resolve LSP request")?;
 5215                let resolved_hint = InlayHints::lsp_to_project_hint(
 5216                    resolved_hint,
 5217                    &buffer,
 5218                    server_id,
 5219                    ResolveState::Resolved,
 5220                    false,
 5221                    cx,
 5222                )
 5223                .await?;
 5224                Ok(resolved_hint)
 5225            })
 5226        }
 5227    }
 5228
 5229    pub fn resolve_color_presentation(
 5230        &mut self,
 5231        mut color: DocumentColor,
 5232        buffer: Entity<Buffer>,
 5233        server_id: LanguageServerId,
 5234        cx: &mut Context<Self>,
 5235    ) -> Task<Result<DocumentColor>> {
 5236        if color.resolved {
 5237            return Task::ready(Ok(color));
 5238        }
 5239
 5240        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5241            let start = color.lsp_range.start;
 5242            let end = color.lsp_range.end;
 5243            let request = proto::GetColorPresentation {
 5244                project_id,
 5245                server_id: server_id.to_proto(),
 5246                buffer_id: buffer.read(cx).remote_id().into(),
 5247                color: Some(proto::ColorInformation {
 5248                    red: color.color.red,
 5249                    green: color.color.green,
 5250                    blue: color.color.blue,
 5251                    alpha: color.color.alpha,
 5252                    lsp_range_start: Some(proto::PointUtf16 {
 5253                        row: start.line,
 5254                        column: start.character,
 5255                    }),
 5256                    lsp_range_end: Some(proto::PointUtf16 {
 5257                        row: end.line,
 5258                        column: end.character,
 5259                    }),
 5260                }),
 5261            };
 5262            cx.background_spawn(async move {
 5263                let response = upstream_client
 5264                    .request(request)
 5265                    .await
 5266                    .context("color presentation proto request")?;
 5267                color.resolved = true;
 5268                color.color_presentations = response
 5269                    .presentations
 5270                    .into_iter()
 5271                    .map(|presentation| ColorPresentation {
 5272                        label: SharedString::from(presentation.label),
 5273                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5274                        additional_text_edits: presentation
 5275                            .additional_text_edits
 5276                            .into_iter()
 5277                            .filter_map(deserialize_lsp_edit)
 5278                            .collect(),
 5279                    })
 5280                    .collect();
 5281                Ok(color)
 5282            })
 5283        } else {
 5284            let path = match buffer
 5285                .update(cx, |buffer, cx| {
 5286                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5287                })
 5288                .context("buffer with the missing path")
 5289            {
 5290                Ok(path) => path,
 5291                Err(e) => return Task::ready(Err(e)),
 5292            };
 5293            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5294                self.language_server_for_local_buffer(buffer, server_id, cx)
 5295                    .map(|(_, server)| server.clone())
 5296            }) else {
 5297                return Task::ready(Ok(color));
 5298            };
 5299            cx.background_spawn(async move {
 5300                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5301                    lsp::ColorPresentationParams {
 5302                        text_document: make_text_document_identifier(&path)?,
 5303                        color: color.color,
 5304                        range: color.lsp_range,
 5305                        work_done_progress_params: Default::default(),
 5306                        partial_result_params: Default::default(),
 5307                    },
 5308                );
 5309                color.color_presentations = resolve_task
 5310                    .await
 5311                    .into_response()
 5312                    .context("color presentation resolve LSP request")?
 5313                    .into_iter()
 5314                    .map(|presentation| ColorPresentation {
 5315                        label: SharedString::from(presentation.label),
 5316                        text_edit: presentation.text_edit,
 5317                        additional_text_edits: presentation
 5318                            .additional_text_edits
 5319                            .unwrap_or_default(),
 5320                    })
 5321                    .collect();
 5322                color.resolved = true;
 5323                Ok(color)
 5324            })
 5325        }
 5326    }
 5327
 5328    pub(crate) fn linked_edits(
 5329        &mut self,
 5330        buffer: &Entity<Buffer>,
 5331        position: Anchor,
 5332        cx: &mut Context<Self>,
 5333    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5334        let snapshot = buffer.read(cx).snapshot();
 5335        let scope = snapshot.language_scope_at(position);
 5336        let Some(server_id) = self
 5337            .as_local()
 5338            .and_then(|local| {
 5339                buffer.update(cx, |buffer, cx| {
 5340                    local
 5341                        .language_servers_for_buffer(buffer, cx)
 5342                        .filter(|(_, server)| {
 5343                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5344                        })
 5345                        .filter(|(adapter, _)| {
 5346                            scope
 5347                                .as_ref()
 5348                                .map(|scope| scope.language_allowed(&adapter.name))
 5349                                .unwrap_or(true)
 5350                        })
 5351                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5352                        .next()
 5353                })
 5354            })
 5355            .or_else(|| {
 5356                self.upstream_client()
 5357                    .is_some()
 5358                    .then_some(LanguageServerToQuery::FirstCapable)
 5359            })
 5360            .filter(|_| {
 5361                maybe!({
 5362                    let language = buffer.read(cx).language_at(position)?;
 5363                    Some(
 5364                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5365                            .linked_edits,
 5366                    )
 5367                }) == Some(true)
 5368            })
 5369        else {
 5370            return Task::ready(Ok(Vec::new()));
 5371        };
 5372
 5373        self.request_lsp(
 5374            buffer.clone(),
 5375            server_id,
 5376            LinkedEditingRange { position },
 5377            cx,
 5378        )
 5379    }
 5380
 5381    fn apply_on_type_formatting(
 5382        &mut self,
 5383        buffer: Entity<Buffer>,
 5384        position: Anchor,
 5385        trigger: String,
 5386        cx: &mut Context<Self>,
 5387    ) -> Task<Result<Option<Transaction>>> {
 5388        if let Some((client, project_id)) = self.upstream_client() {
 5389            if !self.check_if_capable_for_proto_request(
 5390                &buffer,
 5391                |capabilities| {
 5392                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5393                },
 5394                cx,
 5395            ) {
 5396                return Task::ready(Ok(None));
 5397            }
 5398            let request = proto::OnTypeFormatting {
 5399                project_id,
 5400                buffer_id: buffer.read(cx).remote_id().into(),
 5401                position: Some(serialize_anchor(&position)),
 5402                trigger,
 5403                version: serialize_version(&buffer.read(cx).version()),
 5404            };
 5405            cx.background_spawn(async move {
 5406                client
 5407                    .request(request)
 5408                    .await?
 5409                    .transaction
 5410                    .map(language::proto::deserialize_transaction)
 5411                    .transpose()
 5412            })
 5413        } else if let Some(local) = self.as_local_mut() {
 5414            let buffer_id = buffer.read(cx).remote_id();
 5415            local.buffers_being_formatted.insert(buffer_id);
 5416            cx.spawn(async move |this, cx| {
 5417                let _cleanup = defer({
 5418                    let this = this.clone();
 5419                    let mut cx = cx.clone();
 5420                    move || {
 5421                        this.update(&mut cx, |this, _| {
 5422                            if let Some(local) = this.as_local_mut() {
 5423                                local.buffers_being_formatted.remove(&buffer_id);
 5424                            }
 5425                        })
 5426                        .ok();
 5427                    }
 5428                });
 5429
 5430                buffer
 5431                    .update(cx, |buffer, _| {
 5432                        buffer.wait_for_edits(Some(position.timestamp))
 5433                    })?
 5434                    .await?;
 5435                this.update(cx, |this, cx| {
 5436                    let position = position.to_point_utf16(buffer.read(cx));
 5437                    this.on_type_format(buffer, position, trigger, false, cx)
 5438                })?
 5439                .await
 5440            })
 5441        } else {
 5442            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5443        }
 5444    }
 5445
 5446    pub fn on_type_format<T: ToPointUtf16>(
 5447        &mut self,
 5448        buffer: Entity<Buffer>,
 5449        position: T,
 5450        trigger: String,
 5451        push_to_history: bool,
 5452        cx: &mut Context<Self>,
 5453    ) -> Task<Result<Option<Transaction>>> {
 5454        let position = position.to_point_utf16(buffer.read(cx));
 5455        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5456    }
 5457
 5458    fn on_type_format_impl(
 5459        &mut self,
 5460        buffer: Entity<Buffer>,
 5461        position: PointUtf16,
 5462        trigger: String,
 5463        push_to_history: bool,
 5464        cx: &mut Context<Self>,
 5465    ) -> Task<Result<Option<Transaction>>> {
 5466        let options = buffer.update(cx, |buffer, cx| {
 5467            lsp_command::lsp_formatting_options(
 5468                language_settings(
 5469                    buffer.language_at(position).map(|l| l.name()),
 5470                    buffer.file(),
 5471                    cx,
 5472                )
 5473                .as_ref(),
 5474            )
 5475        });
 5476
 5477        cx.spawn(async move |this, cx| {
 5478            if let Some(waiter) =
 5479                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5480            {
 5481                waiter.await?;
 5482            }
 5483            cx.update(|cx| {
 5484                this.update(cx, |this, cx| {
 5485                    this.request_lsp(
 5486                        buffer.clone(),
 5487                        LanguageServerToQuery::FirstCapable,
 5488                        OnTypeFormatting {
 5489                            position,
 5490                            trigger,
 5491                            options,
 5492                            push_to_history,
 5493                        },
 5494                        cx,
 5495                    )
 5496                })
 5497            })??
 5498            .await
 5499        })
 5500    }
 5501
 5502    pub fn definitions(
 5503        &mut self,
 5504        buffer: &Entity<Buffer>,
 5505        position: PointUtf16,
 5506        cx: &mut Context<Self>,
 5507    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5508        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5509            let request = GetDefinitions { position };
 5510            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5511                return Task::ready(Ok(None));
 5512            }
 5513            let request_task = upstream_client.request_lsp(
 5514                project_id,
 5515                None,
 5516                LSP_REQUEST_TIMEOUT,
 5517                cx.background_executor().clone(),
 5518                request.to_proto(project_id, buffer.read(cx)),
 5519            );
 5520            let buffer = buffer.clone();
 5521            cx.spawn(async move |weak_lsp_store, cx| {
 5522                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5523                    return Ok(None);
 5524                };
 5525                let Some(responses) = request_task.await? else {
 5526                    return Ok(None);
 5527                };
 5528                let actions = join_all(responses.payload.into_iter().map(|response| {
 5529                    GetDefinitions { position }.response_from_proto(
 5530                        response.response,
 5531                        lsp_store.clone(),
 5532                        buffer.clone(),
 5533                        cx.clone(),
 5534                    )
 5535                }))
 5536                .await;
 5537
 5538                Ok(Some(
 5539                    actions
 5540                        .into_iter()
 5541                        .collect::<Result<Vec<Vec<_>>>>()?
 5542                        .into_iter()
 5543                        .flatten()
 5544                        .dedup()
 5545                        .collect(),
 5546                ))
 5547            })
 5548        } else {
 5549            let definitions_task = self.request_multiple_lsp_locally(
 5550                buffer,
 5551                Some(position),
 5552                GetDefinitions { position },
 5553                cx,
 5554            );
 5555            cx.background_spawn(async move {
 5556                Ok(Some(
 5557                    definitions_task
 5558                        .await
 5559                        .into_iter()
 5560                        .flat_map(|(_, definitions)| definitions)
 5561                        .dedup()
 5562                        .collect(),
 5563                ))
 5564            })
 5565        }
 5566    }
 5567
 5568    pub fn declarations(
 5569        &mut self,
 5570        buffer: &Entity<Buffer>,
 5571        position: PointUtf16,
 5572        cx: &mut Context<Self>,
 5573    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5574        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5575            let request = GetDeclarations { position };
 5576            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5577                return Task::ready(Ok(None));
 5578            }
 5579            let request_task = upstream_client.request_lsp(
 5580                project_id,
 5581                None,
 5582                LSP_REQUEST_TIMEOUT,
 5583                cx.background_executor().clone(),
 5584                request.to_proto(project_id, buffer.read(cx)),
 5585            );
 5586            let buffer = buffer.clone();
 5587            cx.spawn(async move |weak_lsp_store, cx| {
 5588                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5589                    return Ok(None);
 5590                };
 5591                let Some(responses) = request_task.await? else {
 5592                    return Ok(None);
 5593                };
 5594                let actions = join_all(responses.payload.into_iter().map(|response| {
 5595                    GetDeclarations { position }.response_from_proto(
 5596                        response.response,
 5597                        lsp_store.clone(),
 5598                        buffer.clone(),
 5599                        cx.clone(),
 5600                    )
 5601                }))
 5602                .await;
 5603
 5604                Ok(Some(
 5605                    actions
 5606                        .into_iter()
 5607                        .collect::<Result<Vec<Vec<_>>>>()?
 5608                        .into_iter()
 5609                        .flatten()
 5610                        .dedup()
 5611                        .collect(),
 5612                ))
 5613            })
 5614        } else {
 5615            let declarations_task = self.request_multiple_lsp_locally(
 5616                buffer,
 5617                Some(position),
 5618                GetDeclarations { position },
 5619                cx,
 5620            );
 5621            cx.background_spawn(async move {
 5622                Ok(Some(
 5623                    declarations_task
 5624                        .await
 5625                        .into_iter()
 5626                        .flat_map(|(_, declarations)| declarations)
 5627                        .dedup()
 5628                        .collect(),
 5629                ))
 5630            })
 5631        }
 5632    }
 5633
 5634    pub fn type_definitions(
 5635        &mut self,
 5636        buffer: &Entity<Buffer>,
 5637        position: PointUtf16,
 5638        cx: &mut Context<Self>,
 5639    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5640        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5641            let request = GetTypeDefinitions { position };
 5642            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5643                return Task::ready(Ok(None));
 5644            }
 5645            let request_task = upstream_client.request_lsp(
 5646                project_id,
 5647                None,
 5648                LSP_REQUEST_TIMEOUT,
 5649                cx.background_executor().clone(),
 5650                request.to_proto(project_id, buffer.read(cx)),
 5651            );
 5652            let buffer = buffer.clone();
 5653            cx.spawn(async move |weak_lsp_store, cx| {
 5654                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5655                    return Ok(None);
 5656                };
 5657                let Some(responses) = request_task.await? else {
 5658                    return Ok(None);
 5659                };
 5660                let actions = join_all(responses.payload.into_iter().map(|response| {
 5661                    GetTypeDefinitions { position }.response_from_proto(
 5662                        response.response,
 5663                        lsp_store.clone(),
 5664                        buffer.clone(),
 5665                        cx.clone(),
 5666                    )
 5667                }))
 5668                .await;
 5669
 5670                Ok(Some(
 5671                    actions
 5672                        .into_iter()
 5673                        .collect::<Result<Vec<Vec<_>>>>()?
 5674                        .into_iter()
 5675                        .flatten()
 5676                        .dedup()
 5677                        .collect(),
 5678                ))
 5679            })
 5680        } else {
 5681            let type_definitions_task = self.request_multiple_lsp_locally(
 5682                buffer,
 5683                Some(position),
 5684                GetTypeDefinitions { position },
 5685                cx,
 5686            );
 5687            cx.background_spawn(async move {
 5688                Ok(Some(
 5689                    type_definitions_task
 5690                        .await
 5691                        .into_iter()
 5692                        .flat_map(|(_, type_definitions)| type_definitions)
 5693                        .dedup()
 5694                        .collect(),
 5695                ))
 5696            })
 5697        }
 5698    }
 5699
 5700    pub fn implementations(
 5701        &mut self,
 5702        buffer: &Entity<Buffer>,
 5703        position: PointUtf16,
 5704        cx: &mut Context<Self>,
 5705    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5706        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5707            let request = GetImplementations { position };
 5708            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5709                return Task::ready(Ok(None));
 5710            }
 5711            let request_task = upstream_client.request_lsp(
 5712                project_id,
 5713                None,
 5714                LSP_REQUEST_TIMEOUT,
 5715                cx.background_executor().clone(),
 5716                request.to_proto(project_id, buffer.read(cx)),
 5717            );
 5718            let buffer = buffer.clone();
 5719            cx.spawn(async move |weak_lsp_store, cx| {
 5720                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5721                    return Ok(None);
 5722                };
 5723                let Some(responses) = request_task.await? else {
 5724                    return Ok(None);
 5725                };
 5726                let actions = join_all(responses.payload.into_iter().map(|response| {
 5727                    GetImplementations { position }.response_from_proto(
 5728                        response.response,
 5729                        lsp_store.clone(),
 5730                        buffer.clone(),
 5731                        cx.clone(),
 5732                    )
 5733                }))
 5734                .await;
 5735
 5736                Ok(Some(
 5737                    actions
 5738                        .into_iter()
 5739                        .collect::<Result<Vec<Vec<_>>>>()?
 5740                        .into_iter()
 5741                        .flatten()
 5742                        .dedup()
 5743                        .collect(),
 5744                ))
 5745            })
 5746        } else {
 5747            let implementations_task = self.request_multiple_lsp_locally(
 5748                buffer,
 5749                Some(position),
 5750                GetImplementations { position },
 5751                cx,
 5752            );
 5753            cx.background_spawn(async move {
 5754                Ok(Some(
 5755                    implementations_task
 5756                        .await
 5757                        .into_iter()
 5758                        .flat_map(|(_, implementations)| implementations)
 5759                        .dedup()
 5760                        .collect(),
 5761                ))
 5762            })
 5763        }
 5764    }
 5765
 5766    pub fn references(
 5767        &mut self,
 5768        buffer: &Entity<Buffer>,
 5769        position: PointUtf16,
 5770        cx: &mut Context<Self>,
 5771    ) -> Task<Result<Option<Vec<Location>>>> {
 5772        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5773            let request = GetReferences { position };
 5774            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5775                return Task::ready(Ok(None));
 5776            }
 5777
 5778            let request_task = upstream_client.request_lsp(
 5779                project_id,
 5780                None,
 5781                LSP_REQUEST_TIMEOUT,
 5782                cx.background_executor().clone(),
 5783                request.to_proto(project_id, buffer.read(cx)),
 5784            );
 5785            let buffer = buffer.clone();
 5786            cx.spawn(async move |weak_lsp_store, cx| {
 5787                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5788                    return Ok(None);
 5789                };
 5790                let Some(responses) = request_task.await? else {
 5791                    return Ok(None);
 5792                };
 5793
 5794                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5795                    GetReferences { position }.response_from_proto(
 5796                        lsp_response.response,
 5797                        lsp_store.clone(),
 5798                        buffer.clone(),
 5799                        cx.clone(),
 5800                    )
 5801                }))
 5802                .await
 5803                .into_iter()
 5804                .collect::<Result<Vec<Vec<_>>>>()?
 5805                .into_iter()
 5806                .flatten()
 5807                .dedup()
 5808                .collect();
 5809                Ok(Some(locations))
 5810            })
 5811        } else {
 5812            let references_task = self.request_multiple_lsp_locally(
 5813                buffer,
 5814                Some(position),
 5815                GetReferences { position },
 5816                cx,
 5817            );
 5818            cx.background_spawn(async move {
 5819                Ok(Some(
 5820                    references_task
 5821                        .await
 5822                        .into_iter()
 5823                        .flat_map(|(_, references)| references)
 5824                        .dedup()
 5825                        .collect(),
 5826                ))
 5827            })
 5828        }
 5829    }
 5830
 5831    pub fn code_actions(
 5832        &mut self,
 5833        buffer: &Entity<Buffer>,
 5834        range: Range<Anchor>,
 5835        kinds: Option<Vec<CodeActionKind>>,
 5836        cx: &mut Context<Self>,
 5837    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5838        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5839            let request = GetCodeActions {
 5840                range: range.clone(),
 5841                kinds: kinds.clone(),
 5842            };
 5843            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5844                return Task::ready(Ok(None));
 5845            }
 5846            let request_task = upstream_client.request_lsp(
 5847                project_id,
 5848                None,
 5849                LSP_REQUEST_TIMEOUT,
 5850                cx.background_executor().clone(),
 5851                request.to_proto(project_id, buffer.read(cx)),
 5852            );
 5853            let buffer = buffer.clone();
 5854            cx.spawn(async move |weak_lsp_store, cx| {
 5855                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5856                    return Ok(None);
 5857                };
 5858                let Some(responses) = request_task.await? else {
 5859                    return Ok(None);
 5860                };
 5861                let actions = join_all(responses.payload.into_iter().map(|response| {
 5862                    GetCodeActions {
 5863                        range: range.clone(),
 5864                        kinds: kinds.clone(),
 5865                    }
 5866                    .response_from_proto(
 5867                        response.response,
 5868                        lsp_store.clone(),
 5869                        buffer.clone(),
 5870                        cx.clone(),
 5871                    )
 5872                }))
 5873                .await;
 5874
 5875                Ok(Some(
 5876                    actions
 5877                        .into_iter()
 5878                        .collect::<Result<Vec<Vec<_>>>>()?
 5879                        .into_iter()
 5880                        .flatten()
 5881                        .collect(),
 5882                ))
 5883            })
 5884        } else {
 5885            let all_actions_task = self.request_multiple_lsp_locally(
 5886                buffer,
 5887                Some(range.start),
 5888                GetCodeActions { range, kinds },
 5889                cx,
 5890            );
 5891            cx.background_spawn(async move {
 5892                Ok(Some(
 5893                    all_actions_task
 5894                        .await
 5895                        .into_iter()
 5896                        .flat_map(|(_, actions)| actions)
 5897                        .collect(),
 5898                ))
 5899            })
 5900        }
 5901    }
 5902
 5903    pub fn code_lens_actions(
 5904        &mut self,
 5905        buffer: &Entity<Buffer>,
 5906        cx: &mut Context<Self>,
 5907    ) -> CodeLensTask {
 5908        let version_queried_for = buffer.read(cx).version();
 5909        let buffer_id = buffer.read(cx).remote_id();
 5910        let existing_servers = self.as_local().map(|local| {
 5911            local
 5912                .buffers_opened_in_servers
 5913                .get(&buffer_id)
 5914                .cloned()
 5915                .unwrap_or_default()
 5916        });
 5917
 5918        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5919            if let Some(cached_lens) = &lsp_data.code_lens {
 5920                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5921                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5922                        existing_servers != cached_lens.lens.keys().copied().collect()
 5923                    });
 5924                    if !has_different_servers {
 5925                        return Task::ready(Ok(Some(
 5926                            cached_lens.lens.values().flatten().cloned().collect(),
 5927                        )))
 5928                        .shared();
 5929                    }
 5930                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5931                    if !version_queried_for.changed_since(updating_for) {
 5932                        return running_update.clone();
 5933                    }
 5934                }
 5935            }
 5936        }
 5937
 5938        let lens_lsp_data = self
 5939            .latest_lsp_data(buffer, cx)
 5940            .code_lens
 5941            .get_or_insert_default();
 5942        let buffer = buffer.clone();
 5943        let query_version_queried_for = version_queried_for.clone();
 5944        let new_task = cx
 5945            .spawn(async move |lsp_store, cx| {
 5946                cx.background_executor()
 5947                    .timer(Duration::from_millis(30))
 5948                    .await;
 5949                let fetched_lens = lsp_store
 5950                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5951                    .map_err(Arc::new)?
 5952                    .await
 5953                    .context("fetching code lens")
 5954                    .map_err(Arc::new);
 5955                let fetched_lens = match fetched_lens {
 5956                    Ok(fetched_lens) => fetched_lens,
 5957                    Err(e) => {
 5958                        lsp_store
 5959                            .update(cx, |lsp_store, _| {
 5960                                if let Some(lens_lsp_data) = lsp_store
 5961                                    .lsp_data
 5962                                    .get_mut(&buffer_id)
 5963                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5964                                {
 5965                                    lens_lsp_data.update = None;
 5966                                }
 5967                            })
 5968                            .ok();
 5969                        return Err(e);
 5970                    }
 5971                };
 5972
 5973                lsp_store
 5974                    .update(cx, |lsp_store, _| {
 5975                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5976                        let code_lens = lsp_data.code_lens.as_mut()?;
 5977                        if let Some(fetched_lens) = fetched_lens {
 5978                            if lsp_data.buffer_version == query_version_queried_for {
 5979                                code_lens.lens.extend(fetched_lens);
 5980                            } else if !lsp_data
 5981                                .buffer_version
 5982                                .changed_since(&query_version_queried_for)
 5983                            {
 5984                                lsp_data.buffer_version = query_version_queried_for;
 5985                                code_lens.lens = fetched_lens;
 5986                            }
 5987                        }
 5988                        code_lens.update = None;
 5989                        Some(code_lens.lens.values().flatten().cloned().collect())
 5990                    })
 5991                    .map_err(Arc::new)
 5992            })
 5993            .shared();
 5994        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5995        new_task
 5996    }
 5997
 5998    fn fetch_code_lens(
 5999        &mut self,
 6000        buffer: &Entity<Buffer>,
 6001        cx: &mut Context<Self>,
 6002    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6003        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6004            let request = GetCodeLens;
 6005            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6006                return Task::ready(Ok(None));
 6007            }
 6008            let request_task = upstream_client.request_lsp(
 6009                project_id,
 6010                None,
 6011                LSP_REQUEST_TIMEOUT,
 6012                cx.background_executor().clone(),
 6013                request.to_proto(project_id, buffer.read(cx)),
 6014            );
 6015            let buffer = buffer.clone();
 6016            cx.spawn(async move |weak_lsp_store, cx| {
 6017                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6018                    return Ok(None);
 6019                };
 6020                let Some(responses) = request_task.await? else {
 6021                    return Ok(None);
 6022                };
 6023
 6024                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6025                    let lsp_store = lsp_store.clone();
 6026                    let buffer = buffer.clone();
 6027                    let cx = cx.clone();
 6028                    async move {
 6029                        (
 6030                            LanguageServerId::from_proto(response.server_id),
 6031                            GetCodeLens
 6032                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6033                                .await,
 6034                        )
 6035                    }
 6036                }))
 6037                .await;
 6038
 6039                let mut has_errors = false;
 6040                let code_lens_actions = code_lens_actions
 6041                    .into_iter()
 6042                    .filter_map(|(server_id, code_lens)| match code_lens {
 6043                        Ok(code_lens) => Some((server_id, code_lens)),
 6044                        Err(e) => {
 6045                            has_errors = true;
 6046                            log::error!("{e:#}");
 6047                            None
 6048                        }
 6049                    })
 6050                    .collect::<HashMap<_, _>>();
 6051                anyhow::ensure!(
 6052                    !has_errors || !code_lens_actions.is_empty(),
 6053                    "Failed to fetch code lens"
 6054                );
 6055                Ok(Some(code_lens_actions))
 6056            })
 6057        } else {
 6058            let code_lens_actions_task =
 6059                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6060            cx.background_spawn(async move {
 6061                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6062            })
 6063        }
 6064    }
 6065
 6066    #[inline(never)]
 6067    pub fn completions(
 6068        &self,
 6069        buffer: &Entity<Buffer>,
 6070        position: PointUtf16,
 6071        context: CompletionContext,
 6072        cx: &mut Context<Self>,
 6073    ) -> Task<Result<Vec<CompletionResponse>>> {
 6074        let language_registry = self.languages.clone();
 6075
 6076        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6077            let snapshot = buffer.read(cx).snapshot();
 6078            let offset = position.to_offset(&snapshot);
 6079            let scope = snapshot.language_scope_at(offset);
 6080            let capable_lsps = self.all_capable_for_proto_request(
 6081                buffer,
 6082                |server_name, capabilities| {
 6083                    capabilities.completion_provider.is_some()
 6084                        && scope
 6085                            .as_ref()
 6086                            .map(|scope| scope.language_allowed(server_name))
 6087                            .unwrap_or(true)
 6088                },
 6089                cx,
 6090            );
 6091            if capable_lsps.is_empty() {
 6092                return Task::ready(Ok(Vec::new()));
 6093            }
 6094
 6095            let language = buffer.read(cx).language().cloned();
 6096
 6097            // In the future, we should provide project guests with the names of LSP adapters,
 6098            // so that they can use the correct LSP adapter when computing labels. For now,
 6099            // guests just use the first LSP adapter associated with the buffer's language.
 6100            let lsp_adapter = language.as_ref().and_then(|language| {
 6101                language_registry
 6102                    .lsp_adapters(&language.name())
 6103                    .first()
 6104                    .cloned()
 6105            });
 6106
 6107            let buffer = buffer.clone();
 6108
 6109            cx.spawn(async move |this, cx| {
 6110                let requests = join_all(
 6111                    capable_lsps
 6112                        .into_iter()
 6113                        .map(|id| {
 6114                            let request = GetCompletions {
 6115                                position,
 6116                                context: context.clone(),
 6117                                server_id: Some(id),
 6118                            };
 6119                            let buffer = buffer.clone();
 6120                            let language = language.clone();
 6121                            let lsp_adapter = lsp_adapter.clone();
 6122                            let upstream_client = upstream_client.clone();
 6123                            let response = this
 6124                                .update(cx, |this, cx| {
 6125                                    this.send_lsp_proto_request(
 6126                                        buffer,
 6127                                        upstream_client,
 6128                                        project_id,
 6129                                        request,
 6130                                        cx,
 6131                                    )
 6132                                })
 6133                                .log_err();
 6134                            async move {
 6135                                let response = response?.await.log_err()?;
 6136
 6137                                let completions = populate_labels_for_completions(
 6138                                    response.completions,
 6139                                    language,
 6140                                    lsp_adapter,
 6141                                )
 6142                                .await;
 6143
 6144                                Some(CompletionResponse {
 6145                                    completions,
 6146                                    display_options: CompletionDisplayOptions::default(),
 6147                                    is_incomplete: response.is_incomplete,
 6148                                })
 6149                            }
 6150                        })
 6151                        .collect::<Vec<_>>(),
 6152                );
 6153                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6154            })
 6155        } else if let Some(local) = self.as_local() {
 6156            let snapshot = buffer.read(cx).snapshot();
 6157            let offset = position.to_offset(&snapshot);
 6158            let scope = snapshot.language_scope_at(offset);
 6159            let language = snapshot.language().cloned();
 6160            let completion_settings = language_settings(
 6161                language.as_ref().map(|language| language.name()),
 6162                buffer.read(cx).file(),
 6163                cx,
 6164            )
 6165            .completions
 6166            .clone();
 6167            if !completion_settings.lsp {
 6168                return Task::ready(Ok(Vec::new()));
 6169            }
 6170
 6171            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6172                local
 6173                    .language_servers_for_buffer(buffer, cx)
 6174                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6175                    .filter(|(adapter, _)| {
 6176                        scope
 6177                            .as_ref()
 6178                            .map(|scope| scope.language_allowed(&adapter.name))
 6179                            .unwrap_or(true)
 6180                    })
 6181                    .map(|(_, server)| server.server_id())
 6182                    .collect()
 6183            });
 6184
 6185            let buffer = buffer.clone();
 6186            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6187            let lsp_timeout = if lsp_timeout > 0 {
 6188                Some(Duration::from_millis(lsp_timeout))
 6189            } else {
 6190                None
 6191            };
 6192            cx.spawn(async move |this,  cx| {
 6193                let mut tasks = Vec::with_capacity(server_ids.len());
 6194                this.update(cx, |lsp_store, cx| {
 6195                    for server_id in server_ids {
 6196                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6197                        let lsp_timeout = lsp_timeout
 6198                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6199                        let mut timeout = cx.background_spawn(async move {
 6200                            match lsp_timeout {
 6201                                Some(lsp_timeout) => {
 6202                                    lsp_timeout.await;
 6203                                    true
 6204                                },
 6205                                None => false,
 6206                            }
 6207                        }).fuse();
 6208                        let mut lsp_request = lsp_store.request_lsp(
 6209                            buffer.clone(),
 6210                            LanguageServerToQuery::Other(server_id),
 6211                            GetCompletions {
 6212                                position,
 6213                                context: context.clone(),
 6214                                server_id: Some(server_id),
 6215                            },
 6216                            cx,
 6217                        ).fuse();
 6218                        let new_task = cx.background_spawn(async move {
 6219                            select_biased! {
 6220                                response = lsp_request => anyhow::Ok(Some(response?)),
 6221                                timeout_happened = timeout => {
 6222                                    if timeout_happened {
 6223                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6224                                        Ok(None)
 6225                                    } else {
 6226                                        let completions = lsp_request.await?;
 6227                                        Ok(Some(completions))
 6228                                    }
 6229                                },
 6230                            }
 6231                        });
 6232                        tasks.push((lsp_adapter, new_task));
 6233                    }
 6234                })?;
 6235
 6236                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6237                    let completion_response = task.await.ok()??;
 6238                    let completions = populate_labels_for_completions(
 6239                            completion_response.completions,
 6240                            language.clone(),
 6241                            lsp_adapter,
 6242                        )
 6243                        .await;
 6244                    Some(CompletionResponse {
 6245                        completions,
 6246                        display_options: CompletionDisplayOptions::default(),
 6247                        is_incomplete: completion_response.is_incomplete,
 6248                    })
 6249                });
 6250
 6251                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6252
 6253                Ok(responses.into_iter().flatten().collect())
 6254            })
 6255        } else {
 6256            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6257        }
 6258    }
 6259
 6260    pub fn resolve_completions(
 6261        &self,
 6262        buffer: Entity<Buffer>,
 6263        completion_indices: Vec<usize>,
 6264        completions: Rc<RefCell<Box<[Completion]>>>,
 6265        cx: &mut Context<Self>,
 6266    ) -> Task<Result<bool>> {
 6267        let client = self.upstream_client();
 6268        let buffer_id = buffer.read(cx).remote_id();
 6269        let buffer_snapshot = buffer.read(cx).snapshot();
 6270
 6271        if !self.check_if_capable_for_proto_request(
 6272            &buffer,
 6273            GetCompletions::can_resolve_completions,
 6274            cx,
 6275        ) {
 6276            return Task::ready(Ok(false));
 6277        }
 6278        cx.spawn(async move |lsp_store, cx| {
 6279            let mut did_resolve = false;
 6280            if let Some((client, project_id)) = client {
 6281                for completion_index in completion_indices {
 6282                    let server_id = {
 6283                        let completion = &completions.borrow()[completion_index];
 6284                        completion.source.server_id()
 6285                    };
 6286                    if let Some(server_id) = server_id {
 6287                        if Self::resolve_completion_remote(
 6288                            project_id,
 6289                            server_id,
 6290                            buffer_id,
 6291                            completions.clone(),
 6292                            completion_index,
 6293                            client.clone(),
 6294                        )
 6295                        .await
 6296                        .log_err()
 6297                        .is_some()
 6298                        {
 6299                            did_resolve = true;
 6300                        }
 6301                    } else {
 6302                        resolve_word_completion(
 6303                            &buffer_snapshot,
 6304                            &mut completions.borrow_mut()[completion_index],
 6305                        );
 6306                    }
 6307                }
 6308            } else {
 6309                for completion_index in completion_indices {
 6310                    let server_id = {
 6311                        let completion = &completions.borrow()[completion_index];
 6312                        completion.source.server_id()
 6313                    };
 6314                    if let Some(server_id) = server_id {
 6315                        let server_and_adapter = lsp_store
 6316                            .read_with(cx, |lsp_store, _| {
 6317                                let server = lsp_store.language_server_for_id(server_id)?;
 6318                                let adapter =
 6319                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6320                                Some((server, adapter))
 6321                            })
 6322                            .ok()
 6323                            .flatten();
 6324                        let Some((server, adapter)) = server_and_adapter else {
 6325                            continue;
 6326                        };
 6327
 6328                        let resolved = Self::resolve_completion_local(
 6329                            server,
 6330                            completions.clone(),
 6331                            completion_index,
 6332                        )
 6333                        .await
 6334                        .log_err()
 6335                        .is_some();
 6336                        if resolved {
 6337                            Self::regenerate_completion_labels(
 6338                                adapter,
 6339                                &buffer_snapshot,
 6340                                completions.clone(),
 6341                                completion_index,
 6342                            )
 6343                            .await
 6344                            .log_err();
 6345                            did_resolve = true;
 6346                        }
 6347                    } else {
 6348                        resolve_word_completion(
 6349                            &buffer_snapshot,
 6350                            &mut completions.borrow_mut()[completion_index],
 6351                        );
 6352                    }
 6353                }
 6354            }
 6355
 6356            Ok(did_resolve)
 6357        })
 6358    }
 6359
 6360    async fn resolve_completion_local(
 6361        server: Arc<lsp::LanguageServer>,
 6362        completions: Rc<RefCell<Box<[Completion]>>>,
 6363        completion_index: usize,
 6364    ) -> Result<()> {
 6365        let server_id = server.server_id();
 6366        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6367            return Ok(());
 6368        }
 6369
 6370        let request = {
 6371            let completion = &completions.borrow()[completion_index];
 6372            match &completion.source {
 6373                CompletionSource::Lsp {
 6374                    lsp_completion,
 6375                    resolved,
 6376                    server_id: completion_server_id,
 6377                    ..
 6378                } => {
 6379                    if *resolved {
 6380                        return Ok(());
 6381                    }
 6382                    anyhow::ensure!(
 6383                        server_id == *completion_server_id,
 6384                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6385                    );
 6386                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6387                }
 6388                CompletionSource::BufferWord { .. }
 6389                | CompletionSource::Dap { .. }
 6390                | CompletionSource::Custom => {
 6391                    return Ok(());
 6392                }
 6393            }
 6394        };
 6395        let resolved_completion = request
 6396            .await
 6397            .into_response()
 6398            .context("resolve completion")?;
 6399
 6400        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6401        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6402
 6403        let mut completions = completions.borrow_mut();
 6404        let completion = &mut completions[completion_index];
 6405        if let CompletionSource::Lsp {
 6406            lsp_completion,
 6407            resolved,
 6408            server_id: completion_server_id,
 6409            ..
 6410        } = &mut completion.source
 6411        {
 6412            if *resolved {
 6413                return Ok(());
 6414            }
 6415            anyhow::ensure!(
 6416                server_id == *completion_server_id,
 6417                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6418            );
 6419            *lsp_completion = Box::new(resolved_completion);
 6420            *resolved = true;
 6421        }
 6422        Ok(())
 6423    }
 6424
 6425    async fn regenerate_completion_labels(
 6426        adapter: Arc<CachedLspAdapter>,
 6427        snapshot: &BufferSnapshot,
 6428        completions: Rc<RefCell<Box<[Completion]>>>,
 6429        completion_index: usize,
 6430    ) -> Result<()> {
 6431        let completion_item = completions.borrow()[completion_index]
 6432            .source
 6433            .lsp_completion(true)
 6434            .map(Cow::into_owned);
 6435        if let Some(lsp_documentation) = completion_item
 6436            .as_ref()
 6437            .and_then(|completion_item| completion_item.documentation.clone())
 6438        {
 6439            let mut completions = completions.borrow_mut();
 6440            let completion = &mut completions[completion_index];
 6441            completion.documentation = Some(lsp_documentation.into());
 6442        } else {
 6443            let mut completions = completions.borrow_mut();
 6444            let completion = &mut completions[completion_index];
 6445            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6446        }
 6447
 6448        let mut new_label = match completion_item {
 6449            Some(completion_item) => {
 6450                // 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
 6451                // So we have to update the label here anyway...
 6452                let language = snapshot.language();
 6453                match language {
 6454                    Some(language) => {
 6455                        adapter
 6456                            .labels_for_completions(
 6457                                std::slice::from_ref(&completion_item),
 6458                                language,
 6459                            )
 6460                            .await?
 6461                    }
 6462                    None => Vec::new(),
 6463                }
 6464                .pop()
 6465                .flatten()
 6466                .unwrap_or_else(|| {
 6467                    CodeLabel::fallback_for_completion(
 6468                        &completion_item,
 6469                        language.map(|language| language.as_ref()),
 6470                    )
 6471                })
 6472            }
 6473            None => CodeLabel::plain(
 6474                completions.borrow()[completion_index].new_text.clone(),
 6475                None,
 6476            ),
 6477        };
 6478        ensure_uniform_list_compatible_label(&mut new_label);
 6479
 6480        let mut completions = completions.borrow_mut();
 6481        let completion = &mut completions[completion_index];
 6482        if completion.label.filter_text() == new_label.filter_text() {
 6483            completion.label = new_label;
 6484        } else {
 6485            log::error!(
 6486                "Resolved completion changed display label from {} to {}. \
 6487                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6488                completion.label.text(),
 6489                new_label.text(),
 6490                completion.label.filter_text(),
 6491                new_label.filter_text()
 6492            );
 6493        }
 6494
 6495        Ok(())
 6496    }
 6497
 6498    async fn resolve_completion_remote(
 6499        project_id: u64,
 6500        server_id: LanguageServerId,
 6501        buffer_id: BufferId,
 6502        completions: Rc<RefCell<Box<[Completion]>>>,
 6503        completion_index: usize,
 6504        client: AnyProtoClient,
 6505    ) -> Result<()> {
 6506        let lsp_completion = {
 6507            let completion = &completions.borrow()[completion_index];
 6508            match &completion.source {
 6509                CompletionSource::Lsp {
 6510                    lsp_completion,
 6511                    resolved,
 6512                    server_id: completion_server_id,
 6513                    ..
 6514                } => {
 6515                    anyhow::ensure!(
 6516                        server_id == *completion_server_id,
 6517                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6518                    );
 6519                    if *resolved {
 6520                        return Ok(());
 6521                    }
 6522                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6523                }
 6524                CompletionSource::Custom
 6525                | CompletionSource::Dap { .. }
 6526                | CompletionSource::BufferWord { .. } => {
 6527                    return Ok(());
 6528                }
 6529            }
 6530        };
 6531        let request = proto::ResolveCompletionDocumentation {
 6532            project_id,
 6533            language_server_id: server_id.0 as u64,
 6534            lsp_completion,
 6535            buffer_id: buffer_id.into(),
 6536        };
 6537
 6538        let response = client
 6539            .request(request)
 6540            .await
 6541            .context("completion documentation resolve proto request")?;
 6542        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6543
 6544        let documentation = if response.documentation.is_empty() {
 6545            CompletionDocumentation::Undocumented
 6546        } else if response.documentation_is_markdown {
 6547            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6548        } else if response.documentation.lines().count() <= 1 {
 6549            CompletionDocumentation::SingleLine(response.documentation.into())
 6550        } else {
 6551            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6552        };
 6553
 6554        let mut completions = completions.borrow_mut();
 6555        let completion = &mut completions[completion_index];
 6556        completion.documentation = Some(documentation);
 6557        if let CompletionSource::Lsp {
 6558            insert_range,
 6559            lsp_completion,
 6560            resolved,
 6561            server_id: completion_server_id,
 6562            lsp_defaults: _,
 6563        } = &mut completion.source
 6564        {
 6565            let completion_insert_range = response
 6566                .old_insert_start
 6567                .and_then(deserialize_anchor)
 6568                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6569            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6570
 6571            if *resolved {
 6572                return Ok(());
 6573            }
 6574            anyhow::ensure!(
 6575                server_id == *completion_server_id,
 6576                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6577            );
 6578            *lsp_completion = Box::new(resolved_lsp_completion);
 6579            *resolved = true;
 6580        }
 6581
 6582        let replace_range = response
 6583            .old_replace_start
 6584            .and_then(deserialize_anchor)
 6585            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6586        if let Some((old_replace_start, old_replace_end)) = replace_range
 6587            && !response.new_text.is_empty()
 6588        {
 6589            completion.new_text = response.new_text;
 6590            completion.replace_range = old_replace_start..old_replace_end;
 6591        }
 6592
 6593        Ok(())
 6594    }
 6595
 6596    pub fn apply_additional_edits_for_completion(
 6597        &self,
 6598        buffer_handle: Entity<Buffer>,
 6599        completions: Rc<RefCell<Box<[Completion]>>>,
 6600        completion_index: usize,
 6601        push_to_history: bool,
 6602        cx: &mut Context<Self>,
 6603    ) -> Task<Result<Option<Transaction>>> {
 6604        if let Some((client, project_id)) = self.upstream_client() {
 6605            let buffer = buffer_handle.read(cx);
 6606            let buffer_id = buffer.remote_id();
 6607            cx.spawn(async move |_, cx| {
 6608                let request = {
 6609                    let completion = completions.borrow()[completion_index].clone();
 6610                    proto::ApplyCompletionAdditionalEdits {
 6611                        project_id,
 6612                        buffer_id: buffer_id.into(),
 6613                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6614                            replace_range: completion.replace_range,
 6615                            new_text: completion.new_text,
 6616                            source: completion.source,
 6617                        })),
 6618                    }
 6619                };
 6620
 6621                if let Some(transaction) = client.request(request).await?.transaction {
 6622                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6623                    buffer_handle
 6624                        .update(cx, |buffer, _| {
 6625                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6626                        })?
 6627                        .await?;
 6628                    if push_to_history {
 6629                        buffer_handle.update(cx, |buffer, _| {
 6630                            buffer.push_transaction(transaction.clone(), Instant::now());
 6631                            buffer.finalize_last_transaction();
 6632                        })?;
 6633                    }
 6634                    Ok(Some(transaction))
 6635                } else {
 6636                    Ok(None)
 6637                }
 6638            })
 6639        } else {
 6640            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6641                let completion = &completions.borrow()[completion_index];
 6642                let server_id = completion.source.server_id()?;
 6643                Some(
 6644                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6645                        .1
 6646                        .clone(),
 6647                )
 6648            }) else {
 6649                return Task::ready(Ok(None));
 6650            };
 6651
 6652            cx.spawn(async move |this, cx| {
 6653                Self::resolve_completion_local(
 6654                    server.clone(),
 6655                    completions.clone(),
 6656                    completion_index,
 6657                )
 6658                .await
 6659                .context("resolving completion")?;
 6660                let completion = completions.borrow()[completion_index].clone();
 6661                let additional_text_edits = completion
 6662                    .source
 6663                    .lsp_completion(true)
 6664                    .as_ref()
 6665                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6666                if let Some(edits) = additional_text_edits {
 6667                    let edits = this
 6668                        .update(cx, |this, cx| {
 6669                            this.as_local_mut().unwrap().edits_from_lsp(
 6670                                &buffer_handle,
 6671                                edits,
 6672                                server.server_id(),
 6673                                None,
 6674                                cx,
 6675                            )
 6676                        })?
 6677                        .await?;
 6678
 6679                    buffer_handle.update(cx, |buffer, cx| {
 6680                        buffer.finalize_last_transaction();
 6681                        buffer.start_transaction();
 6682
 6683                        for (range, text) in edits {
 6684                            let primary = &completion.replace_range;
 6685
 6686                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6687                            // and the primary completion is just an insertion (empty range), then this is likely
 6688                            // an auto-import scenario and should not be considered overlapping
 6689                            // https://github.com/zed-industries/zed/issues/26136
 6690                            let is_file_start_auto_import = {
 6691                                let snapshot = buffer.snapshot();
 6692                                let primary_start_point = primary.start.to_point(&snapshot);
 6693                                let range_start_point = range.start.to_point(&snapshot);
 6694
 6695                                let result = primary_start_point.row == 0
 6696                                    && primary_start_point.column == 0
 6697                                    && range_start_point.row == 0
 6698                                    && range_start_point.column == 0;
 6699
 6700                                result
 6701                            };
 6702
 6703                            let has_overlap = if is_file_start_auto_import {
 6704                                false
 6705                            } else {
 6706                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6707                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6708                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6709                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6710                                let result = start_within || end_within;
 6711                                result
 6712                            };
 6713
 6714                            //Skip additional edits which overlap with the primary completion edit
 6715                            //https://github.com/zed-industries/zed/pull/1871
 6716                            if !has_overlap {
 6717                                buffer.edit([(range, text)], None, cx);
 6718                            }
 6719                        }
 6720
 6721                        let transaction = if buffer.end_transaction(cx).is_some() {
 6722                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6723                            if !push_to_history {
 6724                                buffer.forget_transaction(transaction.id);
 6725                            }
 6726                            Some(transaction)
 6727                        } else {
 6728                            None
 6729                        };
 6730                        Ok(transaction)
 6731                    })?
 6732                } else {
 6733                    Ok(None)
 6734                }
 6735            })
 6736        }
 6737    }
 6738
 6739    pub fn pull_diagnostics(
 6740        &mut self,
 6741        buffer: Entity<Buffer>,
 6742        cx: &mut Context<Self>,
 6743    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6744        let buffer_id = buffer.read(cx).remote_id();
 6745
 6746        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6747            let mut suitable_capabilities = None;
 6748            // Are we capable for proto request?
 6749            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6750                &buffer,
 6751                |capabilities| {
 6752                    if let Some(caps) = &capabilities.diagnostic_provider {
 6753                        suitable_capabilities = Some(caps.clone());
 6754                        true
 6755                    } else {
 6756                        false
 6757                    }
 6758                },
 6759                cx,
 6760            );
 6761            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6762            let Some(dynamic_caps) = suitable_capabilities else {
 6763                return Task::ready(Ok(None));
 6764            };
 6765            assert!(any_server_has_diagnostics_provider);
 6766
 6767            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6768            let request = GetDocumentDiagnostics {
 6769                previous_result_id: None,
 6770                identifier,
 6771                registration_id: None,
 6772            };
 6773            let request_task = client.request_lsp(
 6774                upstream_project_id,
 6775                None,
 6776                LSP_REQUEST_TIMEOUT,
 6777                cx.background_executor().clone(),
 6778                request.to_proto(upstream_project_id, buffer.read(cx)),
 6779            );
 6780            cx.background_spawn(async move {
 6781                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6782                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6783                // Do not attempt to further process the dummy responses here.
 6784                let _response = request_task.await?;
 6785                Ok(None)
 6786            })
 6787        } else {
 6788            let servers = buffer.update(cx, |buffer, cx| {
 6789                self.running_language_servers_for_local_buffer(buffer, cx)
 6790                    .map(|(_, server)| server.clone())
 6791                    .collect::<Vec<_>>()
 6792            });
 6793
 6794            let pull_diagnostics = servers
 6795                .into_iter()
 6796                .flat_map(|server| {
 6797                    let result = maybe!({
 6798                        let local = self.as_local()?;
 6799                        let server_id = server.server_id();
 6800                        let providers_with_identifiers = local
 6801                            .language_server_dynamic_registrations
 6802                            .get(&server_id)
 6803                            .into_iter()
 6804                            .flat_map(|registrations| registrations.diagnostics.clone())
 6805                            .collect::<Vec<_>>();
 6806                        Some(
 6807                            providers_with_identifiers
 6808                                .into_iter()
 6809                                .map(|(registration_id, dynamic_caps)| {
 6810                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6811                                    let registration_id = registration_id.map(SharedString::from);
 6812                                    let result_id = self.result_id_for_buffer_pull(
 6813                                        server_id,
 6814                                        buffer_id,
 6815                                        &registration_id,
 6816                                        cx,
 6817                                    );
 6818                                    self.request_lsp(
 6819                                        buffer.clone(),
 6820                                        LanguageServerToQuery::Other(server_id),
 6821                                        GetDocumentDiagnostics {
 6822                                            previous_result_id: result_id,
 6823                                            registration_id,
 6824                                            identifier,
 6825                                        },
 6826                                        cx,
 6827                                    )
 6828                                })
 6829                                .collect::<Vec<_>>(),
 6830                        )
 6831                    });
 6832
 6833                    result.unwrap_or_default()
 6834                })
 6835                .collect::<Vec<_>>();
 6836
 6837            cx.background_spawn(async move {
 6838                let mut responses = Vec::new();
 6839                for diagnostics in join_all(pull_diagnostics).await {
 6840                    responses.extend(diagnostics?);
 6841                }
 6842                Ok(Some(responses))
 6843            })
 6844        }
 6845    }
 6846
 6847    pub fn applicable_inlay_chunks(
 6848        &mut self,
 6849        buffer: &Entity<Buffer>,
 6850        ranges: &[Range<text::Anchor>],
 6851        cx: &mut Context<Self>,
 6852    ) -> Vec<Range<BufferRow>> {
 6853        self.latest_lsp_data(buffer, cx)
 6854            .inlay_hints
 6855            .applicable_chunks(ranges)
 6856            .map(|chunk| chunk.row_range())
 6857            .collect()
 6858    }
 6859
 6860    pub fn invalidate_inlay_hints<'a>(
 6861        &'a mut self,
 6862        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6863    ) {
 6864        for buffer_id in for_buffers {
 6865            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6866                lsp_data.inlay_hints.clear();
 6867            }
 6868        }
 6869    }
 6870
 6871    pub fn inlay_hints(
 6872        &mut self,
 6873        invalidate: InvalidationStrategy,
 6874        buffer: Entity<Buffer>,
 6875        ranges: Vec<Range<text::Anchor>>,
 6876        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6877        cx: &mut Context<Self>,
 6878    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6879        let next_hint_id = self.next_hint_id.clone();
 6880        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6881        let query_version = lsp_data.buffer_version.clone();
 6882        let mut lsp_refresh_requested = false;
 6883        let for_server = if let InvalidationStrategy::RefreshRequested {
 6884            server_id,
 6885            request_id,
 6886        } = invalidate
 6887        {
 6888            let invalidated = lsp_data
 6889                .inlay_hints
 6890                .invalidate_for_server_refresh(server_id, request_id);
 6891            lsp_refresh_requested = invalidated;
 6892            Some(server_id)
 6893        } else {
 6894            None
 6895        };
 6896        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6897        let known_chunks = known_chunks
 6898            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6899            .map(|(_, known_chunks)| known_chunks)
 6900            .unwrap_or_default();
 6901
 6902        let mut hint_fetch_tasks = Vec::new();
 6903        let mut cached_inlay_hints = None;
 6904        let mut ranges_to_query = None;
 6905        let applicable_chunks = existing_inlay_hints
 6906            .applicable_chunks(ranges.as_slice())
 6907            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6908            .collect::<Vec<_>>();
 6909        if applicable_chunks.is_empty() {
 6910            return HashMap::default();
 6911        }
 6912
 6913        for row_chunk in applicable_chunks {
 6914            match (
 6915                existing_inlay_hints
 6916                    .cached_hints(&row_chunk)
 6917                    .filter(|_| !lsp_refresh_requested)
 6918                    .cloned(),
 6919                existing_inlay_hints
 6920                    .fetched_hints(&row_chunk)
 6921                    .as_ref()
 6922                    .filter(|_| !lsp_refresh_requested)
 6923                    .cloned(),
 6924            ) {
 6925                (None, None) => {
 6926                    let Some(chunk_range) = existing_inlay_hints.chunk_range(row_chunk) else {
 6927                        continue;
 6928                    };
 6929                    ranges_to_query
 6930                        .get_or_insert_with(Vec::new)
 6931                        .push((row_chunk, chunk_range));
 6932                }
 6933                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6934                (Some(cached_hints), None) => {
 6935                    for (server_id, cached_hints) in cached_hints {
 6936                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6937                            cached_inlay_hints
 6938                                .get_or_insert_with(HashMap::default)
 6939                                .entry(row_chunk.row_range())
 6940                                .or_insert_with(HashMap::default)
 6941                                .entry(server_id)
 6942                                .or_insert_with(Vec::new)
 6943                                .extend(cached_hints);
 6944                        }
 6945                    }
 6946                }
 6947                (Some(cached_hints), Some(fetched_hints)) => {
 6948                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6949                    for (server_id, cached_hints) in cached_hints {
 6950                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6951                            cached_inlay_hints
 6952                                .get_or_insert_with(HashMap::default)
 6953                                .entry(row_chunk.row_range())
 6954                                .or_insert_with(HashMap::default)
 6955                                .entry(server_id)
 6956                                .or_insert_with(Vec::new)
 6957                                .extend(cached_hints);
 6958                        }
 6959                    }
 6960                }
 6961            }
 6962        }
 6963
 6964        if hint_fetch_tasks.is_empty()
 6965            && ranges_to_query
 6966                .as_ref()
 6967                .is_none_or(|ranges| ranges.is_empty())
 6968            && let Some(cached_inlay_hints) = cached_inlay_hints
 6969        {
 6970            cached_inlay_hints
 6971                .into_iter()
 6972                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6973                .collect()
 6974        } else {
 6975            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6976                let next_hint_id = next_hint_id.clone();
 6977                let buffer = buffer.clone();
 6978                let query_version = query_version.clone();
 6979                let new_inlay_hints = cx
 6980                    .spawn(async move |lsp_store, cx| {
 6981                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6982                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6983                        })?;
 6984                        new_fetch_task
 6985                            .await
 6986                            .and_then(|new_hints_by_server| {
 6987                                lsp_store.update(cx, |lsp_store, cx| {
 6988                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6989                                    let update_cache = lsp_data.buffer_version == query_version;
 6990                                    if new_hints_by_server.is_empty() {
 6991                                        if update_cache {
 6992                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6993                                        }
 6994                                        HashMap::default()
 6995                                    } else {
 6996                                        new_hints_by_server
 6997                                            .into_iter()
 6998                                            .map(|(server_id, new_hints)| {
 6999                                                let new_hints = new_hints
 7000                                                    .into_iter()
 7001                                                    .map(|new_hint| {
 7002                                                        (
 7003                                                            InlayId::Hint(next_hint_id.fetch_add(
 7004                                                                1,
 7005                                                                atomic::Ordering::AcqRel,
 7006                                                            )),
 7007                                                            new_hint,
 7008                                                        )
 7009                                                    })
 7010                                                    .collect::<Vec<_>>();
 7011                                                if update_cache {
 7012                                                    lsp_data.inlay_hints.insert_new_hints(
 7013                                                        chunk,
 7014                                                        server_id,
 7015                                                        new_hints.clone(),
 7016                                                    );
 7017                                                }
 7018                                                (server_id, new_hints)
 7019                                            })
 7020                                            .collect()
 7021                                    }
 7022                                })
 7023                            })
 7024                            .map_err(Arc::new)
 7025                    })
 7026                    .shared();
 7027
 7028                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7029                *fetch_task = Some(new_inlay_hints.clone());
 7030                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7031            }
 7032
 7033            cached_inlay_hints
 7034                .unwrap_or_default()
 7035                .into_iter()
 7036                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7037                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7038                    (
 7039                        chunk.row_range(),
 7040                        cx.spawn(async move |_, _| {
 7041                            hints_fetch.await.map_err(|e| {
 7042                                if e.error_code() != ErrorCode::Internal {
 7043                                    anyhow!(e.error_code())
 7044                                } else {
 7045                                    anyhow!("{e:#}")
 7046                                }
 7047                            })
 7048                        }),
 7049                    )
 7050                }))
 7051                .collect()
 7052        }
 7053    }
 7054
 7055    fn fetch_inlay_hints(
 7056        &mut self,
 7057        for_server: Option<LanguageServerId>,
 7058        buffer: &Entity<Buffer>,
 7059        range: Range<Anchor>,
 7060        cx: &mut Context<Self>,
 7061    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7062        let request = InlayHints {
 7063            range: range.clone(),
 7064        };
 7065        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7066            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7067                return Task::ready(Ok(HashMap::default()));
 7068            }
 7069            let request_task = upstream_client.request_lsp(
 7070                project_id,
 7071                for_server.map(|id| id.to_proto()),
 7072                LSP_REQUEST_TIMEOUT,
 7073                cx.background_executor().clone(),
 7074                request.to_proto(project_id, buffer.read(cx)),
 7075            );
 7076            let buffer = buffer.clone();
 7077            cx.spawn(async move |weak_lsp_store, cx| {
 7078                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7079                    return Ok(HashMap::default());
 7080                };
 7081                let Some(responses) = request_task.await? else {
 7082                    return Ok(HashMap::default());
 7083                };
 7084
 7085                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7086                    let lsp_store = lsp_store.clone();
 7087                    let buffer = buffer.clone();
 7088                    let cx = cx.clone();
 7089                    let request = request.clone();
 7090                    async move {
 7091                        (
 7092                            LanguageServerId::from_proto(response.server_id),
 7093                            request
 7094                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7095                                .await,
 7096                        )
 7097                    }
 7098                }))
 7099                .await;
 7100
 7101                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7102                let mut has_errors = false;
 7103                let inlay_hints = inlay_hints
 7104                    .into_iter()
 7105                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7106                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7107                        Err(e) => {
 7108                            has_errors = true;
 7109                            log::error!("{e:#}");
 7110                            None
 7111                        }
 7112                    })
 7113                    .map(|(server_id, mut new_hints)| {
 7114                        new_hints.retain(|hint| {
 7115                            hint.position.is_valid(&buffer_snapshot)
 7116                                && range.start.is_valid(&buffer_snapshot)
 7117                                && range.end.is_valid(&buffer_snapshot)
 7118                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7119                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7120                        });
 7121                        (server_id, new_hints)
 7122                    })
 7123                    .collect::<HashMap<_, _>>();
 7124                anyhow::ensure!(
 7125                    !has_errors || !inlay_hints.is_empty(),
 7126                    "Failed to fetch inlay hints"
 7127                );
 7128                Ok(inlay_hints)
 7129            })
 7130        } else {
 7131            let inlay_hints_task = match for_server {
 7132                Some(server_id) => {
 7133                    let server_task = self.request_lsp(
 7134                        buffer.clone(),
 7135                        LanguageServerToQuery::Other(server_id),
 7136                        request,
 7137                        cx,
 7138                    );
 7139                    cx.background_spawn(async move {
 7140                        let mut responses = Vec::new();
 7141                        match server_task.await {
 7142                            Ok(response) => responses.push((server_id, response)),
 7143                            // rust-analyzer likes to error with this when its still loading up
 7144                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7145                            Err(e) => log::error!(
 7146                                "Error handling response for inlay hints request: {e:#}"
 7147                            ),
 7148                        }
 7149                        responses
 7150                    })
 7151                }
 7152                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7153            };
 7154            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7155            cx.background_spawn(async move {
 7156                Ok(inlay_hints_task
 7157                    .await
 7158                    .into_iter()
 7159                    .map(|(server_id, mut new_hints)| {
 7160                        new_hints.retain(|hint| {
 7161                            hint.position.is_valid(&buffer_snapshot)
 7162                                && range.start.is_valid(&buffer_snapshot)
 7163                                && range.end.is_valid(&buffer_snapshot)
 7164                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7165                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7166                        });
 7167                        (server_id, new_hints)
 7168                    })
 7169                    .collect())
 7170            })
 7171        }
 7172    }
 7173
 7174    pub fn pull_diagnostics_for_buffer(
 7175        &mut self,
 7176        buffer: Entity<Buffer>,
 7177        cx: &mut Context<Self>,
 7178    ) -> Task<anyhow::Result<()>> {
 7179        let diagnostics = self.pull_diagnostics(buffer, cx);
 7180        cx.spawn(async move |lsp_store, cx| {
 7181            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7182                return Ok(());
 7183            };
 7184            lsp_store.update(cx, |lsp_store, cx| {
 7185                if lsp_store.as_local().is_none() {
 7186                    return;
 7187                }
 7188
 7189                let mut unchanged_buffers = HashMap::default();
 7190                let server_diagnostics_updates = diagnostics
 7191                    .into_iter()
 7192                    .filter_map(|diagnostics_set| match diagnostics_set {
 7193                        LspPullDiagnostics::Response {
 7194                            server_id,
 7195                            uri,
 7196                            diagnostics,
 7197                            registration_id,
 7198                        } => Some((server_id, uri, diagnostics, registration_id)),
 7199                        LspPullDiagnostics::Default => None,
 7200                    })
 7201                    .fold(
 7202                        HashMap::default(),
 7203                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7204                            let (result_id, diagnostics) = match diagnostics {
 7205                                PulledDiagnostics::Unchanged { result_id } => {
 7206                                    unchanged_buffers
 7207                                        .entry(new_registration_id.clone())
 7208                                        .or_insert_with(HashSet::default)
 7209                                        .insert(uri.clone());
 7210                                    (Some(result_id), Vec::new())
 7211                                }
 7212                                PulledDiagnostics::Changed {
 7213                                    result_id,
 7214                                    diagnostics,
 7215                                } => (result_id, diagnostics),
 7216                            };
 7217                            let disk_based_sources = Cow::Owned(
 7218                                lsp_store
 7219                                    .language_server_adapter_for_id(server_id)
 7220                                    .as_ref()
 7221                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7222                                    .unwrap_or(&[])
 7223                                    .to_vec(),
 7224                            );
 7225                            acc.entry(server_id)
 7226                                .or_insert_with(HashMap::default)
 7227                                .entry(new_registration_id.clone())
 7228                                .or_insert_with(Vec::new)
 7229                                .push(DocumentDiagnosticsUpdate {
 7230                                    server_id,
 7231                                    diagnostics: lsp::PublishDiagnosticsParams {
 7232                                        uri,
 7233                                        diagnostics,
 7234                                        version: None,
 7235                                    },
 7236                                    result_id,
 7237                                    disk_based_sources,
 7238                                    registration_id: new_registration_id,
 7239                                });
 7240                            acc
 7241                        },
 7242                    );
 7243
 7244                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7245                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7246                        lsp_store
 7247                            .merge_lsp_diagnostics(
 7248                                DiagnosticSourceKind::Pulled,
 7249                                diagnostic_updates,
 7250                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7251                                    DiagnosticSourceKind::Pulled => {
 7252                                        old_diagnostic.registration_id != registration_id
 7253                                            || unchanged_buffers
 7254                                                .get(&old_diagnostic.registration_id)
 7255                                                .is_some_and(|unchanged_buffers| {
 7256                                                    unchanged_buffers.contains(&document_uri)
 7257                                                })
 7258                                    }
 7259                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7260                                        true
 7261                                    }
 7262                                },
 7263                                cx,
 7264                            )
 7265                            .log_err();
 7266                    }
 7267                }
 7268            })
 7269        })
 7270    }
 7271
 7272    pub fn document_colors(
 7273        &mut self,
 7274        known_cache_version: Option<usize>,
 7275        buffer: Entity<Buffer>,
 7276        cx: &mut Context<Self>,
 7277    ) -> Option<DocumentColorTask> {
 7278        let version_queried_for = buffer.read(cx).version();
 7279        let buffer_id = buffer.read(cx).remote_id();
 7280
 7281        let current_language_servers = self.as_local().map(|local| {
 7282            local
 7283                .buffers_opened_in_servers
 7284                .get(&buffer_id)
 7285                .cloned()
 7286                .unwrap_or_default()
 7287        });
 7288
 7289        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7290            if let Some(cached_colors) = &lsp_data.document_colors {
 7291                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7292                    let has_different_servers =
 7293                        current_language_servers.is_some_and(|current_language_servers| {
 7294                            current_language_servers
 7295                                != cached_colors.colors.keys().copied().collect()
 7296                        });
 7297                    if !has_different_servers {
 7298                        let cache_version = cached_colors.cache_version;
 7299                        if Some(cache_version) == known_cache_version {
 7300                            return None;
 7301                        } else {
 7302                            return Some(
 7303                                Task::ready(Ok(DocumentColors {
 7304                                    colors: cached_colors
 7305                                        .colors
 7306                                        .values()
 7307                                        .flatten()
 7308                                        .cloned()
 7309                                        .collect(),
 7310                                    cache_version: Some(cache_version),
 7311                                }))
 7312                                .shared(),
 7313                            );
 7314                        }
 7315                    }
 7316                }
 7317            }
 7318        }
 7319
 7320        let color_lsp_data = self
 7321            .latest_lsp_data(&buffer, cx)
 7322            .document_colors
 7323            .get_or_insert_default();
 7324        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7325            && !version_queried_for.changed_since(updating_for)
 7326        {
 7327            return Some(running_update.clone());
 7328        }
 7329        let buffer_version_queried_for = version_queried_for.clone();
 7330        let new_task = cx
 7331            .spawn(async move |lsp_store, cx| {
 7332                cx.background_executor()
 7333                    .timer(Duration::from_millis(30))
 7334                    .await;
 7335                let fetched_colors = lsp_store
 7336                    .update(cx, |lsp_store, cx| {
 7337                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7338                    })?
 7339                    .await
 7340                    .context("fetching document colors")
 7341                    .map_err(Arc::new);
 7342                let fetched_colors = match fetched_colors {
 7343                    Ok(fetched_colors) => {
 7344                        if Some(true)
 7345                            == buffer
 7346                                .update(cx, |buffer, _| {
 7347                                    buffer.version() != buffer_version_queried_for
 7348                                })
 7349                                .ok()
 7350                        {
 7351                            return Ok(DocumentColors::default());
 7352                        }
 7353                        fetched_colors
 7354                    }
 7355                    Err(e) => {
 7356                        lsp_store
 7357                            .update(cx, |lsp_store, _| {
 7358                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7359                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7360                                        document_colors.colors_update = None;
 7361                                    }
 7362                                }
 7363                            })
 7364                            .ok();
 7365                        return Err(e);
 7366                    }
 7367                };
 7368
 7369                lsp_store
 7370                    .update(cx, |lsp_store, cx| {
 7371                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7372                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7373
 7374                        if let Some(fetched_colors) = fetched_colors {
 7375                            if lsp_data.buffer_version == buffer_version_queried_for {
 7376                                lsp_colors.colors.extend(fetched_colors);
 7377                                lsp_colors.cache_version += 1;
 7378                            } else if !lsp_data
 7379                                .buffer_version
 7380                                .changed_since(&buffer_version_queried_for)
 7381                            {
 7382                                lsp_data.buffer_version = buffer_version_queried_for;
 7383                                lsp_colors.colors = fetched_colors;
 7384                                lsp_colors.cache_version += 1;
 7385                            }
 7386                        }
 7387                        lsp_colors.colors_update = None;
 7388                        let colors = lsp_colors
 7389                            .colors
 7390                            .values()
 7391                            .flatten()
 7392                            .cloned()
 7393                            .collect::<HashSet<_>>();
 7394                        DocumentColors {
 7395                            colors,
 7396                            cache_version: Some(lsp_colors.cache_version),
 7397                        }
 7398                    })
 7399                    .map_err(Arc::new)
 7400            })
 7401            .shared();
 7402        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7403        Some(new_task)
 7404    }
 7405
 7406    fn fetch_document_colors_for_buffer(
 7407        &mut self,
 7408        buffer: &Entity<Buffer>,
 7409        cx: &mut Context<Self>,
 7410    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7411        if let Some((client, project_id)) = self.upstream_client() {
 7412            let request = GetDocumentColor {};
 7413            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7414                return Task::ready(Ok(None));
 7415            }
 7416
 7417            let request_task = client.request_lsp(
 7418                project_id,
 7419                None,
 7420                LSP_REQUEST_TIMEOUT,
 7421                cx.background_executor().clone(),
 7422                request.to_proto(project_id, buffer.read(cx)),
 7423            );
 7424            let buffer = buffer.clone();
 7425            cx.spawn(async move |lsp_store, cx| {
 7426                let Some(lsp_store) = lsp_store.upgrade() else {
 7427                    return Ok(None);
 7428                };
 7429                let colors = join_all(
 7430                    request_task
 7431                        .await
 7432                        .log_err()
 7433                        .flatten()
 7434                        .map(|response| response.payload)
 7435                        .unwrap_or_default()
 7436                        .into_iter()
 7437                        .map(|color_response| {
 7438                            let response = request.response_from_proto(
 7439                                color_response.response,
 7440                                lsp_store.clone(),
 7441                                buffer.clone(),
 7442                                cx.clone(),
 7443                            );
 7444                            async move {
 7445                                (
 7446                                    LanguageServerId::from_proto(color_response.server_id),
 7447                                    response.await.log_err().unwrap_or_default(),
 7448                                )
 7449                            }
 7450                        }),
 7451                )
 7452                .await
 7453                .into_iter()
 7454                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7455                    acc.entry(server_id)
 7456                        .or_insert_with(HashSet::default)
 7457                        .extend(colors);
 7458                    acc
 7459                });
 7460                Ok(Some(colors))
 7461            })
 7462        } else {
 7463            let document_colors_task =
 7464                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7465            cx.background_spawn(async move {
 7466                Ok(Some(
 7467                    document_colors_task
 7468                        .await
 7469                        .into_iter()
 7470                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7471                            acc.entry(server_id)
 7472                                .or_insert_with(HashSet::default)
 7473                                .extend(colors);
 7474                            acc
 7475                        })
 7476                        .into_iter()
 7477                        .collect(),
 7478                ))
 7479            })
 7480        }
 7481    }
 7482
 7483    pub fn signature_help<T: ToPointUtf16>(
 7484        &mut self,
 7485        buffer: &Entity<Buffer>,
 7486        position: T,
 7487        cx: &mut Context<Self>,
 7488    ) -> Task<Option<Vec<SignatureHelp>>> {
 7489        let position = position.to_point_utf16(buffer.read(cx));
 7490
 7491        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7492            let request = GetSignatureHelp { position };
 7493            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7494                return Task::ready(None);
 7495            }
 7496            let request_task = client.request_lsp(
 7497                upstream_project_id,
 7498                None,
 7499                LSP_REQUEST_TIMEOUT,
 7500                cx.background_executor().clone(),
 7501                request.to_proto(upstream_project_id, buffer.read(cx)),
 7502            );
 7503            let buffer = buffer.clone();
 7504            cx.spawn(async move |weak_lsp_store, cx| {
 7505                let lsp_store = weak_lsp_store.upgrade()?;
 7506                let signatures = join_all(
 7507                    request_task
 7508                        .await
 7509                        .log_err()
 7510                        .flatten()
 7511                        .map(|response| response.payload)
 7512                        .unwrap_or_default()
 7513                        .into_iter()
 7514                        .map(|response| {
 7515                            let response = GetSignatureHelp { position }.response_from_proto(
 7516                                response.response,
 7517                                lsp_store.clone(),
 7518                                buffer.clone(),
 7519                                cx.clone(),
 7520                            );
 7521                            async move { response.await.log_err().flatten() }
 7522                        }),
 7523                )
 7524                .await
 7525                .into_iter()
 7526                .flatten()
 7527                .collect();
 7528                Some(signatures)
 7529            })
 7530        } else {
 7531            let all_actions_task = self.request_multiple_lsp_locally(
 7532                buffer,
 7533                Some(position),
 7534                GetSignatureHelp { position },
 7535                cx,
 7536            );
 7537            cx.background_spawn(async move {
 7538                Some(
 7539                    all_actions_task
 7540                        .await
 7541                        .into_iter()
 7542                        .flat_map(|(_, actions)| actions)
 7543                        .collect::<Vec<_>>(),
 7544                )
 7545            })
 7546        }
 7547    }
 7548
 7549    pub fn hover(
 7550        &mut self,
 7551        buffer: &Entity<Buffer>,
 7552        position: PointUtf16,
 7553        cx: &mut Context<Self>,
 7554    ) -> Task<Option<Vec<Hover>>> {
 7555        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7556            let request = GetHover { position };
 7557            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7558                return Task::ready(None);
 7559            }
 7560            let request_task = client.request_lsp(
 7561                upstream_project_id,
 7562                None,
 7563                LSP_REQUEST_TIMEOUT,
 7564                cx.background_executor().clone(),
 7565                request.to_proto(upstream_project_id, buffer.read(cx)),
 7566            );
 7567            let buffer = buffer.clone();
 7568            cx.spawn(async move |weak_lsp_store, cx| {
 7569                let lsp_store = weak_lsp_store.upgrade()?;
 7570                let hovers = join_all(
 7571                    request_task
 7572                        .await
 7573                        .log_err()
 7574                        .flatten()
 7575                        .map(|response| response.payload)
 7576                        .unwrap_or_default()
 7577                        .into_iter()
 7578                        .map(|response| {
 7579                            let response = GetHover { position }.response_from_proto(
 7580                                response.response,
 7581                                lsp_store.clone(),
 7582                                buffer.clone(),
 7583                                cx.clone(),
 7584                            );
 7585                            async move {
 7586                                response
 7587                                    .await
 7588                                    .log_err()
 7589                                    .flatten()
 7590                                    .and_then(remove_empty_hover_blocks)
 7591                            }
 7592                        }),
 7593                )
 7594                .await
 7595                .into_iter()
 7596                .flatten()
 7597                .collect();
 7598                Some(hovers)
 7599            })
 7600        } else {
 7601            let all_actions_task = self.request_multiple_lsp_locally(
 7602                buffer,
 7603                Some(position),
 7604                GetHover { position },
 7605                cx,
 7606            );
 7607            cx.background_spawn(async move {
 7608                Some(
 7609                    all_actions_task
 7610                        .await
 7611                        .into_iter()
 7612                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7613                        .collect::<Vec<Hover>>(),
 7614                )
 7615            })
 7616        }
 7617    }
 7618
 7619    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7620        let language_registry = self.languages.clone();
 7621
 7622        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7623            let request = upstream_client.request(proto::GetProjectSymbols {
 7624                project_id: *project_id,
 7625                query: query.to_string(),
 7626            });
 7627            cx.foreground_executor().spawn(async move {
 7628                let response = request.await?;
 7629                let mut symbols = Vec::new();
 7630                let core_symbols = response
 7631                    .symbols
 7632                    .into_iter()
 7633                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7634                    .collect::<Vec<_>>();
 7635                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7636                    .await;
 7637                Ok(symbols)
 7638            })
 7639        } else if let Some(local) = self.as_local() {
 7640            struct WorkspaceSymbolsResult {
 7641                server_id: LanguageServerId,
 7642                lsp_adapter: Arc<CachedLspAdapter>,
 7643                worktree: WeakEntity<Worktree>,
 7644                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7645            }
 7646
 7647            let mut requests = Vec::new();
 7648            let mut requested_servers = BTreeSet::new();
 7649            for (seed, state) in local.language_server_ids.iter() {
 7650                let Some(worktree_handle) = self
 7651                    .worktree_store
 7652                    .read(cx)
 7653                    .worktree_for_id(seed.worktree_id, cx)
 7654                else {
 7655                    continue;
 7656                };
 7657                let worktree = worktree_handle.read(cx);
 7658                if !worktree.is_visible() {
 7659                    continue;
 7660                }
 7661
 7662                if !requested_servers.insert(state.id) {
 7663                    continue;
 7664                }
 7665
 7666                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7667                    Some(LanguageServerState::Running {
 7668                        adapter, server, ..
 7669                    }) => (adapter.clone(), server),
 7670
 7671                    _ => continue,
 7672                };
 7673                let supports_workspace_symbol_request =
 7674                    match server.capabilities().workspace_symbol_provider {
 7675                        Some(OneOf::Left(supported)) => supported,
 7676                        Some(OneOf::Right(_)) => true,
 7677                        None => false,
 7678                    };
 7679                if !supports_workspace_symbol_request {
 7680                    continue;
 7681                }
 7682                let worktree_handle = worktree_handle.clone();
 7683                let server_id = server.server_id();
 7684                requests.push(
 7685                        server
 7686                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7687                                lsp::WorkspaceSymbolParams {
 7688                                    query: query.to_string(),
 7689                                    ..Default::default()
 7690                                },
 7691                            )
 7692                            .map(move |response| {
 7693                                let lsp_symbols = response.into_response()
 7694                                    .context("workspace symbols request")
 7695                                    .log_err()
 7696                                    .flatten()
 7697                                    .map(|symbol_response| match symbol_response {
 7698                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7699                                            flat_responses.into_iter().map(|lsp_symbol| {
 7700                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7701                                            }).collect::<Vec<_>>()
 7702                                        }
 7703                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7704                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7705                                                let location = match lsp_symbol.location {
 7706                                                    OneOf::Left(location) => location,
 7707                                                    OneOf::Right(_) => {
 7708                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7709                                                        return None
 7710                                                    }
 7711                                                };
 7712                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7713                                            }).collect::<Vec<_>>()
 7714                                        }
 7715                                    }).unwrap_or_default();
 7716
 7717                                WorkspaceSymbolsResult {
 7718                                    server_id,
 7719                                    lsp_adapter,
 7720                                    worktree: worktree_handle.downgrade(),
 7721                                    lsp_symbols,
 7722                                }
 7723                            }),
 7724                    );
 7725            }
 7726
 7727            cx.spawn(async move |this, cx| {
 7728                let responses = futures::future::join_all(requests).await;
 7729                let this = match this.upgrade() {
 7730                    Some(this) => this,
 7731                    None => return Ok(Vec::new()),
 7732                };
 7733
 7734                let mut symbols = Vec::new();
 7735                for result in responses {
 7736                    let core_symbols = this.update(cx, |this, cx| {
 7737                        result
 7738                            .lsp_symbols
 7739                            .into_iter()
 7740                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7741                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7742                                let source_worktree = result.worktree.upgrade()?;
 7743                                let source_worktree_id = source_worktree.read(cx).id();
 7744
 7745                                let path = if let Some((tree, rel_path)) =
 7746                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7747                                {
 7748                                    let worktree_id = tree.read(cx).id();
 7749                                    SymbolLocation::InProject(ProjectPath {
 7750                                        worktree_id,
 7751                                        path: rel_path,
 7752                                    })
 7753                                } else {
 7754                                    SymbolLocation::OutsideProject {
 7755                                        signature: this.symbol_signature(&abs_path),
 7756                                        abs_path: abs_path.into(),
 7757                                    }
 7758                                };
 7759
 7760                                Some(CoreSymbol {
 7761                                    source_language_server_id: result.server_id,
 7762                                    language_server_name: result.lsp_adapter.name.clone(),
 7763                                    source_worktree_id,
 7764                                    path,
 7765                                    kind: symbol_kind,
 7766                                    name: symbol_name,
 7767                                    range: range_from_lsp(symbol_location.range),
 7768                                })
 7769                            })
 7770                            .collect()
 7771                    })?;
 7772
 7773                    populate_labels_for_symbols(
 7774                        core_symbols,
 7775                        &language_registry,
 7776                        Some(result.lsp_adapter),
 7777                        &mut symbols,
 7778                    )
 7779                    .await;
 7780                }
 7781
 7782                Ok(symbols)
 7783            })
 7784        } else {
 7785            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7786        }
 7787    }
 7788
 7789    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7790        let mut summary = DiagnosticSummary::default();
 7791        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7792            summary.error_count += path_summary.error_count;
 7793            summary.warning_count += path_summary.warning_count;
 7794        }
 7795        summary
 7796    }
 7797
 7798    /// Returns the diagnostic summary for a specific project path.
 7799    pub fn diagnostic_summary_for_path(
 7800        &self,
 7801        project_path: &ProjectPath,
 7802        _: &App,
 7803    ) -> DiagnosticSummary {
 7804        if let Some(summaries) = self
 7805            .diagnostic_summaries
 7806            .get(&project_path.worktree_id)
 7807            .and_then(|map| map.get(&project_path.path))
 7808        {
 7809            let (error_count, warning_count) = summaries.iter().fold(
 7810                (0, 0),
 7811                |(error_count, warning_count), (_language_server_id, summary)| {
 7812                    (
 7813                        error_count + summary.error_count,
 7814                        warning_count + summary.warning_count,
 7815                    )
 7816                },
 7817            );
 7818
 7819            DiagnosticSummary {
 7820                error_count,
 7821                warning_count,
 7822            }
 7823        } else {
 7824            DiagnosticSummary::default()
 7825        }
 7826    }
 7827
 7828    pub fn diagnostic_summaries<'a>(
 7829        &'a self,
 7830        include_ignored: bool,
 7831        cx: &'a App,
 7832    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7833        self.worktree_store
 7834            .read(cx)
 7835            .visible_worktrees(cx)
 7836            .filter_map(|worktree| {
 7837                let worktree = worktree.read(cx);
 7838                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7839            })
 7840            .flat_map(move |(worktree, summaries)| {
 7841                let worktree_id = worktree.id();
 7842                summaries
 7843                    .iter()
 7844                    .filter(move |(path, _)| {
 7845                        include_ignored
 7846                            || worktree
 7847                                .entry_for_path(path.as_ref())
 7848                                .is_some_and(|entry| !entry.is_ignored)
 7849                    })
 7850                    .flat_map(move |(path, summaries)| {
 7851                        summaries.iter().map(move |(server_id, summary)| {
 7852                            (
 7853                                ProjectPath {
 7854                                    worktree_id,
 7855                                    path: path.clone(),
 7856                                },
 7857                                *server_id,
 7858                                *summary,
 7859                            )
 7860                        })
 7861                    })
 7862            })
 7863    }
 7864
 7865    pub fn on_buffer_edited(
 7866        &mut self,
 7867        buffer: Entity<Buffer>,
 7868        cx: &mut Context<Self>,
 7869    ) -> Option<()> {
 7870        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7871            Some(
 7872                self.as_local()?
 7873                    .language_servers_for_buffer(buffer, cx)
 7874                    .map(|i| i.1.clone())
 7875                    .collect(),
 7876            )
 7877        })?;
 7878
 7879        let buffer = buffer.read(cx);
 7880        let file = File::from_dyn(buffer.file())?;
 7881        let abs_path = file.as_local()?.abs_path(cx);
 7882        let uri = lsp::Uri::from_file_path(&abs_path)
 7883            .ok()
 7884            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7885            .log_err()?;
 7886        let next_snapshot = buffer.text_snapshot();
 7887        for language_server in language_servers {
 7888            let language_server = language_server.clone();
 7889
 7890            let buffer_snapshots = self
 7891                .as_local_mut()?
 7892                .buffer_snapshots
 7893                .get_mut(&buffer.remote_id())
 7894                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7895            let previous_snapshot = buffer_snapshots.last()?;
 7896
 7897            let build_incremental_change = || {
 7898                buffer
 7899                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7900                        previous_snapshot.snapshot.version(),
 7901                    )
 7902                    .map(|edit| {
 7903                        let edit_start = edit.new.start.0;
 7904                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7905                        let new_text = next_snapshot
 7906                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7907                            .collect();
 7908                        lsp::TextDocumentContentChangeEvent {
 7909                            range: Some(lsp::Range::new(
 7910                                point_to_lsp(edit_start),
 7911                                point_to_lsp(edit_end),
 7912                            )),
 7913                            range_length: None,
 7914                            text: new_text,
 7915                        }
 7916                    })
 7917                    .collect()
 7918            };
 7919
 7920            let document_sync_kind = language_server
 7921                .capabilities()
 7922                .text_document_sync
 7923                .as_ref()
 7924                .and_then(|sync| match sync {
 7925                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7926                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7927                });
 7928
 7929            let content_changes: Vec<_> = match document_sync_kind {
 7930                Some(lsp::TextDocumentSyncKind::FULL) => {
 7931                    vec![lsp::TextDocumentContentChangeEvent {
 7932                        range: None,
 7933                        range_length: None,
 7934                        text: next_snapshot.text(),
 7935                    }]
 7936                }
 7937                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7938                _ => {
 7939                    #[cfg(any(test, feature = "test-support"))]
 7940                    {
 7941                        build_incremental_change()
 7942                    }
 7943
 7944                    #[cfg(not(any(test, feature = "test-support")))]
 7945                    {
 7946                        continue;
 7947                    }
 7948                }
 7949            };
 7950
 7951            let next_version = previous_snapshot.version + 1;
 7952            buffer_snapshots.push(LspBufferSnapshot {
 7953                version: next_version,
 7954                snapshot: next_snapshot.clone(),
 7955            });
 7956
 7957            language_server
 7958                .notify::<lsp::notification::DidChangeTextDocument>(
 7959                    lsp::DidChangeTextDocumentParams {
 7960                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7961                            uri.clone(),
 7962                            next_version,
 7963                        ),
 7964                        content_changes,
 7965                    },
 7966                )
 7967                .ok();
 7968            self.pull_workspace_diagnostics(language_server.server_id());
 7969        }
 7970
 7971        None
 7972    }
 7973
 7974    pub fn on_buffer_saved(
 7975        &mut self,
 7976        buffer: Entity<Buffer>,
 7977        cx: &mut Context<Self>,
 7978    ) -> Option<()> {
 7979        let file = File::from_dyn(buffer.read(cx).file())?;
 7980        let worktree_id = file.worktree_id(cx);
 7981        let abs_path = file.as_local()?.abs_path(cx);
 7982        let text_document = lsp::TextDocumentIdentifier {
 7983            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7984        };
 7985        let local = self.as_local()?;
 7986
 7987        for server in local.language_servers_for_worktree(worktree_id) {
 7988            if let Some(include_text) = include_text(server.as_ref()) {
 7989                let text = if include_text {
 7990                    Some(buffer.read(cx).text())
 7991                } else {
 7992                    None
 7993                };
 7994                server
 7995                    .notify::<lsp::notification::DidSaveTextDocument>(
 7996                        lsp::DidSaveTextDocumentParams {
 7997                            text_document: text_document.clone(),
 7998                            text,
 7999                        },
 8000                    )
 8001                    .ok();
 8002            }
 8003        }
 8004
 8005        let language_servers = buffer.update(cx, |buffer, cx| {
 8006            local.language_server_ids_for_buffer(buffer, cx)
 8007        });
 8008        for language_server_id in language_servers {
 8009            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8010        }
 8011
 8012        None
 8013    }
 8014
 8015    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8016        maybe!(async move {
 8017            let mut refreshed_servers = HashSet::default();
 8018            let servers = lsp_store
 8019                .update(cx, |lsp_store, cx| {
 8020                    let local = lsp_store.as_local()?;
 8021
 8022                    let servers = local
 8023                        .language_server_ids
 8024                        .iter()
 8025                        .filter_map(|(seed, state)| {
 8026                            let worktree = lsp_store
 8027                                .worktree_store
 8028                                .read(cx)
 8029                                .worktree_for_id(seed.worktree_id, cx);
 8030                            let delegate: Arc<dyn LspAdapterDelegate> =
 8031                                worktree.map(|worktree| {
 8032                                    LocalLspAdapterDelegate::new(
 8033                                        local.languages.clone(),
 8034                                        &local.environment,
 8035                                        cx.weak_entity(),
 8036                                        &worktree,
 8037                                        local.http_client.clone(),
 8038                                        local.fs.clone(),
 8039                                        cx,
 8040                                    )
 8041                                })?;
 8042                            let server_id = state.id;
 8043
 8044                            let states = local.language_servers.get(&server_id)?;
 8045
 8046                            match states {
 8047                                LanguageServerState::Starting { .. } => None,
 8048                                LanguageServerState::Running {
 8049                                    adapter, server, ..
 8050                                } => {
 8051                                    let adapter = adapter.clone();
 8052                                    let server = server.clone();
 8053                                    refreshed_servers.insert(server.name());
 8054                                    let toolchain = seed.toolchain.clone();
 8055                                    Some(cx.spawn(async move |_, cx| {
 8056                                        let settings =
 8057                                            LocalLspStore::workspace_configuration_for_adapter(
 8058                                                adapter.adapter.clone(),
 8059                                                &delegate,
 8060                                                toolchain,
 8061                                                None,
 8062                                                cx,
 8063                                            )
 8064                                            .await
 8065                                            .ok()?;
 8066                                        server
 8067                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8068                                                lsp::DidChangeConfigurationParams { settings },
 8069                                            )
 8070                                            .ok()?;
 8071                                        Some(())
 8072                                    }))
 8073                                }
 8074                            }
 8075                        })
 8076                        .collect::<Vec<_>>();
 8077
 8078                    Some(servers)
 8079                })
 8080                .ok()
 8081                .flatten()?;
 8082
 8083            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8084            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8085            // to stop and unregister its language server wrapper.
 8086            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8087            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8088            let _: Vec<Option<()>> = join_all(servers).await;
 8089
 8090            Some(())
 8091        })
 8092        .await;
 8093    }
 8094
 8095    fn maintain_workspace_config(
 8096        external_refresh_requests: watch::Receiver<()>,
 8097        cx: &mut Context<Self>,
 8098    ) -> Task<Result<()>> {
 8099        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8100        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8101
 8102        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8103            *settings_changed_tx.borrow_mut() = ();
 8104        });
 8105
 8106        let mut joint_future =
 8107            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8108        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8109        // - 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).
 8110        // - 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.
 8111        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8112        // - 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,
 8113        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8114        cx.spawn(async move |this, cx| {
 8115            while let Some(()) = joint_future.next().await {
 8116                this.update(cx, |this, cx| {
 8117                    this.refresh_server_tree(cx);
 8118                })
 8119                .ok();
 8120
 8121                Self::refresh_workspace_configurations(&this, cx).await;
 8122            }
 8123
 8124            drop(settings_observation);
 8125            anyhow::Ok(())
 8126        })
 8127    }
 8128
 8129    pub fn running_language_servers_for_local_buffer<'a>(
 8130        &'a self,
 8131        buffer: &Buffer,
 8132        cx: &mut App,
 8133    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8134        let local = self.as_local();
 8135        let language_server_ids = local
 8136            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8137            .unwrap_or_default();
 8138
 8139        language_server_ids
 8140            .into_iter()
 8141            .filter_map(
 8142                move |server_id| match local?.language_servers.get(&server_id)? {
 8143                    LanguageServerState::Running {
 8144                        adapter, server, ..
 8145                    } => Some((adapter, server)),
 8146                    _ => None,
 8147                },
 8148            )
 8149    }
 8150
 8151    pub fn language_servers_for_local_buffer(
 8152        &self,
 8153        buffer: &Buffer,
 8154        cx: &mut App,
 8155    ) -> Vec<LanguageServerId> {
 8156        let local = self.as_local();
 8157        local
 8158            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8159            .unwrap_or_default()
 8160    }
 8161
 8162    pub fn language_server_for_local_buffer<'a>(
 8163        &'a self,
 8164        buffer: &'a Buffer,
 8165        server_id: LanguageServerId,
 8166        cx: &'a mut App,
 8167    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8168        self.as_local()?
 8169            .language_servers_for_buffer(buffer, cx)
 8170            .find(|(_, s)| s.server_id() == server_id)
 8171    }
 8172
 8173    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8174        self.diagnostic_summaries.remove(&id_to_remove);
 8175        if let Some(local) = self.as_local_mut() {
 8176            let to_remove = local.remove_worktree(id_to_remove, cx);
 8177            for server in to_remove {
 8178                self.language_server_statuses.remove(&server);
 8179            }
 8180        }
 8181    }
 8182
 8183    pub fn shared(
 8184        &mut self,
 8185        project_id: u64,
 8186        downstream_client: AnyProtoClient,
 8187        _: &mut Context<Self>,
 8188    ) {
 8189        self.downstream_client = Some((downstream_client.clone(), project_id));
 8190
 8191        for (server_id, status) in &self.language_server_statuses {
 8192            if let Some(server) = self.language_server_for_id(*server_id) {
 8193                downstream_client
 8194                    .send(proto::StartLanguageServer {
 8195                        project_id,
 8196                        server: Some(proto::LanguageServer {
 8197                            id: server_id.to_proto(),
 8198                            name: status.name.to_string(),
 8199                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8200                        }),
 8201                        capabilities: serde_json::to_string(&server.capabilities())
 8202                            .expect("serializing server LSP capabilities"),
 8203                    })
 8204                    .log_err();
 8205            }
 8206        }
 8207    }
 8208
 8209    pub fn disconnected_from_host(&mut self) {
 8210        self.downstream_client.take();
 8211    }
 8212
 8213    pub fn disconnected_from_ssh_remote(&mut self) {
 8214        if let LspStoreMode::Remote(RemoteLspStore {
 8215            upstream_client, ..
 8216        }) = &mut self.mode
 8217        {
 8218            upstream_client.take();
 8219        }
 8220    }
 8221
 8222    pub(crate) fn set_language_server_statuses_from_proto(
 8223        &mut self,
 8224        project: WeakEntity<Project>,
 8225        language_servers: Vec<proto::LanguageServer>,
 8226        server_capabilities: Vec<String>,
 8227        cx: &mut Context<Self>,
 8228    ) {
 8229        let lsp_logs = cx
 8230            .try_global::<GlobalLogStore>()
 8231            .map(|lsp_store| lsp_store.0.clone());
 8232
 8233        self.language_server_statuses = language_servers
 8234            .into_iter()
 8235            .zip(server_capabilities)
 8236            .map(|(server, server_capabilities)| {
 8237                let server_id = LanguageServerId(server.id as usize);
 8238                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8239                    self.lsp_server_capabilities
 8240                        .insert(server_id, server_capabilities);
 8241                }
 8242
 8243                let name = LanguageServerName::from_proto(server.name);
 8244                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8245
 8246                if let Some(lsp_logs) = &lsp_logs {
 8247                    lsp_logs.update(cx, |lsp_logs, cx| {
 8248                        lsp_logs.add_language_server(
 8249                            // Only remote clients get their language servers set from proto
 8250                            LanguageServerKind::Remote {
 8251                                project: project.clone(),
 8252                            },
 8253                            server_id,
 8254                            Some(name.clone()),
 8255                            worktree,
 8256                            None,
 8257                            cx,
 8258                        );
 8259                    });
 8260                }
 8261
 8262                (
 8263                    server_id,
 8264                    LanguageServerStatus {
 8265                        name,
 8266                        pending_work: Default::default(),
 8267                        has_pending_diagnostic_updates: false,
 8268                        progress_tokens: Default::default(),
 8269                        worktree,
 8270                        binary: None,
 8271                        configuration: None,
 8272                        workspace_folders: BTreeSet::new(),
 8273                    },
 8274                )
 8275            })
 8276            .collect();
 8277    }
 8278
 8279    #[cfg(test)]
 8280    pub fn update_diagnostic_entries(
 8281        &mut self,
 8282        server_id: LanguageServerId,
 8283        abs_path: PathBuf,
 8284        result_id: Option<SharedString>,
 8285        version: Option<i32>,
 8286        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8287        cx: &mut Context<Self>,
 8288    ) -> anyhow::Result<()> {
 8289        self.merge_diagnostic_entries(
 8290            vec![DocumentDiagnosticsUpdate {
 8291                diagnostics: DocumentDiagnostics {
 8292                    diagnostics,
 8293                    document_abs_path: abs_path,
 8294                    version,
 8295                },
 8296                result_id,
 8297                server_id,
 8298                disk_based_sources: Cow::Borrowed(&[]),
 8299                registration_id: None,
 8300            }],
 8301            |_, _, _| false,
 8302            cx,
 8303        )?;
 8304        Ok(())
 8305    }
 8306
 8307    pub fn merge_diagnostic_entries<'a>(
 8308        &mut self,
 8309        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8310        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8311        cx: &mut Context<Self>,
 8312    ) -> anyhow::Result<()> {
 8313        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8314        let mut updated_diagnostics_paths = HashMap::default();
 8315        for mut update in diagnostic_updates {
 8316            let abs_path = &update.diagnostics.document_abs_path;
 8317            let server_id = update.server_id;
 8318            let Some((worktree, relative_path)) =
 8319                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8320            else {
 8321                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8322                return Ok(());
 8323            };
 8324
 8325            let worktree_id = worktree.read(cx).id();
 8326            let project_path = ProjectPath {
 8327                worktree_id,
 8328                path: relative_path,
 8329            };
 8330
 8331            let document_uri = lsp::Uri::from_file_path(abs_path)
 8332                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8333            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8334                let snapshot = buffer_handle.read(cx).snapshot();
 8335                let buffer = buffer_handle.read(cx);
 8336                let reused_diagnostics = buffer
 8337                    .buffer_diagnostics(Some(server_id))
 8338                    .iter()
 8339                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8340                    .map(|v| {
 8341                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8342                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8343                        DiagnosticEntry {
 8344                            range: start..end,
 8345                            diagnostic: v.diagnostic.clone(),
 8346                        }
 8347                    })
 8348                    .collect::<Vec<_>>();
 8349
 8350                self.as_local_mut()
 8351                    .context("cannot merge diagnostics on a remote LspStore")?
 8352                    .update_buffer_diagnostics(
 8353                        &buffer_handle,
 8354                        server_id,
 8355                        Some(update.registration_id),
 8356                        update.result_id,
 8357                        update.diagnostics.version,
 8358                        update.diagnostics.diagnostics.clone(),
 8359                        reused_diagnostics.clone(),
 8360                        cx,
 8361                    )?;
 8362
 8363                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8364            } else if let Some(local) = self.as_local() {
 8365                let reused_diagnostics = local
 8366                    .diagnostics
 8367                    .get(&worktree_id)
 8368                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8369                    .and_then(|diagnostics_by_server_id| {
 8370                        diagnostics_by_server_id
 8371                            .binary_search_by_key(&server_id, |e| e.0)
 8372                            .ok()
 8373                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8374                    })
 8375                    .into_iter()
 8376                    .flatten()
 8377                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8378
 8379                update
 8380                    .diagnostics
 8381                    .diagnostics
 8382                    .extend(reused_diagnostics.cloned());
 8383            }
 8384
 8385            let updated = worktree.update(cx, |worktree, cx| {
 8386                self.update_worktree_diagnostics(
 8387                    worktree.id(),
 8388                    server_id,
 8389                    project_path.path.clone(),
 8390                    update.diagnostics.diagnostics,
 8391                    cx,
 8392                )
 8393            })?;
 8394            match updated {
 8395                ControlFlow::Continue(new_summary) => {
 8396                    if let Some((project_id, new_summary)) = new_summary {
 8397                        match &mut diagnostics_summary {
 8398                            Some(diagnostics_summary) => {
 8399                                diagnostics_summary
 8400                                    .more_summaries
 8401                                    .push(proto::DiagnosticSummary {
 8402                                        path: project_path.path.as_ref().to_proto(),
 8403                                        language_server_id: server_id.0 as u64,
 8404                                        error_count: new_summary.error_count,
 8405                                        warning_count: new_summary.warning_count,
 8406                                    })
 8407                            }
 8408                            None => {
 8409                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8410                                    project_id,
 8411                                    worktree_id: worktree_id.to_proto(),
 8412                                    summary: Some(proto::DiagnosticSummary {
 8413                                        path: project_path.path.as_ref().to_proto(),
 8414                                        language_server_id: server_id.0 as u64,
 8415                                        error_count: new_summary.error_count,
 8416                                        warning_count: new_summary.warning_count,
 8417                                    }),
 8418                                    more_summaries: Vec::new(),
 8419                                })
 8420                            }
 8421                        }
 8422                    }
 8423                    updated_diagnostics_paths
 8424                        .entry(server_id)
 8425                        .or_insert_with(Vec::new)
 8426                        .push(project_path);
 8427                }
 8428                ControlFlow::Break(()) => {}
 8429            }
 8430        }
 8431
 8432        if let Some((diagnostics_summary, (downstream_client, _))) =
 8433            diagnostics_summary.zip(self.downstream_client.as_ref())
 8434        {
 8435            downstream_client.send(diagnostics_summary).log_err();
 8436        }
 8437        for (server_id, paths) in updated_diagnostics_paths {
 8438            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8439        }
 8440        Ok(())
 8441    }
 8442
 8443    fn update_worktree_diagnostics(
 8444        &mut self,
 8445        worktree_id: WorktreeId,
 8446        server_id: LanguageServerId,
 8447        path_in_worktree: Arc<RelPath>,
 8448        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8449        _: &mut Context<Worktree>,
 8450    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8451        let local = match &mut self.mode {
 8452            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8453            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8454        };
 8455
 8456        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8457        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8458        let summaries_by_server_id = summaries_for_tree
 8459            .entry(path_in_worktree.clone())
 8460            .or_default();
 8461
 8462        let old_summary = summaries_by_server_id
 8463            .remove(&server_id)
 8464            .unwrap_or_default();
 8465
 8466        let new_summary = DiagnosticSummary::new(&diagnostics);
 8467        if diagnostics.is_empty() {
 8468            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8469            {
 8470                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8471                    diagnostics_by_server_id.remove(ix);
 8472                }
 8473                if diagnostics_by_server_id.is_empty() {
 8474                    diagnostics_for_tree.remove(&path_in_worktree);
 8475                }
 8476            }
 8477        } else {
 8478            summaries_by_server_id.insert(server_id, new_summary);
 8479            let diagnostics_by_server_id = diagnostics_for_tree
 8480                .entry(path_in_worktree.clone())
 8481                .or_default();
 8482            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8483                Ok(ix) => {
 8484                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8485                }
 8486                Err(ix) => {
 8487                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8488                }
 8489            }
 8490        }
 8491
 8492        if !old_summary.is_empty() || !new_summary.is_empty() {
 8493            if let Some((_, project_id)) = &self.downstream_client {
 8494                Ok(ControlFlow::Continue(Some((
 8495                    *project_id,
 8496                    proto::DiagnosticSummary {
 8497                        path: path_in_worktree.to_proto(),
 8498                        language_server_id: server_id.0 as u64,
 8499                        error_count: new_summary.error_count as u32,
 8500                        warning_count: new_summary.warning_count as u32,
 8501                    },
 8502                ))))
 8503            } else {
 8504                Ok(ControlFlow::Continue(None))
 8505            }
 8506        } else {
 8507            Ok(ControlFlow::Break(()))
 8508        }
 8509    }
 8510
 8511    pub fn open_buffer_for_symbol(
 8512        &mut self,
 8513        symbol: &Symbol,
 8514        cx: &mut Context<Self>,
 8515    ) -> Task<Result<Entity<Buffer>>> {
 8516        if let Some((client, project_id)) = self.upstream_client() {
 8517            let request = client.request(proto::OpenBufferForSymbol {
 8518                project_id,
 8519                symbol: Some(Self::serialize_symbol(symbol)),
 8520            });
 8521            cx.spawn(async move |this, cx| {
 8522                let response = request.await?;
 8523                let buffer_id = BufferId::new(response.buffer_id)?;
 8524                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8525                    .await
 8526            })
 8527        } else if let Some(local) = self.as_local() {
 8528            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8529                seed.worktree_id == symbol.source_worktree_id
 8530                    && state.id == symbol.source_language_server_id
 8531                    && symbol.language_server_name == seed.name
 8532            });
 8533            if !is_valid {
 8534                return Task::ready(Err(anyhow!(
 8535                    "language server for worktree and language not found"
 8536                )));
 8537            };
 8538
 8539            let symbol_abs_path = match &symbol.path {
 8540                SymbolLocation::InProject(project_path) => self
 8541                    .worktree_store
 8542                    .read(cx)
 8543                    .absolutize(&project_path, cx)
 8544                    .context("no such worktree"),
 8545                SymbolLocation::OutsideProject {
 8546                    abs_path,
 8547                    signature: _,
 8548                } => Ok(abs_path.to_path_buf()),
 8549            };
 8550            let symbol_abs_path = match symbol_abs_path {
 8551                Ok(abs_path) => abs_path,
 8552                Err(err) => return Task::ready(Err(err)),
 8553            };
 8554            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8555                uri
 8556            } else {
 8557                return Task::ready(Err(anyhow!("invalid symbol path")));
 8558            };
 8559
 8560            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8561        } else {
 8562            Task::ready(Err(anyhow!("no upstream client or local store")))
 8563        }
 8564    }
 8565
 8566    pub(crate) fn open_local_buffer_via_lsp(
 8567        &mut self,
 8568        abs_path: lsp::Uri,
 8569        language_server_id: LanguageServerId,
 8570        cx: &mut Context<Self>,
 8571    ) -> Task<Result<Entity<Buffer>>> {
 8572        cx.spawn(async move |lsp_store, cx| {
 8573            // Escape percent-encoded string.
 8574            let current_scheme = abs_path.scheme().to_owned();
 8575            // Uri is immutable, so we can't modify the scheme
 8576
 8577            let abs_path = abs_path
 8578                .to_file_path()
 8579                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8580            let p = abs_path.clone();
 8581            let yarn_worktree = lsp_store
 8582                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8583                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8584                        cx.spawn(async move |this, cx| {
 8585                            let t = this
 8586                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8587                                .ok()?;
 8588                            t.await
 8589                        })
 8590                    }),
 8591                    None => Task::ready(None),
 8592                })?
 8593                .await;
 8594            let (worktree_root_target, known_relative_path) =
 8595                if let Some((zip_root, relative_path)) = yarn_worktree {
 8596                    (zip_root, Some(relative_path))
 8597                } else {
 8598                    (Arc::<Path>::from(abs_path.as_path()), None)
 8599                };
 8600            let (worktree, relative_path) = if let Some(result) =
 8601                lsp_store.update(cx, |lsp_store, cx| {
 8602                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8603                        worktree_store.find_worktree(&worktree_root_target, cx)
 8604                    })
 8605                })? {
 8606                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8607                (result.0, relative_path)
 8608            } else {
 8609                let worktree = lsp_store
 8610                    .update(cx, |lsp_store, cx| {
 8611                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8612                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8613                        })
 8614                    })?
 8615                    .await?;
 8616                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8617                    lsp_store
 8618                        .update(cx, |lsp_store, cx| {
 8619                            if let Some(local) = lsp_store.as_local_mut() {
 8620                                local.register_language_server_for_invisible_worktree(
 8621                                    &worktree,
 8622                                    language_server_id,
 8623                                    cx,
 8624                                )
 8625                            }
 8626                        })
 8627                        .ok();
 8628                }
 8629                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8630                let relative_path = if let Some(known_path) = known_relative_path {
 8631                    known_path
 8632                } else {
 8633                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8634                        .into_arc()
 8635                };
 8636                (worktree, relative_path)
 8637            };
 8638            let project_path = ProjectPath {
 8639                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8640                path: relative_path,
 8641            };
 8642            lsp_store
 8643                .update(cx, |lsp_store, cx| {
 8644                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8645                        buffer_store.open_buffer(project_path, cx)
 8646                    })
 8647                })?
 8648                .await
 8649        })
 8650    }
 8651
 8652    fn request_multiple_lsp_locally<P, R>(
 8653        &mut self,
 8654        buffer: &Entity<Buffer>,
 8655        position: Option<P>,
 8656        request: R,
 8657        cx: &mut Context<Self>,
 8658    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8659    where
 8660        P: ToOffset,
 8661        R: LspCommand + Clone,
 8662        <R::LspRequest as lsp::request::Request>::Result: Send,
 8663        <R::LspRequest as lsp::request::Request>::Params: Send,
 8664    {
 8665        let Some(local) = self.as_local() else {
 8666            return Task::ready(Vec::new());
 8667        };
 8668
 8669        let snapshot = buffer.read(cx).snapshot();
 8670        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8671
 8672        let server_ids = buffer.update(cx, |buffer, cx| {
 8673            local
 8674                .language_servers_for_buffer(buffer, cx)
 8675                .filter(|(adapter, _)| {
 8676                    scope
 8677                        .as_ref()
 8678                        .map(|scope| scope.language_allowed(&adapter.name))
 8679                        .unwrap_or(true)
 8680                })
 8681                .map(|(_, server)| server.server_id())
 8682                .filter(|server_id| {
 8683                    self.as_local().is_none_or(|local| {
 8684                        local
 8685                            .buffers_opened_in_servers
 8686                            .get(&snapshot.remote_id())
 8687                            .is_some_and(|servers| servers.contains(server_id))
 8688                    })
 8689                })
 8690                .collect::<Vec<_>>()
 8691        });
 8692
 8693        let mut response_results = server_ids
 8694            .into_iter()
 8695            .map(|server_id| {
 8696                let task = self.request_lsp(
 8697                    buffer.clone(),
 8698                    LanguageServerToQuery::Other(server_id),
 8699                    request.clone(),
 8700                    cx,
 8701                );
 8702                async move { (server_id, task.await) }
 8703            })
 8704            .collect::<FuturesUnordered<_>>();
 8705
 8706        cx.background_spawn(async move {
 8707            let mut responses = Vec::with_capacity(response_results.len());
 8708            while let Some((server_id, response_result)) = response_results.next().await {
 8709                match response_result {
 8710                    Ok(response) => responses.push((server_id, response)),
 8711                    // rust-analyzer likes to error with this when its still loading up
 8712                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8713                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8714                }
 8715            }
 8716            responses
 8717        })
 8718    }
 8719
 8720    async fn handle_lsp_get_completions(
 8721        this: Entity<Self>,
 8722        envelope: TypedEnvelope<proto::GetCompletions>,
 8723        mut cx: AsyncApp,
 8724    ) -> Result<proto::GetCompletionsResponse> {
 8725        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8726
 8727        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8728        let buffer_handle = this.update(&mut cx, |this, cx| {
 8729            this.buffer_store.read(cx).get_existing(buffer_id)
 8730        })??;
 8731        let request = GetCompletions::from_proto(
 8732            envelope.payload,
 8733            this.clone(),
 8734            buffer_handle.clone(),
 8735            cx.clone(),
 8736        )
 8737        .await?;
 8738
 8739        let server_to_query = match request.server_id {
 8740            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8741            None => LanguageServerToQuery::FirstCapable,
 8742        };
 8743
 8744        let response = this
 8745            .update(&mut cx, |this, cx| {
 8746                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8747            })?
 8748            .await?;
 8749        this.update(&mut cx, |this, cx| {
 8750            Ok(GetCompletions::response_to_proto(
 8751                response,
 8752                this,
 8753                sender_id,
 8754                &buffer_handle.read(cx).version(),
 8755                cx,
 8756            ))
 8757        })?
 8758    }
 8759
 8760    async fn handle_lsp_command<T: LspCommand>(
 8761        this: Entity<Self>,
 8762        envelope: TypedEnvelope<T::ProtoRequest>,
 8763        mut cx: AsyncApp,
 8764    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8765    where
 8766        <T::LspRequest as lsp::request::Request>::Params: Send,
 8767        <T::LspRequest as lsp::request::Request>::Result: Send,
 8768    {
 8769        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8770        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8771        let buffer_handle = this.update(&mut cx, |this, cx| {
 8772            this.buffer_store.read(cx).get_existing(buffer_id)
 8773        })??;
 8774        let request = T::from_proto(
 8775            envelope.payload,
 8776            this.clone(),
 8777            buffer_handle.clone(),
 8778            cx.clone(),
 8779        )
 8780        .await?;
 8781        let response = this
 8782            .update(&mut cx, |this, cx| {
 8783                this.request_lsp(
 8784                    buffer_handle.clone(),
 8785                    LanguageServerToQuery::FirstCapable,
 8786                    request,
 8787                    cx,
 8788                )
 8789            })?
 8790            .await?;
 8791        this.update(&mut cx, |this, cx| {
 8792            Ok(T::response_to_proto(
 8793                response,
 8794                this,
 8795                sender_id,
 8796                &buffer_handle.read(cx).version(),
 8797                cx,
 8798            ))
 8799        })?
 8800    }
 8801
 8802    async fn handle_lsp_query(
 8803        lsp_store: Entity<Self>,
 8804        envelope: TypedEnvelope<proto::LspQuery>,
 8805        mut cx: AsyncApp,
 8806    ) -> Result<proto::Ack> {
 8807        use proto::lsp_query::Request;
 8808        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8809        let lsp_query = envelope.payload;
 8810        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8811        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8812        match lsp_query.request.context("invalid LSP query request")? {
 8813            Request::GetReferences(get_references) => {
 8814                let position = get_references.position.clone().and_then(deserialize_anchor);
 8815                Self::query_lsp_locally::<GetReferences>(
 8816                    lsp_store,
 8817                    server_id,
 8818                    sender_id,
 8819                    lsp_request_id,
 8820                    get_references,
 8821                    position,
 8822                    &mut cx,
 8823                )
 8824                .await?;
 8825            }
 8826            Request::GetDocumentColor(get_document_color) => {
 8827                Self::query_lsp_locally::<GetDocumentColor>(
 8828                    lsp_store,
 8829                    server_id,
 8830                    sender_id,
 8831                    lsp_request_id,
 8832                    get_document_color,
 8833                    None,
 8834                    &mut cx,
 8835                )
 8836                .await?;
 8837            }
 8838            Request::GetHover(get_hover) => {
 8839                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8840                Self::query_lsp_locally::<GetHover>(
 8841                    lsp_store,
 8842                    server_id,
 8843                    sender_id,
 8844                    lsp_request_id,
 8845                    get_hover,
 8846                    position,
 8847                    &mut cx,
 8848                )
 8849                .await?;
 8850            }
 8851            Request::GetCodeActions(get_code_actions) => {
 8852                Self::query_lsp_locally::<GetCodeActions>(
 8853                    lsp_store,
 8854                    server_id,
 8855                    sender_id,
 8856                    lsp_request_id,
 8857                    get_code_actions,
 8858                    None,
 8859                    &mut cx,
 8860                )
 8861                .await?;
 8862            }
 8863            Request::GetSignatureHelp(get_signature_help) => {
 8864                let position = get_signature_help
 8865                    .position
 8866                    .clone()
 8867                    .and_then(deserialize_anchor);
 8868                Self::query_lsp_locally::<GetSignatureHelp>(
 8869                    lsp_store,
 8870                    server_id,
 8871                    sender_id,
 8872                    lsp_request_id,
 8873                    get_signature_help,
 8874                    position,
 8875                    &mut cx,
 8876                )
 8877                .await?;
 8878            }
 8879            Request::GetCodeLens(get_code_lens) => {
 8880                Self::query_lsp_locally::<GetCodeLens>(
 8881                    lsp_store,
 8882                    server_id,
 8883                    sender_id,
 8884                    lsp_request_id,
 8885                    get_code_lens,
 8886                    None,
 8887                    &mut cx,
 8888                )
 8889                .await?;
 8890            }
 8891            Request::GetDefinition(get_definition) => {
 8892                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8893                Self::query_lsp_locally::<GetDefinitions>(
 8894                    lsp_store,
 8895                    server_id,
 8896                    sender_id,
 8897                    lsp_request_id,
 8898                    get_definition,
 8899                    position,
 8900                    &mut cx,
 8901                )
 8902                .await?;
 8903            }
 8904            Request::GetDeclaration(get_declaration) => {
 8905                let position = get_declaration
 8906                    .position
 8907                    .clone()
 8908                    .and_then(deserialize_anchor);
 8909                Self::query_lsp_locally::<GetDeclarations>(
 8910                    lsp_store,
 8911                    server_id,
 8912                    sender_id,
 8913                    lsp_request_id,
 8914                    get_declaration,
 8915                    position,
 8916                    &mut cx,
 8917                )
 8918                .await?;
 8919            }
 8920            Request::GetTypeDefinition(get_type_definition) => {
 8921                let position = get_type_definition
 8922                    .position
 8923                    .clone()
 8924                    .and_then(deserialize_anchor);
 8925                Self::query_lsp_locally::<GetTypeDefinitions>(
 8926                    lsp_store,
 8927                    server_id,
 8928                    sender_id,
 8929                    lsp_request_id,
 8930                    get_type_definition,
 8931                    position,
 8932                    &mut cx,
 8933                )
 8934                .await?;
 8935            }
 8936            Request::GetImplementation(get_implementation) => {
 8937                let position = get_implementation
 8938                    .position
 8939                    .clone()
 8940                    .and_then(deserialize_anchor);
 8941                Self::query_lsp_locally::<GetImplementations>(
 8942                    lsp_store,
 8943                    server_id,
 8944                    sender_id,
 8945                    lsp_request_id,
 8946                    get_implementation,
 8947                    position,
 8948                    &mut cx,
 8949                )
 8950                .await?;
 8951            }
 8952            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8953                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8954                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8955                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8956                    this.buffer_store.read(cx).get_existing(buffer_id)
 8957                })??;
 8958                buffer
 8959                    .update(&mut cx, |buffer, _| {
 8960                        buffer.wait_for_version(version.clone())
 8961                    })?
 8962                    .await?;
 8963                lsp_store.update(&mut cx, |lsp_store, cx| {
 8964                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8965                    let key = LspKey {
 8966                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8967                        server_queried: server_id,
 8968                    };
 8969                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8970                    ) {
 8971                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8972                            lsp_requests.clear();
 8973                        };
 8974                    }
 8975
 8976                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8977                    existing_queries.insert(
 8978                        lsp_request_id,
 8979                        cx.spawn(async move |lsp_store, cx| {
 8980                            let diagnostics_pull = lsp_store
 8981                                .update(cx, |lsp_store, cx| {
 8982                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8983                                })
 8984                                .ok();
 8985                            if let Some(diagnostics_pull) = diagnostics_pull {
 8986                                match diagnostics_pull.await {
 8987                                    Ok(()) => {}
 8988                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8989                                };
 8990                            }
 8991                        }),
 8992                    );
 8993                })?;
 8994            }
 8995            Request::InlayHints(inlay_hints) => {
 8996                let query_start = inlay_hints
 8997                    .start
 8998                    .clone()
 8999                    .and_then(deserialize_anchor)
 9000                    .context("invalid inlay hints range start")?;
 9001                let query_end = inlay_hints
 9002                    .end
 9003                    .clone()
 9004                    .and_then(deserialize_anchor)
 9005                    .context("invalid inlay hints range end")?;
 9006                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9007                    &lsp_store,
 9008                    server_id,
 9009                    lsp_request_id,
 9010                    &inlay_hints,
 9011                    query_start..query_end,
 9012                    &mut cx,
 9013                )
 9014                .await
 9015                .context("preparing inlay hints request")?;
 9016                Self::query_lsp_locally::<InlayHints>(
 9017                    lsp_store,
 9018                    server_id,
 9019                    sender_id,
 9020                    lsp_request_id,
 9021                    inlay_hints,
 9022                    None,
 9023                    &mut cx,
 9024                )
 9025                .await
 9026                .context("querying for inlay hints")?
 9027            }
 9028        }
 9029        Ok(proto::Ack {})
 9030    }
 9031
 9032    async fn handle_lsp_query_response(
 9033        lsp_store: Entity<Self>,
 9034        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9035        cx: AsyncApp,
 9036    ) -> Result<()> {
 9037        lsp_store.read_with(&cx, |lsp_store, _| {
 9038            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9039                upstream_client.handle_lsp_response(envelope.clone());
 9040            }
 9041        })?;
 9042        Ok(())
 9043    }
 9044
 9045    async fn handle_apply_code_action(
 9046        this: Entity<Self>,
 9047        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9048        mut cx: AsyncApp,
 9049    ) -> Result<proto::ApplyCodeActionResponse> {
 9050        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9051        let action =
 9052            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9053        let apply_code_action = this.update(&mut cx, |this, cx| {
 9054            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9055            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9056            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9057        })??;
 9058
 9059        let project_transaction = apply_code_action.await?;
 9060        let project_transaction = this.update(&mut cx, |this, cx| {
 9061            this.buffer_store.update(cx, |buffer_store, cx| {
 9062                buffer_store.serialize_project_transaction_for_peer(
 9063                    project_transaction,
 9064                    sender_id,
 9065                    cx,
 9066                )
 9067            })
 9068        })?;
 9069        Ok(proto::ApplyCodeActionResponse {
 9070            transaction: Some(project_transaction),
 9071        })
 9072    }
 9073
 9074    async fn handle_register_buffer_with_language_servers(
 9075        this: Entity<Self>,
 9076        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9077        mut cx: AsyncApp,
 9078    ) -> Result<proto::Ack> {
 9079        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9080        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9081        this.update(&mut cx, |this, cx| {
 9082            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9083                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9084                    project_id: upstream_project_id,
 9085                    buffer_id: buffer_id.to_proto(),
 9086                    only_servers: envelope.payload.only_servers,
 9087                });
 9088            }
 9089
 9090            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9091                anyhow::bail!("buffer is not open");
 9092            };
 9093
 9094            let handle = this.register_buffer_with_language_servers(
 9095                &buffer,
 9096                envelope
 9097                    .payload
 9098                    .only_servers
 9099                    .into_iter()
 9100                    .filter_map(|selector| {
 9101                        Some(match selector.selector? {
 9102                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9103                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9104                            }
 9105                            proto::language_server_selector::Selector::Name(name) => {
 9106                                LanguageServerSelector::Name(LanguageServerName(
 9107                                    SharedString::from(name),
 9108                                ))
 9109                            }
 9110                        })
 9111                    })
 9112                    .collect(),
 9113                false,
 9114                cx,
 9115            );
 9116            this.buffer_store().update(cx, |buffer_store, _| {
 9117                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9118            });
 9119
 9120            Ok(())
 9121        })??;
 9122        Ok(proto::Ack {})
 9123    }
 9124
 9125    async fn handle_rename_project_entry(
 9126        this: Entity<Self>,
 9127        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9128        mut cx: AsyncApp,
 9129    ) -> Result<proto::ProjectEntryResponse> {
 9130        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9131        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9132        let new_path =
 9133            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9134
 9135        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9136            .update(&mut cx, |this, cx| {
 9137                let (worktree, entry) = this
 9138                    .worktree_store
 9139                    .read(cx)
 9140                    .worktree_and_entry_for_id(entry_id, cx)?;
 9141                let new_worktree = this
 9142                    .worktree_store
 9143                    .read(cx)
 9144                    .worktree_for_id(new_worktree_id, cx)?;
 9145                Some((
 9146                    this.worktree_store.clone(),
 9147                    worktree,
 9148                    new_worktree,
 9149                    entry.clone(),
 9150                ))
 9151            })?
 9152            .context("worktree not found")?;
 9153        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9154            (worktree.absolutize(&old_entry.path), worktree.id())
 9155        })?;
 9156        let new_abs_path =
 9157            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9158
 9159        let _transaction = Self::will_rename_entry(
 9160            this.downgrade(),
 9161            old_worktree_id,
 9162            &old_abs_path,
 9163            &new_abs_path,
 9164            old_entry.is_dir(),
 9165            cx.clone(),
 9166        )
 9167        .await;
 9168        let response = WorktreeStore::handle_rename_project_entry(
 9169            worktree_store,
 9170            envelope.payload,
 9171            cx.clone(),
 9172        )
 9173        .await;
 9174        this.read_with(&cx, |this, _| {
 9175            this.did_rename_entry(
 9176                old_worktree_id,
 9177                &old_abs_path,
 9178                &new_abs_path,
 9179                old_entry.is_dir(),
 9180            );
 9181        })
 9182        .ok();
 9183        response
 9184    }
 9185
 9186    async fn handle_update_diagnostic_summary(
 9187        this: Entity<Self>,
 9188        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9189        mut cx: AsyncApp,
 9190    ) -> Result<()> {
 9191        this.update(&mut cx, |lsp_store, cx| {
 9192            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9193            let mut updated_diagnostics_paths = HashMap::default();
 9194            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9195            for message_summary in envelope
 9196                .payload
 9197                .summary
 9198                .into_iter()
 9199                .chain(envelope.payload.more_summaries)
 9200            {
 9201                let project_path = ProjectPath {
 9202                    worktree_id,
 9203                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9204                };
 9205                let path = project_path.path.clone();
 9206                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9207                let summary = DiagnosticSummary {
 9208                    error_count: message_summary.error_count as usize,
 9209                    warning_count: message_summary.warning_count as usize,
 9210                };
 9211
 9212                if summary.is_empty() {
 9213                    if let Some(worktree_summaries) =
 9214                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9215                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9216                    {
 9217                        summaries.remove(&server_id);
 9218                        if summaries.is_empty() {
 9219                            worktree_summaries.remove(&path);
 9220                        }
 9221                    }
 9222                } else {
 9223                    lsp_store
 9224                        .diagnostic_summaries
 9225                        .entry(worktree_id)
 9226                        .or_default()
 9227                        .entry(path)
 9228                        .or_default()
 9229                        .insert(server_id, summary);
 9230                }
 9231
 9232                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9233                    match &mut diagnostics_summary {
 9234                        Some(diagnostics_summary) => {
 9235                            diagnostics_summary
 9236                                .more_summaries
 9237                                .push(proto::DiagnosticSummary {
 9238                                    path: project_path.path.as_ref().to_proto(),
 9239                                    language_server_id: server_id.0 as u64,
 9240                                    error_count: summary.error_count as u32,
 9241                                    warning_count: summary.warning_count as u32,
 9242                                })
 9243                        }
 9244                        None => {
 9245                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9246                                project_id: *project_id,
 9247                                worktree_id: worktree_id.to_proto(),
 9248                                summary: Some(proto::DiagnosticSummary {
 9249                                    path: project_path.path.as_ref().to_proto(),
 9250                                    language_server_id: server_id.0 as u64,
 9251                                    error_count: summary.error_count as u32,
 9252                                    warning_count: summary.warning_count as u32,
 9253                                }),
 9254                                more_summaries: Vec::new(),
 9255                            })
 9256                        }
 9257                    }
 9258                }
 9259                updated_diagnostics_paths
 9260                    .entry(server_id)
 9261                    .or_insert_with(Vec::new)
 9262                    .push(project_path);
 9263            }
 9264
 9265            if let Some((diagnostics_summary, (downstream_client, _))) =
 9266                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9267            {
 9268                downstream_client.send(diagnostics_summary).log_err();
 9269            }
 9270            for (server_id, paths) in updated_diagnostics_paths {
 9271                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9272            }
 9273            Ok(())
 9274        })?
 9275    }
 9276
 9277    async fn handle_start_language_server(
 9278        lsp_store: Entity<Self>,
 9279        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9280        mut cx: AsyncApp,
 9281    ) -> Result<()> {
 9282        let server = envelope.payload.server.context("invalid server")?;
 9283        let server_capabilities =
 9284            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9285                .with_context(|| {
 9286                    format!(
 9287                        "incorrect server capabilities {}",
 9288                        envelope.payload.capabilities
 9289                    )
 9290                })?;
 9291        lsp_store.update(&mut cx, |lsp_store, cx| {
 9292            let server_id = LanguageServerId(server.id as usize);
 9293            let server_name = LanguageServerName::from_proto(server.name.clone());
 9294            lsp_store
 9295                .lsp_server_capabilities
 9296                .insert(server_id, server_capabilities);
 9297            lsp_store.language_server_statuses.insert(
 9298                server_id,
 9299                LanguageServerStatus {
 9300                    name: server_name.clone(),
 9301                    pending_work: Default::default(),
 9302                    has_pending_diagnostic_updates: false,
 9303                    progress_tokens: Default::default(),
 9304                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9305                    binary: None,
 9306                    configuration: None,
 9307                    workspace_folders: BTreeSet::new(),
 9308                },
 9309            );
 9310            cx.emit(LspStoreEvent::LanguageServerAdded(
 9311                server_id,
 9312                server_name,
 9313                server.worktree_id.map(WorktreeId::from_proto),
 9314            ));
 9315            cx.notify();
 9316        })?;
 9317        Ok(())
 9318    }
 9319
 9320    async fn handle_update_language_server(
 9321        lsp_store: Entity<Self>,
 9322        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9323        mut cx: AsyncApp,
 9324    ) -> Result<()> {
 9325        lsp_store.update(&mut cx, |lsp_store, cx| {
 9326            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9327
 9328            match envelope.payload.variant.context("invalid variant")? {
 9329                proto::update_language_server::Variant::WorkStart(payload) => {
 9330                    lsp_store.on_lsp_work_start(
 9331                        language_server_id,
 9332                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9333                            .context("invalid progress token value")?,
 9334                        LanguageServerProgress {
 9335                            title: payload.title,
 9336                            is_disk_based_diagnostics_progress: false,
 9337                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9338                            message: payload.message,
 9339                            percentage: payload.percentage.map(|p| p as usize),
 9340                            last_update_at: cx.background_executor().now(),
 9341                        },
 9342                        cx,
 9343                    );
 9344                }
 9345                proto::update_language_server::Variant::WorkProgress(payload) => {
 9346                    lsp_store.on_lsp_work_progress(
 9347                        language_server_id,
 9348                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9349                            .context("invalid progress token value")?,
 9350                        LanguageServerProgress {
 9351                            title: None,
 9352                            is_disk_based_diagnostics_progress: false,
 9353                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9354                            message: payload.message,
 9355                            percentage: payload.percentage.map(|p| p as usize),
 9356                            last_update_at: cx.background_executor().now(),
 9357                        },
 9358                        cx,
 9359                    );
 9360                }
 9361
 9362                proto::update_language_server::Variant::WorkEnd(payload) => {
 9363                    lsp_store.on_lsp_work_end(
 9364                        language_server_id,
 9365                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9366                            .context("invalid progress token value")?,
 9367                        cx,
 9368                    );
 9369                }
 9370
 9371                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9372                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9373                }
 9374
 9375                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9376                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9377                }
 9378
 9379                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9380                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9381                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9382                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9383                        language_server_id,
 9384                        name: envelope
 9385                            .payload
 9386                            .server_name
 9387                            .map(SharedString::new)
 9388                            .map(LanguageServerName),
 9389                        message: non_lsp,
 9390                    });
 9391                }
 9392            }
 9393
 9394            Ok(())
 9395        })?
 9396    }
 9397
 9398    async fn handle_language_server_log(
 9399        this: Entity<Self>,
 9400        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9401        mut cx: AsyncApp,
 9402    ) -> Result<()> {
 9403        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9404        let log_type = envelope
 9405            .payload
 9406            .log_type
 9407            .map(LanguageServerLogType::from_proto)
 9408            .context("invalid language server log type")?;
 9409
 9410        let message = envelope.payload.message;
 9411
 9412        this.update(&mut cx, |_, cx| {
 9413            cx.emit(LspStoreEvent::LanguageServerLog(
 9414                language_server_id,
 9415                log_type,
 9416                message,
 9417            ));
 9418        })
 9419    }
 9420
 9421    async fn handle_lsp_ext_cancel_flycheck(
 9422        lsp_store: Entity<Self>,
 9423        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9424        cx: AsyncApp,
 9425    ) -> Result<proto::Ack> {
 9426        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9427        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9428            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9429                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9430            } else {
 9431                None
 9432            }
 9433        })?;
 9434        if let Some(task) = task {
 9435            task.context("handling lsp ext cancel flycheck")?;
 9436        }
 9437
 9438        Ok(proto::Ack {})
 9439    }
 9440
 9441    async fn handle_lsp_ext_run_flycheck(
 9442        lsp_store: Entity<Self>,
 9443        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9444        mut cx: AsyncApp,
 9445    ) -> Result<proto::Ack> {
 9446        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9447        lsp_store.update(&mut cx, |lsp_store, cx| {
 9448            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9449                let text_document = if envelope.payload.current_file_only {
 9450                    let buffer_id = envelope
 9451                        .payload
 9452                        .buffer_id
 9453                        .map(|id| BufferId::new(id))
 9454                        .transpose()?;
 9455                    buffer_id
 9456                        .and_then(|buffer_id| {
 9457                            lsp_store
 9458                                .buffer_store()
 9459                                .read(cx)
 9460                                .get(buffer_id)
 9461                                .and_then(|buffer| {
 9462                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9463                                })
 9464                                .map(|path| make_text_document_identifier(&path))
 9465                        })
 9466                        .transpose()?
 9467                } else {
 9468                    None
 9469                };
 9470                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9471                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9472                )?;
 9473            }
 9474            anyhow::Ok(())
 9475        })??;
 9476
 9477        Ok(proto::Ack {})
 9478    }
 9479
 9480    async fn handle_lsp_ext_clear_flycheck(
 9481        lsp_store: Entity<Self>,
 9482        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9483        cx: AsyncApp,
 9484    ) -> Result<proto::Ack> {
 9485        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9486        lsp_store
 9487            .read_with(&cx, |lsp_store, _| {
 9488                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9489                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9490                } else {
 9491                    None
 9492                }
 9493            })
 9494            .context("handling lsp ext clear flycheck")?;
 9495
 9496        Ok(proto::Ack {})
 9497    }
 9498
 9499    pub fn disk_based_diagnostics_started(
 9500        &mut self,
 9501        language_server_id: LanguageServerId,
 9502        cx: &mut Context<Self>,
 9503    ) {
 9504        if let Some(language_server_status) =
 9505            self.language_server_statuses.get_mut(&language_server_id)
 9506        {
 9507            language_server_status.has_pending_diagnostic_updates = true;
 9508        }
 9509
 9510        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9511        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9512            language_server_id,
 9513            name: self
 9514                .language_server_adapter_for_id(language_server_id)
 9515                .map(|adapter| adapter.name()),
 9516            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9517                Default::default(),
 9518            ),
 9519        })
 9520    }
 9521
 9522    pub fn disk_based_diagnostics_finished(
 9523        &mut self,
 9524        language_server_id: LanguageServerId,
 9525        cx: &mut Context<Self>,
 9526    ) {
 9527        if let Some(language_server_status) =
 9528            self.language_server_statuses.get_mut(&language_server_id)
 9529        {
 9530            language_server_status.has_pending_diagnostic_updates = false;
 9531        }
 9532
 9533        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9534        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9535            language_server_id,
 9536            name: self
 9537                .language_server_adapter_for_id(language_server_id)
 9538                .map(|adapter| adapter.name()),
 9539            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9540                Default::default(),
 9541            ),
 9542        })
 9543    }
 9544
 9545    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9546    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9547    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9548    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9549    // the language server might take some time to publish diagnostics.
 9550    fn simulate_disk_based_diagnostics_events_if_needed(
 9551        &mut self,
 9552        language_server_id: LanguageServerId,
 9553        cx: &mut Context<Self>,
 9554    ) {
 9555        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9556
 9557        let Some(LanguageServerState::Running {
 9558            simulate_disk_based_diagnostics_completion,
 9559            adapter,
 9560            ..
 9561        }) = self
 9562            .as_local_mut()
 9563            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9564        else {
 9565            return;
 9566        };
 9567
 9568        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9569            return;
 9570        }
 9571
 9572        let prev_task =
 9573            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9574                cx.background_executor()
 9575                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9576                    .await;
 9577
 9578                this.update(cx, |this, cx| {
 9579                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9580
 9581                    if let Some(LanguageServerState::Running {
 9582                        simulate_disk_based_diagnostics_completion,
 9583                        ..
 9584                    }) = this.as_local_mut().and_then(|local_store| {
 9585                        local_store.language_servers.get_mut(&language_server_id)
 9586                    }) {
 9587                        *simulate_disk_based_diagnostics_completion = None;
 9588                    }
 9589                })
 9590                .ok();
 9591            }));
 9592
 9593        if prev_task.is_none() {
 9594            self.disk_based_diagnostics_started(language_server_id, cx);
 9595        }
 9596    }
 9597
 9598    pub fn language_server_statuses(
 9599        &self,
 9600    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9601        self.language_server_statuses
 9602            .iter()
 9603            .map(|(key, value)| (*key, value))
 9604    }
 9605
 9606    pub(super) fn did_rename_entry(
 9607        &self,
 9608        worktree_id: WorktreeId,
 9609        old_path: &Path,
 9610        new_path: &Path,
 9611        is_dir: bool,
 9612    ) {
 9613        maybe!({
 9614            let local_store = self.as_local()?;
 9615
 9616            let old_uri = lsp::Uri::from_file_path(old_path)
 9617                .ok()
 9618                .map(|uri| uri.to_string())?;
 9619            let new_uri = lsp::Uri::from_file_path(new_path)
 9620                .ok()
 9621                .map(|uri| uri.to_string())?;
 9622
 9623            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9624                let Some(filter) = local_store
 9625                    .language_server_paths_watched_for_rename
 9626                    .get(&language_server.server_id())
 9627                else {
 9628                    continue;
 9629                };
 9630
 9631                if filter.should_send_did_rename(&old_uri, is_dir) {
 9632                    language_server
 9633                        .notify::<DidRenameFiles>(RenameFilesParams {
 9634                            files: vec![FileRename {
 9635                                old_uri: old_uri.clone(),
 9636                                new_uri: new_uri.clone(),
 9637                            }],
 9638                        })
 9639                        .ok();
 9640                }
 9641            }
 9642            Some(())
 9643        });
 9644    }
 9645
 9646    pub(super) fn will_rename_entry(
 9647        this: WeakEntity<Self>,
 9648        worktree_id: WorktreeId,
 9649        old_path: &Path,
 9650        new_path: &Path,
 9651        is_dir: bool,
 9652        cx: AsyncApp,
 9653    ) -> Task<ProjectTransaction> {
 9654        let old_uri = lsp::Uri::from_file_path(old_path)
 9655            .ok()
 9656            .map(|uri| uri.to_string());
 9657        let new_uri = lsp::Uri::from_file_path(new_path)
 9658            .ok()
 9659            .map(|uri| uri.to_string());
 9660        cx.spawn(async move |cx| {
 9661            let mut tasks = vec![];
 9662            this.update(cx, |this, cx| {
 9663                let local_store = this.as_local()?;
 9664                let old_uri = old_uri?;
 9665                let new_uri = new_uri?;
 9666                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9667                    let Some(filter) = local_store
 9668                        .language_server_paths_watched_for_rename
 9669                        .get(&language_server.server_id())
 9670                    else {
 9671                        continue;
 9672                    };
 9673
 9674                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9675                        let apply_edit = cx.spawn({
 9676                            let old_uri = old_uri.clone();
 9677                            let new_uri = new_uri.clone();
 9678                            let language_server = language_server.clone();
 9679                            async move |this, cx| {
 9680                                let edit = language_server
 9681                                    .request::<WillRenameFiles>(RenameFilesParams {
 9682                                        files: vec![FileRename { old_uri, new_uri }],
 9683                                    })
 9684                                    .await
 9685                                    .into_response()
 9686                                    .context("will rename files")
 9687                                    .log_err()
 9688                                    .flatten()?;
 9689
 9690                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9691                                    this.upgrade()?,
 9692                                    edit,
 9693                                    false,
 9694                                    language_server.clone(),
 9695                                    cx,
 9696                                )
 9697                                .await
 9698                                .ok()?;
 9699                                Some(transaction)
 9700                            }
 9701                        });
 9702                        tasks.push(apply_edit);
 9703                    }
 9704                }
 9705                Some(())
 9706            })
 9707            .ok()
 9708            .flatten();
 9709            let mut merged_transaction = ProjectTransaction::default();
 9710            for task in tasks {
 9711                // Await on tasks sequentially so that the order of application of edits is deterministic
 9712                // (at least with regards to the order of registration of language servers)
 9713                if let Some(transaction) = task.await {
 9714                    for (buffer, buffer_transaction) in transaction.0 {
 9715                        merged_transaction.0.insert(buffer, buffer_transaction);
 9716                    }
 9717                }
 9718            }
 9719            merged_transaction
 9720        })
 9721    }
 9722
 9723    fn lsp_notify_abs_paths_changed(
 9724        &mut self,
 9725        server_id: LanguageServerId,
 9726        changes: Vec<PathEvent>,
 9727    ) {
 9728        maybe!({
 9729            let server = self.language_server_for_id(server_id)?;
 9730            let changes = changes
 9731                .into_iter()
 9732                .filter_map(|event| {
 9733                    let typ = match event.kind? {
 9734                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9735                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9736                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9737                    };
 9738                    Some(lsp::FileEvent {
 9739                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9740                        typ,
 9741                    })
 9742                })
 9743                .collect::<Vec<_>>();
 9744            if !changes.is_empty() {
 9745                server
 9746                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9747                        lsp::DidChangeWatchedFilesParams { changes },
 9748                    )
 9749                    .ok();
 9750            }
 9751            Some(())
 9752        });
 9753    }
 9754
 9755    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9756        self.as_local()?.language_server_for_id(id)
 9757    }
 9758
 9759    fn on_lsp_progress(
 9760        &mut self,
 9761        progress_params: lsp::ProgressParams,
 9762        language_server_id: LanguageServerId,
 9763        disk_based_diagnostics_progress_token: Option<String>,
 9764        cx: &mut Context<Self>,
 9765    ) {
 9766        match progress_params.value {
 9767            lsp::ProgressParamsValue::WorkDone(progress) => {
 9768                self.handle_work_done_progress(
 9769                    progress,
 9770                    language_server_id,
 9771                    disk_based_diagnostics_progress_token,
 9772                    ProgressToken::from_lsp(progress_params.token),
 9773                    cx,
 9774                );
 9775            }
 9776            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9777                let registration_id = match progress_params.token {
 9778                    lsp::NumberOrString::Number(_) => None,
 9779                    lsp::NumberOrString::String(token) => token
 9780                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9781                        .map(|(_, id)| id.to_owned()),
 9782                };
 9783                if let Some(LanguageServerState::Running {
 9784                    workspace_diagnostics_refresh_tasks,
 9785                    ..
 9786                }) = self
 9787                    .as_local_mut()
 9788                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9789                    && let Some(workspace_diagnostics) =
 9790                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9791                {
 9792                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9793                    self.apply_workspace_diagnostic_report(
 9794                        language_server_id,
 9795                        report,
 9796                        registration_id.map(SharedString::from),
 9797                        cx,
 9798                    )
 9799                }
 9800            }
 9801        }
 9802    }
 9803
 9804    fn handle_work_done_progress(
 9805        &mut self,
 9806        progress: lsp::WorkDoneProgress,
 9807        language_server_id: LanguageServerId,
 9808        disk_based_diagnostics_progress_token: Option<String>,
 9809        token: ProgressToken,
 9810        cx: &mut Context<Self>,
 9811    ) {
 9812        let language_server_status =
 9813            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9814                status
 9815            } else {
 9816                return;
 9817            };
 9818
 9819        if !language_server_status.progress_tokens.contains(&token) {
 9820            return;
 9821        }
 9822
 9823        let is_disk_based_diagnostics_progress =
 9824            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9825                (&disk_based_diagnostics_progress_token, &token)
 9826            {
 9827                token.starts_with(disk_based_token)
 9828            } else {
 9829                false
 9830            };
 9831
 9832        match progress {
 9833            lsp::WorkDoneProgress::Begin(report) => {
 9834                if is_disk_based_diagnostics_progress {
 9835                    self.disk_based_diagnostics_started(language_server_id, cx);
 9836                }
 9837                self.on_lsp_work_start(
 9838                    language_server_id,
 9839                    token.clone(),
 9840                    LanguageServerProgress {
 9841                        title: Some(report.title),
 9842                        is_disk_based_diagnostics_progress,
 9843                        is_cancellable: report.cancellable.unwrap_or(false),
 9844                        message: report.message.clone(),
 9845                        percentage: report.percentage.map(|p| p as usize),
 9846                        last_update_at: cx.background_executor().now(),
 9847                    },
 9848                    cx,
 9849                );
 9850            }
 9851            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9852                language_server_id,
 9853                token,
 9854                LanguageServerProgress {
 9855                    title: None,
 9856                    is_disk_based_diagnostics_progress,
 9857                    is_cancellable: report.cancellable.unwrap_or(false),
 9858                    message: report.message,
 9859                    percentage: report.percentage.map(|p| p as usize),
 9860                    last_update_at: cx.background_executor().now(),
 9861                },
 9862                cx,
 9863            ),
 9864            lsp::WorkDoneProgress::End(_) => {
 9865                language_server_status.progress_tokens.remove(&token);
 9866                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9867                if is_disk_based_diagnostics_progress {
 9868                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9869                }
 9870            }
 9871        }
 9872    }
 9873
 9874    fn on_lsp_work_start(
 9875        &mut self,
 9876        language_server_id: LanguageServerId,
 9877        token: ProgressToken,
 9878        progress: LanguageServerProgress,
 9879        cx: &mut Context<Self>,
 9880    ) {
 9881        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9882            status.pending_work.insert(token.clone(), progress.clone());
 9883            cx.notify();
 9884        }
 9885        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9886            language_server_id,
 9887            name: self
 9888                .language_server_adapter_for_id(language_server_id)
 9889                .map(|adapter| adapter.name()),
 9890            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9891                token: Some(token.to_proto()),
 9892                title: progress.title,
 9893                message: progress.message,
 9894                percentage: progress.percentage.map(|p| p as u32),
 9895                is_cancellable: Some(progress.is_cancellable),
 9896            }),
 9897        })
 9898    }
 9899
 9900    fn on_lsp_work_progress(
 9901        &mut self,
 9902        language_server_id: LanguageServerId,
 9903        token: ProgressToken,
 9904        progress: LanguageServerProgress,
 9905        cx: &mut Context<Self>,
 9906    ) {
 9907        let mut did_update = false;
 9908        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9909            match status.pending_work.entry(token.clone()) {
 9910                btree_map::Entry::Vacant(entry) => {
 9911                    entry.insert(progress.clone());
 9912                    did_update = true;
 9913                }
 9914                btree_map::Entry::Occupied(mut entry) => {
 9915                    let entry = entry.get_mut();
 9916                    if (progress.last_update_at - entry.last_update_at)
 9917                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9918                    {
 9919                        entry.last_update_at = progress.last_update_at;
 9920                        if progress.message.is_some() {
 9921                            entry.message = progress.message.clone();
 9922                        }
 9923                        if progress.percentage.is_some() {
 9924                            entry.percentage = progress.percentage;
 9925                        }
 9926                        if progress.is_cancellable != entry.is_cancellable {
 9927                            entry.is_cancellable = progress.is_cancellable;
 9928                        }
 9929                        did_update = true;
 9930                    }
 9931                }
 9932            }
 9933        }
 9934
 9935        if did_update {
 9936            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9937                language_server_id,
 9938                name: self
 9939                    .language_server_adapter_for_id(language_server_id)
 9940                    .map(|adapter| adapter.name()),
 9941                message: proto::update_language_server::Variant::WorkProgress(
 9942                    proto::LspWorkProgress {
 9943                        token: Some(token.to_proto()),
 9944                        message: progress.message,
 9945                        percentage: progress.percentage.map(|p| p as u32),
 9946                        is_cancellable: Some(progress.is_cancellable),
 9947                    },
 9948                ),
 9949            })
 9950        }
 9951    }
 9952
 9953    fn on_lsp_work_end(
 9954        &mut self,
 9955        language_server_id: LanguageServerId,
 9956        token: ProgressToken,
 9957        cx: &mut Context<Self>,
 9958    ) {
 9959        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9960            if let Some(work) = status.pending_work.remove(&token)
 9961                && !work.is_disk_based_diagnostics_progress
 9962            {
 9963                cx.emit(LspStoreEvent::RefreshInlayHints {
 9964                    server_id: language_server_id,
 9965                    request_id: None,
 9966                });
 9967            }
 9968            cx.notify();
 9969        }
 9970
 9971        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9972            language_server_id,
 9973            name: self
 9974                .language_server_adapter_for_id(language_server_id)
 9975                .map(|adapter| adapter.name()),
 9976            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9977                token: Some(token.to_proto()),
 9978            }),
 9979        })
 9980    }
 9981
 9982    pub async fn handle_resolve_completion_documentation(
 9983        this: Entity<Self>,
 9984        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9985        mut cx: AsyncApp,
 9986    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9987        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9988
 9989        let completion = this
 9990            .read_with(&cx, |this, cx| {
 9991                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9992                let server = this
 9993                    .language_server_for_id(id)
 9994                    .with_context(|| format!("No language server {id}"))?;
 9995
 9996                anyhow::Ok(cx.background_spawn(async move {
 9997                    let can_resolve = server
 9998                        .capabilities()
 9999                        .completion_provider
10000                        .as_ref()
10001                        .and_then(|options| options.resolve_provider)
10002                        .unwrap_or(false);
10003                    if can_resolve {
10004                        server
10005                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10006                            .await
10007                            .into_response()
10008                            .context("resolve completion item")
10009                    } else {
10010                        anyhow::Ok(lsp_completion)
10011                    }
10012                }))
10013            })??
10014            .await?;
10015
10016        let mut documentation_is_markdown = false;
10017        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10018        let documentation = match completion.documentation {
10019            Some(lsp::Documentation::String(text)) => text,
10020
10021            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10022                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10023                value
10024            }
10025
10026            _ => String::new(),
10027        };
10028
10029        // If we have a new buffer_id, that means we're talking to a new client
10030        // and want to check for new text_edits in the completion too.
10031        let mut old_replace_start = None;
10032        let mut old_replace_end = None;
10033        let mut old_insert_start = None;
10034        let mut old_insert_end = None;
10035        let mut new_text = String::default();
10036        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10037            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10038                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10039                anyhow::Ok(buffer.read(cx).snapshot())
10040            })??;
10041
10042            if let Some(text_edit) = completion.text_edit.as_ref() {
10043                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10044
10045                if let Some(mut edit) = edit {
10046                    LineEnding::normalize(&mut edit.new_text);
10047
10048                    new_text = edit.new_text;
10049                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10050                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10051                    if let Some(insert_range) = edit.insert_range {
10052                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10053                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10054                    }
10055                }
10056            }
10057        }
10058
10059        Ok(proto::ResolveCompletionDocumentationResponse {
10060            documentation,
10061            documentation_is_markdown,
10062            old_replace_start,
10063            old_replace_end,
10064            new_text,
10065            lsp_completion,
10066            old_insert_start,
10067            old_insert_end,
10068        })
10069    }
10070
10071    async fn handle_on_type_formatting(
10072        this: Entity<Self>,
10073        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10074        mut cx: AsyncApp,
10075    ) -> Result<proto::OnTypeFormattingResponse> {
10076        let on_type_formatting = this.update(&mut cx, |this, cx| {
10077            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10078            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10079            let position = envelope
10080                .payload
10081                .position
10082                .and_then(deserialize_anchor)
10083                .context("invalid position")?;
10084            anyhow::Ok(this.apply_on_type_formatting(
10085                buffer,
10086                position,
10087                envelope.payload.trigger.clone(),
10088                cx,
10089            ))
10090        })??;
10091
10092        let transaction = on_type_formatting
10093            .await?
10094            .as_ref()
10095            .map(language::proto::serialize_transaction);
10096        Ok(proto::OnTypeFormattingResponse { transaction })
10097    }
10098
10099    async fn handle_refresh_inlay_hints(
10100        lsp_store: Entity<Self>,
10101        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10102        mut cx: AsyncApp,
10103    ) -> Result<proto::Ack> {
10104        lsp_store.update(&mut cx, |_, cx| {
10105            cx.emit(LspStoreEvent::RefreshInlayHints {
10106                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10107                request_id: envelope.payload.request_id.map(|id| id as usize),
10108            });
10109        })?;
10110        Ok(proto::Ack {})
10111    }
10112
10113    async fn handle_pull_workspace_diagnostics(
10114        lsp_store: Entity<Self>,
10115        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10116        mut cx: AsyncApp,
10117    ) -> Result<proto::Ack> {
10118        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10119        lsp_store.update(&mut cx, |lsp_store, _| {
10120            lsp_store.pull_workspace_diagnostics(server_id);
10121        })?;
10122        Ok(proto::Ack {})
10123    }
10124
10125    async fn handle_get_color_presentation(
10126        lsp_store: Entity<Self>,
10127        envelope: TypedEnvelope<proto::GetColorPresentation>,
10128        mut cx: AsyncApp,
10129    ) -> Result<proto::GetColorPresentationResponse> {
10130        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10131        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10132            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10133        })??;
10134
10135        let color = envelope
10136            .payload
10137            .color
10138            .context("invalid color resolve request")?;
10139        let start = color
10140            .lsp_range_start
10141            .context("invalid color resolve request")?;
10142        let end = color
10143            .lsp_range_end
10144            .context("invalid color resolve request")?;
10145
10146        let color = DocumentColor {
10147            lsp_range: lsp::Range {
10148                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10149                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10150            },
10151            color: lsp::Color {
10152                red: color.red,
10153                green: color.green,
10154                blue: color.blue,
10155                alpha: color.alpha,
10156            },
10157            resolved: false,
10158            color_presentations: Vec::new(),
10159        };
10160        let resolved_color = lsp_store
10161            .update(&mut cx, |lsp_store, cx| {
10162                lsp_store.resolve_color_presentation(
10163                    color,
10164                    buffer.clone(),
10165                    LanguageServerId(envelope.payload.server_id as usize),
10166                    cx,
10167                )
10168            })?
10169            .await
10170            .context("resolving color presentation")?;
10171
10172        Ok(proto::GetColorPresentationResponse {
10173            presentations: resolved_color
10174                .color_presentations
10175                .into_iter()
10176                .map(|presentation| proto::ColorPresentation {
10177                    label: presentation.label.to_string(),
10178                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10179                    additional_text_edits: presentation
10180                        .additional_text_edits
10181                        .into_iter()
10182                        .map(serialize_lsp_edit)
10183                        .collect(),
10184                })
10185                .collect(),
10186        })
10187    }
10188
10189    async fn handle_resolve_inlay_hint(
10190        lsp_store: Entity<Self>,
10191        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10192        mut cx: AsyncApp,
10193    ) -> Result<proto::ResolveInlayHintResponse> {
10194        let proto_hint = envelope
10195            .payload
10196            .hint
10197            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10198        let hint = InlayHints::proto_to_project_hint(proto_hint)
10199            .context("resolved proto inlay hint conversion")?;
10200        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10201            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10202            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10203        })??;
10204        let response_hint = lsp_store
10205            .update(&mut cx, |lsp_store, cx| {
10206                lsp_store.resolve_inlay_hint(
10207                    hint,
10208                    buffer,
10209                    LanguageServerId(envelope.payload.language_server_id as usize),
10210                    cx,
10211                )
10212            })?
10213            .await
10214            .context("inlay hints fetch")?;
10215        Ok(proto::ResolveInlayHintResponse {
10216            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10217        })
10218    }
10219
10220    async fn handle_refresh_code_lens(
10221        this: Entity<Self>,
10222        _: TypedEnvelope<proto::RefreshCodeLens>,
10223        mut cx: AsyncApp,
10224    ) -> Result<proto::Ack> {
10225        this.update(&mut cx, |_, cx| {
10226            cx.emit(LspStoreEvent::RefreshCodeLens);
10227        })?;
10228        Ok(proto::Ack {})
10229    }
10230
10231    async fn handle_open_buffer_for_symbol(
10232        this: Entity<Self>,
10233        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10234        mut cx: AsyncApp,
10235    ) -> Result<proto::OpenBufferForSymbolResponse> {
10236        let peer_id = envelope.original_sender_id().unwrap_or_default();
10237        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10238        let symbol = Self::deserialize_symbol(symbol)?;
10239        this.read_with(&cx, |this, _| {
10240            if let SymbolLocation::OutsideProject {
10241                abs_path,
10242                signature,
10243            } = &symbol.path
10244            {
10245                let new_signature = this.symbol_signature(&abs_path);
10246                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10247            }
10248            Ok(())
10249        })??;
10250        let buffer = this
10251            .update(&mut cx, |this, cx| {
10252                this.open_buffer_for_symbol(
10253                    &Symbol {
10254                        language_server_name: symbol.language_server_name,
10255                        source_worktree_id: symbol.source_worktree_id,
10256                        source_language_server_id: symbol.source_language_server_id,
10257                        path: symbol.path,
10258                        name: symbol.name,
10259                        kind: symbol.kind,
10260                        range: symbol.range,
10261                        label: CodeLabel::default(),
10262                    },
10263                    cx,
10264                )
10265            })?
10266            .await?;
10267
10268        this.update(&mut cx, |this, cx| {
10269            let is_private = buffer
10270                .read(cx)
10271                .file()
10272                .map(|f| f.is_private())
10273                .unwrap_or_default();
10274            if is_private {
10275                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10276            } else {
10277                this.buffer_store
10278                    .update(cx, |buffer_store, cx| {
10279                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10280                    })
10281                    .detach_and_log_err(cx);
10282                let buffer_id = buffer.read(cx).remote_id().to_proto();
10283                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10284            }
10285        })?
10286    }
10287
10288    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10289        let mut hasher = Sha256::new();
10290        hasher.update(abs_path.to_string_lossy().as_bytes());
10291        hasher.update(self.nonce.to_be_bytes());
10292        hasher.finalize().as_slice().try_into().unwrap()
10293    }
10294
10295    pub async fn handle_get_project_symbols(
10296        this: Entity<Self>,
10297        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10298        mut cx: AsyncApp,
10299    ) -> Result<proto::GetProjectSymbolsResponse> {
10300        let symbols = this
10301            .update(&mut cx, |this, cx| {
10302                this.symbols(&envelope.payload.query, cx)
10303            })?
10304            .await?;
10305
10306        Ok(proto::GetProjectSymbolsResponse {
10307            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10308        })
10309    }
10310
10311    pub async fn handle_restart_language_servers(
10312        this: Entity<Self>,
10313        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10314        mut cx: AsyncApp,
10315    ) -> Result<proto::Ack> {
10316        this.update(&mut cx, |lsp_store, cx| {
10317            let buffers =
10318                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10319            lsp_store.restart_language_servers_for_buffers(
10320                buffers,
10321                envelope
10322                    .payload
10323                    .only_servers
10324                    .into_iter()
10325                    .filter_map(|selector| {
10326                        Some(match selector.selector? {
10327                            proto::language_server_selector::Selector::ServerId(server_id) => {
10328                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10329                            }
10330                            proto::language_server_selector::Selector::Name(name) => {
10331                                LanguageServerSelector::Name(LanguageServerName(
10332                                    SharedString::from(name),
10333                                ))
10334                            }
10335                        })
10336                    })
10337                    .collect(),
10338                cx,
10339            );
10340        })?;
10341
10342        Ok(proto::Ack {})
10343    }
10344
10345    pub async fn handle_stop_language_servers(
10346        lsp_store: Entity<Self>,
10347        envelope: TypedEnvelope<proto::StopLanguageServers>,
10348        mut cx: AsyncApp,
10349    ) -> Result<proto::Ack> {
10350        lsp_store.update(&mut cx, |lsp_store, cx| {
10351            if envelope.payload.all
10352                && envelope.payload.also_servers.is_empty()
10353                && envelope.payload.buffer_ids.is_empty()
10354            {
10355                lsp_store.stop_all_language_servers(cx);
10356            } else {
10357                let buffers =
10358                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10359                lsp_store
10360                    .stop_language_servers_for_buffers(
10361                        buffers,
10362                        envelope
10363                            .payload
10364                            .also_servers
10365                            .into_iter()
10366                            .filter_map(|selector| {
10367                                Some(match selector.selector? {
10368                                    proto::language_server_selector::Selector::ServerId(
10369                                        server_id,
10370                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10371                                        server_id,
10372                                    )),
10373                                    proto::language_server_selector::Selector::Name(name) => {
10374                                        LanguageServerSelector::Name(LanguageServerName(
10375                                            SharedString::from(name),
10376                                        ))
10377                                    }
10378                                })
10379                            })
10380                            .collect(),
10381                        cx,
10382                    )
10383                    .detach_and_log_err(cx);
10384            }
10385        })?;
10386
10387        Ok(proto::Ack {})
10388    }
10389
10390    pub async fn handle_cancel_language_server_work(
10391        lsp_store: Entity<Self>,
10392        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10393        mut cx: AsyncApp,
10394    ) -> Result<proto::Ack> {
10395        lsp_store.update(&mut cx, |lsp_store, cx| {
10396            if let Some(work) = envelope.payload.work {
10397                match work {
10398                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10399                        let buffers =
10400                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10401                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10402                    }
10403                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10404                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10405                        let token = work
10406                            .token
10407                            .map(|token| {
10408                                ProgressToken::from_proto(token)
10409                                    .context("invalid work progress token")
10410                            })
10411                            .transpose()?;
10412                        lsp_store.cancel_language_server_work(server_id, token, cx);
10413                    }
10414                }
10415            }
10416            anyhow::Ok(())
10417        })??;
10418
10419        Ok(proto::Ack {})
10420    }
10421
10422    fn buffer_ids_to_buffers(
10423        &mut self,
10424        buffer_ids: impl Iterator<Item = u64>,
10425        cx: &mut Context<Self>,
10426    ) -> Vec<Entity<Buffer>> {
10427        buffer_ids
10428            .into_iter()
10429            .flat_map(|buffer_id| {
10430                self.buffer_store
10431                    .read(cx)
10432                    .get(BufferId::new(buffer_id).log_err()?)
10433            })
10434            .collect::<Vec<_>>()
10435    }
10436
10437    async fn handle_apply_additional_edits_for_completion(
10438        this: Entity<Self>,
10439        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10440        mut cx: AsyncApp,
10441    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10442        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10443            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10444            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10445            let completion = Self::deserialize_completion(
10446                envelope.payload.completion.context("invalid completion")?,
10447            )?;
10448            anyhow::Ok((buffer, completion))
10449        })??;
10450
10451        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10452            this.apply_additional_edits_for_completion(
10453                buffer,
10454                Rc::new(RefCell::new(Box::new([Completion {
10455                    replace_range: completion.replace_range,
10456                    new_text: completion.new_text,
10457                    source: completion.source,
10458                    documentation: None,
10459                    label: CodeLabel::default(),
10460                    match_start: None,
10461                    snippet_deduplication_key: None,
10462                    insert_text_mode: None,
10463                    icon_path: None,
10464                    confirm: None,
10465                }]))),
10466                0,
10467                false,
10468                cx,
10469            )
10470        })?;
10471
10472        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10473            transaction: apply_additional_edits
10474                .await?
10475                .as_ref()
10476                .map(language::proto::serialize_transaction),
10477        })
10478    }
10479
10480    pub fn last_formatting_failure(&self) -> Option<&str> {
10481        self.last_formatting_failure.as_deref()
10482    }
10483
10484    pub fn reset_last_formatting_failure(&mut self) {
10485        self.last_formatting_failure = None;
10486    }
10487
10488    pub fn environment_for_buffer(
10489        &self,
10490        buffer: &Entity<Buffer>,
10491        cx: &mut Context<Self>,
10492    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10493        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10494            environment.update(cx, |env, cx| {
10495                env.buffer_environment(buffer, &self.worktree_store, cx)
10496            })
10497        } else {
10498            Task::ready(None).shared()
10499        }
10500    }
10501
10502    pub fn format(
10503        &mut self,
10504        buffers: HashSet<Entity<Buffer>>,
10505        target: LspFormatTarget,
10506        push_to_history: bool,
10507        trigger: FormatTrigger,
10508        cx: &mut Context<Self>,
10509    ) -> Task<anyhow::Result<ProjectTransaction>> {
10510        let logger = zlog::scoped!("format");
10511        if self.as_local().is_some() {
10512            zlog::trace!(logger => "Formatting locally");
10513            let logger = zlog::scoped!(logger => "local");
10514            let buffers = buffers
10515                .into_iter()
10516                .map(|buffer_handle| {
10517                    let buffer = buffer_handle.read(cx);
10518                    let buffer_abs_path = File::from_dyn(buffer.file())
10519                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10520
10521                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10522                })
10523                .collect::<Vec<_>>();
10524
10525            cx.spawn(async move |lsp_store, cx| {
10526                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10527
10528                for (handle, abs_path, id) in buffers {
10529                    let env = lsp_store
10530                        .update(cx, |lsp_store, cx| {
10531                            lsp_store.environment_for_buffer(&handle, cx)
10532                        })?
10533                        .await;
10534
10535                    let ranges = match &target {
10536                        LspFormatTarget::Buffers => None,
10537                        LspFormatTarget::Ranges(ranges) => {
10538                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10539                        }
10540                    };
10541
10542                    formattable_buffers.push(FormattableBuffer {
10543                        handle,
10544                        abs_path,
10545                        env,
10546                        ranges,
10547                    });
10548                }
10549                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10550
10551                let format_timer = zlog::time!(logger => "Formatting buffers");
10552                let result = LocalLspStore::format_locally(
10553                    lsp_store.clone(),
10554                    formattable_buffers,
10555                    push_to_history,
10556                    trigger,
10557                    logger,
10558                    cx,
10559                )
10560                .await;
10561                format_timer.end();
10562
10563                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10564
10565                lsp_store.update(cx, |lsp_store, _| {
10566                    lsp_store.update_last_formatting_failure(&result);
10567                })?;
10568
10569                result
10570            })
10571        } else if let Some((client, project_id)) = self.upstream_client() {
10572            zlog::trace!(logger => "Formatting remotely");
10573            let logger = zlog::scoped!(logger => "remote");
10574            // Don't support formatting ranges via remote
10575            match target {
10576                LspFormatTarget::Buffers => {}
10577                LspFormatTarget::Ranges(_) => {
10578                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10579                    return Task::ready(Ok(ProjectTransaction::default()));
10580                }
10581            }
10582
10583            let buffer_store = self.buffer_store();
10584            cx.spawn(async move |lsp_store, cx| {
10585                zlog::trace!(logger => "Sending remote format request");
10586                let request_timer = zlog::time!(logger => "remote format request");
10587                let result = client
10588                    .request(proto::FormatBuffers {
10589                        project_id,
10590                        trigger: trigger as i32,
10591                        buffer_ids: buffers
10592                            .iter()
10593                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10594                            .collect::<Result<_>>()?,
10595                    })
10596                    .await
10597                    .and_then(|result| result.transaction.context("missing transaction"));
10598                request_timer.end();
10599
10600                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10601
10602                lsp_store.update(cx, |lsp_store, _| {
10603                    lsp_store.update_last_formatting_failure(&result);
10604                })?;
10605
10606                let transaction_response = result?;
10607                let _timer = zlog::time!(logger => "deserializing project transaction");
10608                buffer_store
10609                    .update(cx, |buffer_store, cx| {
10610                        buffer_store.deserialize_project_transaction(
10611                            transaction_response,
10612                            push_to_history,
10613                            cx,
10614                        )
10615                    })?
10616                    .await
10617            })
10618        } else {
10619            zlog::trace!(logger => "Not formatting");
10620            Task::ready(Ok(ProjectTransaction::default()))
10621        }
10622    }
10623
10624    async fn handle_format_buffers(
10625        this: Entity<Self>,
10626        envelope: TypedEnvelope<proto::FormatBuffers>,
10627        mut cx: AsyncApp,
10628    ) -> Result<proto::FormatBuffersResponse> {
10629        let sender_id = envelope.original_sender_id().unwrap_or_default();
10630        let format = this.update(&mut cx, |this, cx| {
10631            let mut buffers = HashSet::default();
10632            for buffer_id in &envelope.payload.buffer_ids {
10633                let buffer_id = BufferId::new(*buffer_id)?;
10634                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10635            }
10636            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10637            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10638        })??;
10639
10640        let project_transaction = format.await?;
10641        let project_transaction = this.update(&mut cx, |this, cx| {
10642            this.buffer_store.update(cx, |buffer_store, cx| {
10643                buffer_store.serialize_project_transaction_for_peer(
10644                    project_transaction,
10645                    sender_id,
10646                    cx,
10647                )
10648            })
10649        })?;
10650        Ok(proto::FormatBuffersResponse {
10651            transaction: Some(project_transaction),
10652        })
10653    }
10654
10655    async fn handle_apply_code_action_kind(
10656        this: Entity<Self>,
10657        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10658        mut cx: AsyncApp,
10659    ) -> Result<proto::ApplyCodeActionKindResponse> {
10660        let sender_id = envelope.original_sender_id().unwrap_or_default();
10661        let format = this.update(&mut cx, |this, cx| {
10662            let mut buffers = HashSet::default();
10663            for buffer_id in &envelope.payload.buffer_ids {
10664                let buffer_id = BufferId::new(*buffer_id)?;
10665                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10666            }
10667            let kind = match envelope.payload.kind.as_str() {
10668                "" => CodeActionKind::EMPTY,
10669                "quickfix" => CodeActionKind::QUICKFIX,
10670                "refactor" => CodeActionKind::REFACTOR,
10671                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10672                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10673                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10674                "source" => CodeActionKind::SOURCE,
10675                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10676                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10677                _ => anyhow::bail!(
10678                    "Invalid code action kind {}",
10679                    envelope.payload.kind.as_str()
10680                ),
10681            };
10682            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10683        })??;
10684
10685        let project_transaction = format.await?;
10686        let project_transaction = this.update(&mut cx, |this, cx| {
10687            this.buffer_store.update(cx, |buffer_store, cx| {
10688                buffer_store.serialize_project_transaction_for_peer(
10689                    project_transaction,
10690                    sender_id,
10691                    cx,
10692                )
10693            })
10694        })?;
10695        Ok(proto::ApplyCodeActionKindResponse {
10696            transaction: Some(project_transaction),
10697        })
10698    }
10699
10700    async fn shutdown_language_server(
10701        server_state: Option<LanguageServerState>,
10702        name: LanguageServerName,
10703        cx: &mut AsyncApp,
10704    ) {
10705        let server = match server_state {
10706            Some(LanguageServerState::Starting { startup, .. }) => {
10707                let mut timer = cx
10708                    .background_executor()
10709                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10710                    .fuse();
10711
10712                select! {
10713                    server = startup.fuse() => server,
10714                    () = timer => {
10715                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10716                        None
10717                    },
10718                }
10719            }
10720
10721            Some(LanguageServerState::Running { server, .. }) => Some(server),
10722
10723            None => None,
10724        };
10725
10726        if let Some(server) = server
10727            && let Some(shutdown) = server.shutdown()
10728        {
10729            shutdown.await;
10730        }
10731    }
10732
10733    // Returns a list of all of the worktrees which no longer have a language server and the root path
10734    // for the stopped server
10735    fn stop_local_language_server(
10736        &mut self,
10737        server_id: LanguageServerId,
10738        cx: &mut Context<Self>,
10739    ) -> Task<()> {
10740        let local = match &mut self.mode {
10741            LspStoreMode::Local(local) => local,
10742            _ => {
10743                return Task::ready(());
10744            }
10745        };
10746
10747        // Remove this server ID from all entries in the given worktree.
10748        local
10749            .language_server_ids
10750            .retain(|_, state| state.id != server_id);
10751        self.buffer_store.update(cx, |buffer_store, cx| {
10752            for buffer in buffer_store.buffers() {
10753                buffer.update(cx, |buffer, cx| {
10754                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10755                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10756                });
10757            }
10758        });
10759
10760        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10761            summaries.retain(|path, summaries_by_server_id| {
10762                if summaries_by_server_id.remove(&server_id).is_some() {
10763                    if let Some((client, project_id)) = self.downstream_client.clone() {
10764                        client
10765                            .send(proto::UpdateDiagnosticSummary {
10766                                project_id,
10767                                worktree_id: worktree_id.to_proto(),
10768                                summary: Some(proto::DiagnosticSummary {
10769                                    path: path.as_ref().to_proto(),
10770                                    language_server_id: server_id.0 as u64,
10771                                    error_count: 0,
10772                                    warning_count: 0,
10773                                }),
10774                                more_summaries: Vec::new(),
10775                            })
10776                            .log_err();
10777                    }
10778                    !summaries_by_server_id.is_empty()
10779                } else {
10780                    true
10781                }
10782            });
10783        }
10784
10785        let local = self.as_local_mut().unwrap();
10786        for diagnostics in local.diagnostics.values_mut() {
10787            diagnostics.retain(|_, diagnostics_by_server_id| {
10788                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10789                    diagnostics_by_server_id.remove(ix);
10790                    !diagnostics_by_server_id.is_empty()
10791                } else {
10792                    true
10793                }
10794            });
10795        }
10796        local.language_server_watched_paths.remove(&server_id);
10797
10798        let server_state = local.language_servers.remove(&server_id);
10799        self.cleanup_lsp_data(server_id);
10800        let name = self
10801            .language_server_statuses
10802            .remove(&server_id)
10803            .map(|status| status.name)
10804            .or_else(|| {
10805                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10806                    Some(adapter.name())
10807                } else {
10808                    None
10809                }
10810            });
10811
10812        if let Some(name) = name {
10813            log::info!("stopping language server {name}");
10814            self.languages
10815                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10816            cx.notify();
10817
10818            return cx.spawn(async move |lsp_store, cx| {
10819                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10820                lsp_store
10821                    .update(cx, |lsp_store, cx| {
10822                        lsp_store
10823                            .languages
10824                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10825                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10826                        cx.notify();
10827                    })
10828                    .ok();
10829            });
10830        }
10831
10832        if server_state.is_some() {
10833            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10834        }
10835        Task::ready(())
10836    }
10837
10838    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10839        if let Some((client, project_id)) = self.upstream_client() {
10840            let request = client.request(proto::StopLanguageServers {
10841                project_id,
10842                buffer_ids: Vec::new(),
10843                also_servers: Vec::new(),
10844                all: true,
10845            });
10846            cx.background_spawn(request).detach_and_log_err(cx);
10847        } else {
10848            let Some(local) = self.as_local_mut() else {
10849                return;
10850            };
10851            let language_servers_to_stop = local
10852                .language_server_ids
10853                .values()
10854                .map(|state| state.id)
10855                .collect();
10856            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10857            let tasks = language_servers_to_stop
10858                .into_iter()
10859                .map(|server| self.stop_local_language_server(server, cx))
10860                .collect::<Vec<_>>();
10861            cx.background_spawn(async move {
10862                futures::future::join_all(tasks).await;
10863            })
10864            .detach();
10865        }
10866    }
10867
10868    pub fn restart_language_servers_for_buffers(
10869        &mut self,
10870        buffers: Vec<Entity<Buffer>>,
10871        only_restart_servers: HashSet<LanguageServerSelector>,
10872        cx: &mut Context<Self>,
10873    ) {
10874        if let Some((client, project_id)) = self.upstream_client() {
10875            let request = client.request(proto::RestartLanguageServers {
10876                project_id,
10877                buffer_ids: buffers
10878                    .into_iter()
10879                    .map(|b| b.read(cx).remote_id().to_proto())
10880                    .collect(),
10881                only_servers: only_restart_servers
10882                    .into_iter()
10883                    .map(|selector| {
10884                        let selector = match selector {
10885                            LanguageServerSelector::Id(language_server_id) => {
10886                                proto::language_server_selector::Selector::ServerId(
10887                                    language_server_id.to_proto(),
10888                                )
10889                            }
10890                            LanguageServerSelector::Name(language_server_name) => {
10891                                proto::language_server_selector::Selector::Name(
10892                                    language_server_name.to_string(),
10893                                )
10894                            }
10895                        };
10896                        proto::LanguageServerSelector {
10897                            selector: Some(selector),
10898                        }
10899                    })
10900                    .collect(),
10901                all: false,
10902            });
10903            cx.background_spawn(request).detach_and_log_err(cx);
10904        } else {
10905            let stop_task = if only_restart_servers.is_empty() {
10906                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10907            } else {
10908                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10909            };
10910            cx.spawn(async move |lsp_store, cx| {
10911                stop_task.await;
10912                lsp_store
10913                    .update(cx, |lsp_store, cx| {
10914                        for buffer in buffers {
10915                            lsp_store.register_buffer_with_language_servers(
10916                                &buffer,
10917                                only_restart_servers.clone(),
10918                                true,
10919                                cx,
10920                            );
10921                        }
10922                    })
10923                    .ok()
10924            })
10925            .detach();
10926        }
10927    }
10928
10929    pub fn stop_language_servers_for_buffers(
10930        &mut self,
10931        buffers: Vec<Entity<Buffer>>,
10932        also_stop_servers: HashSet<LanguageServerSelector>,
10933        cx: &mut Context<Self>,
10934    ) -> Task<Result<()>> {
10935        if let Some((client, project_id)) = self.upstream_client() {
10936            let request = client.request(proto::StopLanguageServers {
10937                project_id,
10938                buffer_ids: buffers
10939                    .into_iter()
10940                    .map(|b| b.read(cx).remote_id().to_proto())
10941                    .collect(),
10942                also_servers: also_stop_servers
10943                    .into_iter()
10944                    .map(|selector| {
10945                        let selector = match selector {
10946                            LanguageServerSelector::Id(language_server_id) => {
10947                                proto::language_server_selector::Selector::ServerId(
10948                                    language_server_id.to_proto(),
10949                                )
10950                            }
10951                            LanguageServerSelector::Name(language_server_name) => {
10952                                proto::language_server_selector::Selector::Name(
10953                                    language_server_name.to_string(),
10954                                )
10955                            }
10956                        };
10957                        proto::LanguageServerSelector {
10958                            selector: Some(selector),
10959                        }
10960                    })
10961                    .collect(),
10962                all: false,
10963            });
10964            cx.background_spawn(async move {
10965                let _ = request.await?;
10966                Ok(())
10967            })
10968        } else {
10969            let task =
10970                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10971            cx.background_spawn(async move {
10972                task.await;
10973                Ok(())
10974            })
10975        }
10976    }
10977
10978    fn stop_local_language_servers_for_buffers(
10979        &mut self,
10980        buffers: &[Entity<Buffer>],
10981        also_stop_servers: HashSet<LanguageServerSelector>,
10982        cx: &mut Context<Self>,
10983    ) -> Task<()> {
10984        let Some(local) = self.as_local_mut() else {
10985            return Task::ready(());
10986        };
10987        let mut language_server_names_to_stop = BTreeSet::default();
10988        let mut language_servers_to_stop = also_stop_servers
10989            .into_iter()
10990            .flat_map(|selector| match selector {
10991                LanguageServerSelector::Id(id) => Some(id),
10992                LanguageServerSelector::Name(name) => {
10993                    language_server_names_to_stop.insert(name);
10994                    None
10995                }
10996            })
10997            .collect::<BTreeSet<_>>();
10998
10999        let mut covered_worktrees = HashSet::default();
11000        for buffer in buffers {
11001            buffer.update(cx, |buffer, cx| {
11002                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11003                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11004                    && covered_worktrees.insert(worktree_id)
11005                {
11006                    language_server_names_to_stop.retain(|name| {
11007                        let old_ids_count = language_servers_to_stop.len();
11008                        let all_language_servers_with_this_name = local
11009                            .language_server_ids
11010                            .iter()
11011                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11012                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11013                        old_ids_count == language_servers_to_stop.len()
11014                    });
11015                }
11016            });
11017        }
11018        for name in language_server_names_to_stop {
11019            language_servers_to_stop.extend(
11020                local
11021                    .language_server_ids
11022                    .iter()
11023                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11024            );
11025        }
11026
11027        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11028        let tasks = language_servers_to_stop
11029            .into_iter()
11030            .map(|server| self.stop_local_language_server(server, cx))
11031            .collect::<Vec<_>>();
11032
11033        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11034    }
11035
11036    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11037        let (worktree, relative_path) =
11038            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11039
11040        let project_path = ProjectPath {
11041            worktree_id: worktree.read(cx).id(),
11042            path: relative_path,
11043        };
11044
11045        Some(
11046            self.buffer_store()
11047                .read(cx)
11048                .get_by_path(&project_path)?
11049                .read(cx),
11050        )
11051    }
11052
11053    #[cfg(any(test, feature = "test-support"))]
11054    pub fn update_diagnostics(
11055        &mut self,
11056        server_id: LanguageServerId,
11057        diagnostics: lsp::PublishDiagnosticsParams,
11058        result_id: Option<SharedString>,
11059        source_kind: DiagnosticSourceKind,
11060        disk_based_sources: &[String],
11061        cx: &mut Context<Self>,
11062    ) -> Result<()> {
11063        self.merge_lsp_diagnostics(
11064            source_kind,
11065            vec![DocumentDiagnosticsUpdate {
11066                diagnostics,
11067                result_id,
11068                server_id,
11069                disk_based_sources: Cow::Borrowed(disk_based_sources),
11070                registration_id: None,
11071            }],
11072            |_, _, _| false,
11073            cx,
11074        )
11075    }
11076
11077    pub fn merge_lsp_diagnostics(
11078        &mut self,
11079        source_kind: DiagnosticSourceKind,
11080        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11081        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11082        cx: &mut Context<Self>,
11083    ) -> Result<()> {
11084        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11085        let updates = lsp_diagnostics
11086            .into_iter()
11087            .filter_map(|update| {
11088                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11089                Some(DocumentDiagnosticsUpdate {
11090                    diagnostics: self.lsp_to_document_diagnostics(
11091                        abs_path,
11092                        source_kind,
11093                        update.server_id,
11094                        update.diagnostics,
11095                        &update.disk_based_sources,
11096                        update.registration_id.clone(),
11097                    ),
11098                    result_id: update.result_id,
11099                    server_id: update.server_id,
11100                    disk_based_sources: update.disk_based_sources,
11101                    registration_id: update.registration_id,
11102                })
11103            })
11104            .collect();
11105        self.merge_diagnostic_entries(updates, merge, cx)?;
11106        Ok(())
11107    }
11108
11109    fn lsp_to_document_diagnostics(
11110        &mut self,
11111        document_abs_path: PathBuf,
11112        source_kind: DiagnosticSourceKind,
11113        server_id: LanguageServerId,
11114        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11115        disk_based_sources: &[String],
11116        registration_id: Option<SharedString>,
11117    ) -> DocumentDiagnostics {
11118        let mut diagnostics = Vec::default();
11119        let mut primary_diagnostic_group_ids = HashMap::default();
11120        let mut sources_by_group_id = HashMap::default();
11121        let mut supporting_diagnostics = HashMap::default();
11122
11123        let adapter = self.language_server_adapter_for_id(server_id);
11124
11125        // Ensure that primary diagnostics are always the most severe
11126        lsp_diagnostics
11127            .diagnostics
11128            .sort_by_key(|item| item.severity);
11129
11130        for diagnostic in &lsp_diagnostics.diagnostics {
11131            let source = diagnostic.source.as_ref();
11132            let range = range_from_lsp(diagnostic.range);
11133            let is_supporting = diagnostic
11134                .related_information
11135                .as_ref()
11136                .is_some_and(|infos| {
11137                    infos.iter().any(|info| {
11138                        primary_diagnostic_group_ids.contains_key(&(
11139                            source,
11140                            diagnostic.code.clone(),
11141                            range_from_lsp(info.location.range),
11142                        ))
11143                    })
11144                });
11145
11146            let is_unnecessary = diagnostic
11147                .tags
11148                .as_ref()
11149                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11150
11151            let underline = self
11152                .language_server_adapter_for_id(server_id)
11153                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11154
11155            if is_supporting {
11156                supporting_diagnostics.insert(
11157                    (source, diagnostic.code.clone(), range),
11158                    (diagnostic.severity, is_unnecessary),
11159                );
11160            } else {
11161                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11162                let is_disk_based =
11163                    source.is_some_and(|source| disk_based_sources.contains(source));
11164
11165                sources_by_group_id.insert(group_id, source);
11166                primary_diagnostic_group_ids
11167                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11168
11169                diagnostics.push(DiagnosticEntry {
11170                    range,
11171                    diagnostic: Diagnostic {
11172                        source: diagnostic.source.clone(),
11173                        source_kind,
11174                        code: diagnostic.code.clone(),
11175                        code_description: diagnostic
11176                            .code_description
11177                            .as_ref()
11178                            .and_then(|d| d.href.clone()),
11179                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11180                        markdown: adapter.as_ref().and_then(|adapter| {
11181                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11182                        }),
11183                        message: diagnostic.message.trim().to_string(),
11184                        group_id,
11185                        is_primary: true,
11186                        is_disk_based,
11187                        is_unnecessary,
11188                        underline,
11189                        data: diagnostic.data.clone(),
11190                        registration_id: registration_id.clone(),
11191                    },
11192                });
11193                if let Some(infos) = &diagnostic.related_information {
11194                    for info in infos {
11195                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11196                            let range = range_from_lsp(info.location.range);
11197                            diagnostics.push(DiagnosticEntry {
11198                                range,
11199                                diagnostic: Diagnostic {
11200                                    source: diagnostic.source.clone(),
11201                                    source_kind,
11202                                    code: diagnostic.code.clone(),
11203                                    code_description: diagnostic
11204                                        .code_description
11205                                        .as_ref()
11206                                        .and_then(|d| d.href.clone()),
11207                                    severity: DiagnosticSeverity::INFORMATION,
11208                                    markdown: adapter.as_ref().and_then(|adapter| {
11209                                        adapter.diagnostic_message_to_markdown(&info.message)
11210                                    }),
11211                                    message: info.message.trim().to_string(),
11212                                    group_id,
11213                                    is_primary: false,
11214                                    is_disk_based,
11215                                    is_unnecessary: false,
11216                                    underline,
11217                                    data: diagnostic.data.clone(),
11218                                    registration_id: registration_id.clone(),
11219                                },
11220                            });
11221                        }
11222                    }
11223                }
11224            }
11225        }
11226
11227        for entry in &mut diagnostics {
11228            let diagnostic = &mut entry.diagnostic;
11229            if !diagnostic.is_primary {
11230                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11231                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11232                    source,
11233                    diagnostic.code.clone(),
11234                    entry.range.clone(),
11235                )) {
11236                    if let Some(severity) = severity {
11237                        diagnostic.severity = severity;
11238                    }
11239                    diagnostic.is_unnecessary = is_unnecessary;
11240                }
11241            }
11242        }
11243
11244        DocumentDiagnostics {
11245            diagnostics,
11246            document_abs_path,
11247            version: lsp_diagnostics.version,
11248        }
11249    }
11250
11251    fn insert_newly_running_language_server(
11252        &mut self,
11253        adapter: Arc<CachedLspAdapter>,
11254        language_server: Arc<LanguageServer>,
11255        server_id: LanguageServerId,
11256        key: LanguageServerSeed,
11257        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11258        cx: &mut Context<Self>,
11259    ) {
11260        let Some(local) = self.as_local_mut() else {
11261            return;
11262        };
11263        // If the language server for this key doesn't match the server id, don't store the
11264        // server. Which will cause it to be dropped, killing the process
11265        if local
11266            .language_server_ids
11267            .get(&key)
11268            .map(|state| state.id != server_id)
11269            .unwrap_or(false)
11270        {
11271            return;
11272        }
11273
11274        // Update language_servers collection with Running variant of LanguageServerState
11275        // indicating that the server is up and running and ready
11276        let workspace_folders = workspace_folders.lock().clone();
11277        language_server.set_workspace_folders(workspace_folders);
11278
11279        let workspace_diagnostics_refresh_tasks = language_server
11280            .capabilities()
11281            .diagnostic_provider
11282            .and_then(|provider| {
11283                local
11284                    .language_server_dynamic_registrations
11285                    .entry(server_id)
11286                    .or_default()
11287                    .diagnostics
11288                    .entry(None)
11289                    .or_insert(provider.clone());
11290                let workspace_refresher =
11291                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11292
11293                Some((None, workspace_refresher))
11294            })
11295            .into_iter()
11296            .collect();
11297        local.language_servers.insert(
11298            server_id,
11299            LanguageServerState::Running {
11300                workspace_diagnostics_refresh_tasks,
11301                adapter: adapter.clone(),
11302                server: language_server.clone(),
11303                simulate_disk_based_diagnostics_completion: None,
11304            },
11305        );
11306        local
11307            .languages
11308            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11309        if let Some(file_ops_caps) = language_server
11310            .capabilities()
11311            .workspace
11312            .as_ref()
11313            .and_then(|ws| ws.file_operations.as_ref())
11314        {
11315            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11316            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11317            if did_rename_caps.or(will_rename_caps).is_some() {
11318                let watcher = RenamePathsWatchedForServer::default()
11319                    .with_did_rename_patterns(did_rename_caps)
11320                    .with_will_rename_patterns(will_rename_caps);
11321                local
11322                    .language_server_paths_watched_for_rename
11323                    .insert(server_id, watcher);
11324            }
11325        }
11326
11327        self.language_server_statuses.insert(
11328            server_id,
11329            LanguageServerStatus {
11330                name: language_server.name(),
11331                pending_work: Default::default(),
11332                has_pending_diagnostic_updates: false,
11333                progress_tokens: Default::default(),
11334                worktree: Some(key.worktree_id),
11335                binary: Some(language_server.binary().clone()),
11336                configuration: Some(language_server.configuration().clone()),
11337                workspace_folders: language_server.workspace_folders(),
11338            },
11339        );
11340
11341        cx.emit(LspStoreEvent::LanguageServerAdded(
11342            server_id,
11343            language_server.name(),
11344            Some(key.worktree_id),
11345        ));
11346
11347        let server_capabilities = language_server.capabilities();
11348        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11349            downstream_client
11350                .send(proto::StartLanguageServer {
11351                    project_id: *project_id,
11352                    server: Some(proto::LanguageServer {
11353                        id: server_id.to_proto(),
11354                        name: language_server.name().to_string(),
11355                        worktree_id: Some(key.worktree_id.to_proto()),
11356                    }),
11357                    capabilities: serde_json::to_string(&server_capabilities)
11358                        .expect("serializing server LSP capabilities"),
11359                })
11360                .log_err();
11361        }
11362        self.lsp_server_capabilities
11363            .insert(server_id, server_capabilities);
11364
11365        // Tell the language server about every open buffer in the worktree that matches the language.
11366        // Also check for buffers in worktrees that reused this server
11367        let mut worktrees_using_server = vec![key.worktree_id];
11368        if let Some(local) = self.as_local() {
11369            // Find all worktrees that have this server in their language server tree
11370            for (worktree_id, servers) in &local.lsp_tree.instances {
11371                if *worktree_id != key.worktree_id {
11372                    for server_map in servers.roots.values() {
11373                        if server_map
11374                            .values()
11375                            .any(|(node, _)| node.id() == Some(server_id))
11376                        {
11377                            worktrees_using_server.push(*worktree_id);
11378                        }
11379                    }
11380                }
11381            }
11382        }
11383
11384        let mut buffer_paths_registered = Vec::new();
11385        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11386            let mut lsp_adapters = HashMap::default();
11387            for buffer_handle in buffer_store.buffers() {
11388                let buffer = buffer_handle.read(cx);
11389                let file = match File::from_dyn(buffer.file()) {
11390                    Some(file) => file,
11391                    None => continue,
11392                };
11393                let language = match buffer.language() {
11394                    Some(language) => language,
11395                    None => continue,
11396                };
11397
11398                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11399                    || !lsp_adapters
11400                        .entry(language.name())
11401                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11402                        .iter()
11403                        .any(|a| a.name == key.name)
11404                {
11405                    continue;
11406                }
11407                // didOpen
11408                let file = match file.as_local() {
11409                    Some(file) => file,
11410                    None => continue,
11411                };
11412
11413                let local = self.as_local_mut().unwrap();
11414
11415                let buffer_id = buffer.remote_id();
11416                if local.registered_buffers.contains_key(&buffer_id) {
11417                    let versions = local
11418                        .buffer_snapshots
11419                        .entry(buffer_id)
11420                        .or_default()
11421                        .entry(server_id)
11422                        .and_modify(|_| {
11423                            assert!(
11424                            false,
11425                            "There should not be an existing snapshot for a newly inserted buffer"
11426                        )
11427                        })
11428                        .or_insert_with(|| {
11429                            vec![LspBufferSnapshot {
11430                                version: 0,
11431                                snapshot: buffer.text_snapshot(),
11432                            }]
11433                        });
11434
11435                    let snapshot = versions.last().unwrap();
11436                    let version = snapshot.version;
11437                    let initial_snapshot = &snapshot.snapshot;
11438                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11439                    language_server.register_buffer(
11440                        uri,
11441                        adapter.language_id(&language.name()),
11442                        version,
11443                        initial_snapshot.text(),
11444                    );
11445                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11446                    local
11447                        .buffers_opened_in_servers
11448                        .entry(buffer_id)
11449                        .or_default()
11450                        .insert(server_id);
11451                }
11452                buffer_handle.update(cx, |buffer, cx| {
11453                    buffer.set_completion_triggers(
11454                        server_id,
11455                        language_server
11456                            .capabilities()
11457                            .completion_provider
11458                            .as_ref()
11459                            .and_then(|provider| {
11460                                provider
11461                                    .trigger_characters
11462                                    .as_ref()
11463                                    .map(|characters| characters.iter().cloned().collect())
11464                            })
11465                            .unwrap_or_default(),
11466                        cx,
11467                    )
11468                });
11469            }
11470        });
11471
11472        for (buffer_id, abs_path) in buffer_paths_registered {
11473            cx.emit(LspStoreEvent::LanguageServerUpdate {
11474                language_server_id: server_id,
11475                name: Some(adapter.name()),
11476                message: proto::update_language_server::Variant::RegisteredForBuffer(
11477                    proto::RegisteredForBuffer {
11478                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11479                        buffer_id: buffer_id.to_proto(),
11480                    },
11481                ),
11482            });
11483        }
11484
11485        cx.notify();
11486    }
11487
11488    pub fn language_servers_running_disk_based_diagnostics(
11489        &self,
11490    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11491        self.language_server_statuses
11492            .iter()
11493            .filter_map(|(id, status)| {
11494                if status.has_pending_diagnostic_updates {
11495                    Some(*id)
11496                } else {
11497                    None
11498                }
11499            })
11500    }
11501
11502    pub(crate) fn cancel_language_server_work_for_buffers(
11503        &mut self,
11504        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11505        cx: &mut Context<Self>,
11506    ) {
11507        if let Some((client, project_id)) = self.upstream_client() {
11508            let request = client.request(proto::CancelLanguageServerWork {
11509                project_id,
11510                work: Some(proto::cancel_language_server_work::Work::Buffers(
11511                    proto::cancel_language_server_work::Buffers {
11512                        buffer_ids: buffers
11513                            .into_iter()
11514                            .map(|b| b.read(cx).remote_id().to_proto())
11515                            .collect(),
11516                    },
11517                )),
11518            });
11519            cx.background_spawn(request).detach_and_log_err(cx);
11520        } else if let Some(local) = self.as_local() {
11521            let servers = buffers
11522                .into_iter()
11523                .flat_map(|buffer| {
11524                    buffer.update(cx, |buffer, cx| {
11525                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11526                    })
11527                })
11528                .collect::<HashSet<_>>();
11529            for server_id in servers {
11530                self.cancel_language_server_work(server_id, None, cx);
11531            }
11532        }
11533    }
11534
11535    pub(crate) fn cancel_language_server_work(
11536        &mut self,
11537        server_id: LanguageServerId,
11538        token_to_cancel: Option<ProgressToken>,
11539        cx: &mut Context<Self>,
11540    ) {
11541        if let Some(local) = self.as_local() {
11542            let status = self.language_server_statuses.get(&server_id);
11543            let server = local.language_servers.get(&server_id);
11544            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11545            {
11546                for (token, progress) in &status.pending_work {
11547                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11548                        && token != token_to_cancel
11549                    {
11550                        continue;
11551                    }
11552                    if progress.is_cancellable {
11553                        server
11554                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11555                                WorkDoneProgressCancelParams {
11556                                    token: token.to_lsp(),
11557                                },
11558                            )
11559                            .ok();
11560                    }
11561                }
11562            }
11563        } else if let Some((client, project_id)) = self.upstream_client() {
11564            let request = client.request(proto::CancelLanguageServerWork {
11565                project_id,
11566                work: Some(
11567                    proto::cancel_language_server_work::Work::LanguageServerWork(
11568                        proto::cancel_language_server_work::LanguageServerWork {
11569                            language_server_id: server_id.to_proto(),
11570                            token: token_to_cancel.map(|token| token.to_proto()),
11571                        },
11572                    ),
11573                ),
11574            });
11575            cx.background_spawn(request).detach_and_log_err(cx);
11576        }
11577    }
11578
11579    fn register_supplementary_language_server(
11580        &mut self,
11581        id: LanguageServerId,
11582        name: LanguageServerName,
11583        server: Arc<LanguageServer>,
11584        cx: &mut Context<Self>,
11585    ) {
11586        if let Some(local) = self.as_local_mut() {
11587            local
11588                .supplementary_language_servers
11589                .insert(id, (name.clone(), server));
11590            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11591        }
11592    }
11593
11594    fn unregister_supplementary_language_server(
11595        &mut self,
11596        id: LanguageServerId,
11597        cx: &mut Context<Self>,
11598    ) {
11599        if let Some(local) = self.as_local_mut() {
11600            local.supplementary_language_servers.remove(&id);
11601            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11602        }
11603    }
11604
11605    pub(crate) fn supplementary_language_servers(
11606        &self,
11607    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11608        self.as_local().into_iter().flat_map(|local| {
11609            local
11610                .supplementary_language_servers
11611                .iter()
11612                .map(|(id, (name, _))| (*id, name.clone()))
11613        })
11614    }
11615
11616    pub fn language_server_adapter_for_id(
11617        &self,
11618        id: LanguageServerId,
11619    ) -> Option<Arc<CachedLspAdapter>> {
11620        self.as_local()
11621            .and_then(|local| local.language_servers.get(&id))
11622            .and_then(|language_server_state| match language_server_state {
11623                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11624                _ => None,
11625            })
11626    }
11627
11628    pub(super) fn update_local_worktree_language_servers(
11629        &mut self,
11630        worktree_handle: &Entity<Worktree>,
11631        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11632        cx: &mut Context<Self>,
11633    ) {
11634        if changes.is_empty() {
11635            return;
11636        }
11637
11638        let Some(local) = self.as_local() else { return };
11639
11640        local.prettier_store.update(cx, |prettier_store, cx| {
11641            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11642        });
11643
11644        let worktree_id = worktree_handle.read(cx).id();
11645        let mut language_server_ids = local
11646            .language_server_ids
11647            .iter()
11648            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11649            .collect::<Vec<_>>();
11650        language_server_ids.sort();
11651        language_server_ids.dedup();
11652
11653        // let abs_path = worktree_handle.read(cx).abs_path();
11654        for server_id in &language_server_ids {
11655            if let Some(LanguageServerState::Running { server, .. }) =
11656                local.language_servers.get(server_id)
11657                && let Some(watched_paths) = local
11658                    .language_server_watched_paths
11659                    .get(server_id)
11660                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11661            {
11662                let params = lsp::DidChangeWatchedFilesParams {
11663                    changes: changes
11664                        .iter()
11665                        .filter_map(|(path, _, change)| {
11666                            if !watched_paths.is_match(path.as_std_path()) {
11667                                return None;
11668                            }
11669                            let typ = match change {
11670                                PathChange::Loaded => return None,
11671                                PathChange::Added => lsp::FileChangeType::CREATED,
11672                                PathChange::Removed => lsp::FileChangeType::DELETED,
11673                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11674                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11675                            };
11676                            let uri = lsp::Uri::from_file_path(
11677                                worktree_handle.read(cx).absolutize(&path),
11678                            )
11679                            .ok()?;
11680                            Some(lsp::FileEvent { uri, typ })
11681                        })
11682                        .collect(),
11683                };
11684                if !params.changes.is_empty() {
11685                    server
11686                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11687                        .ok();
11688                }
11689            }
11690        }
11691        for (path, _, _) in changes {
11692            if let Some(file_name) = path.file_name()
11693                && local.watched_manifest_filenames.contains(file_name)
11694            {
11695                self.request_workspace_config_refresh();
11696                break;
11697            }
11698        }
11699    }
11700
11701    pub fn wait_for_remote_buffer(
11702        &mut self,
11703        id: BufferId,
11704        cx: &mut Context<Self>,
11705    ) -> Task<Result<Entity<Buffer>>> {
11706        self.buffer_store.update(cx, |buffer_store, cx| {
11707            buffer_store.wait_for_remote_buffer(id, cx)
11708        })
11709    }
11710
11711    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11712        let mut result = proto::Symbol {
11713            language_server_name: symbol.language_server_name.0.to_string(),
11714            source_worktree_id: symbol.source_worktree_id.to_proto(),
11715            language_server_id: symbol.source_language_server_id.to_proto(),
11716            name: symbol.name.clone(),
11717            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11718            start: Some(proto::PointUtf16 {
11719                row: symbol.range.start.0.row,
11720                column: symbol.range.start.0.column,
11721            }),
11722            end: Some(proto::PointUtf16 {
11723                row: symbol.range.end.0.row,
11724                column: symbol.range.end.0.column,
11725            }),
11726            worktree_id: Default::default(),
11727            path: Default::default(),
11728            signature: Default::default(),
11729        };
11730        match &symbol.path {
11731            SymbolLocation::InProject(path) => {
11732                result.worktree_id = path.worktree_id.to_proto();
11733                result.path = path.path.to_proto();
11734            }
11735            SymbolLocation::OutsideProject {
11736                abs_path,
11737                signature,
11738            } => {
11739                result.path = abs_path.to_string_lossy().into_owned();
11740                result.signature = signature.to_vec();
11741            }
11742        }
11743        result
11744    }
11745
11746    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11747        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11748        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11749        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11750
11751        let path = if serialized_symbol.signature.is_empty() {
11752            SymbolLocation::InProject(ProjectPath {
11753                worktree_id,
11754                path: RelPath::from_proto(&serialized_symbol.path)
11755                    .context("invalid symbol path")?,
11756            })
11757        } else {
11758            SymbolLocation::OutsideProject {
11759                abs_path: Path::new(&serialized_symbol.path).into(),
11760                signature: serialized_symbol
11761                    .signature
11762                    .try_into()
11763                    .map_err(|_| anyhow!("invalid signature"))?,
11764            }
11765        };
11766
11767        let start = serialized_symbol.start.context("invalid start")?;
11768        let end = serialized_symbol.end.context("invalid end")?;
11769        Ok(CoreSymbol {
11770            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11771            source_worktree_id,
11772            source_language_server_id: LanguageServerId::from_proto(
11773                serialized_symbol.language_server_id,
11774            ),
11775            path,
11776            name: serialized_symbol.name,
11777            range: Unclipped(PointUtf16::new(start.row, start.column))
11778                ..Unclipped(PointUtf16::new(end.row, end.column)),
11779            kind,
11780        })
11781    }
11782
11783    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11784        let mut serialized_completion = proto::Completion {
11785            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11786            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11787            new_text: completion.new_text.clone(),
11788            ..proto::Completion::default()
11789        };
11790        match &completion.source {
11791            CompletionSource::Lsp {
11792                insert_range,
11793                server_id,
11794                lsp_completion,
11795                lsp_defaults,
11796                resolved,
11797            } => {
11798                let (old_insert_start, old_insert_end) = insert_range
11799                    .as_ref()
11800                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11801                    .unzip();
11802
11803                serialized_completion.old_insert_start = old_insert_start;
11804                serialized_completion.old_insert_end = old_insert_end;
11805                serialized_completion.source = proto::completion::Source::Lsp as i32;
11806                serialized_completion.server_id = server_id.0 as u64;
11807                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11808                serialized_completion.lsp_defaults = lsp_defaults
11809                    .as_deref()
11810                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11811                serialized_completion.resolved = *resolved;
11812            }
11813            CompletionSource::BufferWord {
11814                word_range,
11815                resolved,
11816            } => {
11817                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11818                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11819                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11820                serialized_completion.resolved = *resolved;
11821            }
11822            CompletionSource::Custom => {
11823                serialized_completion.source = proto::completion::Source::Custom as i32;
11824                serialized_completion.resolved = true;
11825            }
11826            CompletionSource::Dap { sort_text } => {
11827                serialized_completion.source = proto::completion::Source::Dap as i32;
11828                serialized_completion.sort_text = Some(sort_text.clone());
11829            }
11830        }
11831
11832        serialized_completion
11833    }
11834
11835    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11836        let old_replace_start = completion
11837            .old_replace_start
11838            .and_then(deserialize_anchor)
11839            .context("invalid old start")?;
11840        let old_replace_end = completion
11841            .old_replace_end
11842            .and_then(deserialize_anchor)
11843            .context("invalid old end")?;
11844        let insert_range = {
11845            match completion.old_insert_start.zip(completion.old_insert_end) {
11846                Some((start, end)) => {
11847                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11848                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11849                    Some(start..end)
11850                }
11851                None => None,
11852            }
11853        };
11854        Ok(CoreCompletion {
11855            replace_range: old_replace_start..old_replace_end,
11856            new_text: completion.new_text,
11857            source: match proto::completion::Source::from_i32(completion.source) {
11858                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11859                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11860                    insert_range,
11861                    server_id: LanguageServerId::from_proto(completion.server_id),
11862                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11863                    lsp_defaults: completion
11864                        .lsp_defaults
11865                        .as_deref()
11866                        .map(serde_json::from_slice)
11867                        .transpose()?,
11868                    resolved: completion.resolved,
11869                },
11870                Some(proto::completion::Source::BufferWord) => {
11871                    let word_range = completion
11872                        .buffer_word_start
11873                        .and_then(deserialize_anchor)
11874                        .context("invalid buffer word start")?
11875                        ..completion
11876                            .buffer_word_end
11877                            .and_then(deserialize_anchor)
11878                            .context("invalid buffer word end")?;
11879                    CompletionSource::BufferWord {
11880                        word_range,
11881                        resolved: completion.resolved,
11882                    }
11883                }
11884                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11885                    sort_text: completion
11886                        .sort_text
11887                        .context("expected sort text to exist")?,
11888                },
11889                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11890            },
11891        })
11892    }
11893
11894    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11895        let (kind, lsp_action) = match &action.lsp_action {
11896            LspAction::Action(code_action) => (
11897                proto::code_action::Kind::Action as i32,
11898                serde_json::to_vec(code_action).unwrap(),
11899            ),
11900            LspAction::Command(command) => (
11901                proto::code_action::Kind::Command as i32,
11902                serde_json::to_vec(command).unwrap(),
11903            ),
11904            LspAction::CodeLens(code_lens) => (
11905                proto::code_action::Kind::CodeLens as i32,
11906                serde_json::to_vec(code_lens).unwrap(),
11907            ),
11908        };
11909
11910        proto::CodeAction {
11911            server_id: action.server_id.0 as u64,
11912            start: Some(serialize_anchor(&action.range.start)),
11913            end: Some(serialize_anchor(&action.range.end)),
11914            lsp_action,
11915            kind,
11916            resolved: action.resolved,
11917        }
11918    }
11919
11920    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11921        let start = action
11922            .start
11923            .and_then(deserialize_anchor)
11924            .context("invalid start")?;
11925        let end = action
11926            .end
11927            .and_then(deserialize_anchor)
11928            .context("invalid end")?;
11929        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11930            Some(proto::code_action::Kind::Action) => {
11931                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11932            }
11933            Some(proto::code_action::Kind::Command) => {
11934                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11935            }
11936            Some(proto::code_action::Kind::CodeLens) => {
11937                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11938            }
11939            None => anyhow::bail!("Unknown action kind {}", action.kind),
11940        };
11941        Ok(CodeAction {
11942            server_id: LanguageServerId(action.server_id as usize),
11943            range: start..end,
11944            resolved: action.resolved,
11945            lsp_action,
11946        })
11947    }
11948
11949    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11950        match &formatting_result {
11951            Ok(_) => self.last_formatting_failure = None,
11952            Err(error) => {
11953                let error_string = format!("{error:#}");
11954                log::error!("Formatting failed: {error_string}");
11955                self.last_formatting_failure
11956                    .replace(error_string.lines().join(" "));
11957            }
11958        }
11959    }
11960
11961    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11962        self.lsp_server_capabilities.remove(&for_server);
11963        for lsp_data in self.lsp_data.values_mut() {
11964            lsp_data.remove_server_data(for_server);
11965        }
11966        if let Some(local) = self.as_local_mut() {
11967            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11968            local
11969                .workspace_pull_diagnostics_result_ids
11970                .remove(&for_server);
11971            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11972                buffer_servers.remove(&for_server);
11973            }
11974        }
11975    }
11976
11977    pub fn result_id_for_buffer_pull(
11978        &self,
11979        server_id: LanguageServerId,
11980        buffer_id: BufferId,
11981        registration_id: &Option<SharedString>,
11982        cx: &App,
11983    ) -> Option<SharedString> {
11984        let abs_path = self
11985            .buffer_store
11986            .read(cx)
11987            .get(buffer_id)
11988            .and_then(|b| File::from_dyn(b.read(cx).file()))
11989            .map(|f| f.abs_path(cx))?;
11990        self.as_local()?
11991            .buffer_pull_diagnostics_result_ids
11992            .get(&server_id)?
11993            .get(registration_id)?
11994            .get(&abs_path)?
11995            .clone()
11996    }
11997
11998    /// Gets all result_ids for a workspace diagnostics pull request.
11999    /// 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.
12000    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12001    pub fn result_ids_for_workspace_refresh(
12002        &self,
12003        server_id: LanguageServerId,
12004        registration_id: &Option<SharedString>,
12005    ) -> HashMap<PathBuf, SharedString> {
12006        let Some(local) = self.as_local() else {
12007            return HashMap::default();
12008        };
12009        local
12010            .workspace_pull_diagnostics_result_ids
12011            .get(&server_id)
12012            .into_iter()
12013            .filter_map(|diagnostics| diagnostics.get(registration_id))
12014            .flatten()
12015            .filter_map(|(abs_path, result_id)| {
12016                let result_id = local
12017                    .buffer_pull_diagnostics_result_ids
12018                    .get(&server_id)
12019                    .and_then(|buffer_ids_result_ids| {
12020                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12021                    })
12022                    .cloned()
12023                    .flatten()
12024                    .or_else(|| result_id.clone())?;
12025                Some((abs_path.clone(), result_id))
12026            })
12027            .collect()
12028    }
12029
12030    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12031        if let Some(LanguageServerState::Running {
12032            workspace_diagnostics_refresh_tasks,
12033            ..
12034        }) = self
12035            .as_local_mut()
12036            .and_then(|local| local.language_servers.get_mut(&server_id))
12037        {
12038            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12039                diagnostics.refresh_tx.try_send(()).ok();
12040            }
12041        }
12042    }
12043
12044    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12045        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12046            return;
12047        };
12048        let Some(local) = self.as_local_mut() else {
12049            return;
12050        };
12051
12052        for server_id in buffer.update(cx, |buffer, cx| {
12053            local.language_server_ids_for_buffer(buffer, cx)
12054        }) {
12055            if let Some(LanguageServerState::Running {
12056                workspace_diagnostics_refresh_tasks,
12057                ..
12058            }) = local.language_servers.get_mut(&server_id)
12059            {
12060                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12061                    diagnostics.refresh_tx.try_send(()).ok();
12062                }
12063            }
12064        }
12065    }
12066
12067    fn apply_workspace_diagnostic_report(
12068        &mut self,
12069        server_id: LanguageServerId,
12070        report: lsp::WorkspaceDiagnosticReportResult,
12071        registration_id: Option<SharedString>,
12072        cx: &mut Context<Self>,
12073    ) {
12074        let workspace_diagnostics =
12075            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12076                report,
12077                server_id,
12078                registration_id,
12079            );
12080        let mut unchanged_buffers = HashMap::default();
12081        let workspace_diagnostics_updates = workspace_diagnostics
12082            .into_iter()
12083            .filter_map(
12084                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12085                    LspPullDiagnostics::Response {
12086                        server_id,
12087                        uri,
12088                        diagnostics,
12089                        registration_id,
12090                    } => Some((
12091                        server_id,
12092                        uri,
12093                        diagnostics,
12094                        workspace_diagnostics.version,
12095                        registration_id,
12096                    )),
12097                    LspPullDiagnostics::Default => None,
12098                },
12099            )
12100            .fold(
12101                HashMap::default(),
12102                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12103                    let (result_id, diagnostics) = match diagnostics {
12104                        PulledDiagnostics::Unchanged { result_id } => {
12105                            unchanged_buffers
12106                                .entry(new_registration_id.clone())
12107                                .or_insert_with(HashSet::default)
12108                                .insert(uri.clone());
12109                            (Some(result_id), Vec::new())
12110                        }
12111                        PulledDiagnostics::Changed {
12112                            result_id,
12113                            diagnostics,
12114                        } => (result_id, diagnostics),
12115                    };
12116                    let disk_based_sources = Cow::Owned(
12117                        self.language_server_adapter_for_id(server_id)
12118                            .as_ref()
12119                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12120                            .unwrap_or(&[])
12121                            .to_vec(),
12122                    );
12123
12124                    let Some(abs_path) = uri.to_file_path().ok() else {
12125                        return acc;
12126                    };
12127                    let Some((worktree, relative_path)) =
12128                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12129                    else {
12130                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12131                        return acc;
12132                    };
12133                    let worktree_id = worktree.read(cx).id();
12134                    let project_path = ProjectPath {
12135                        worktree_id,
12136                        path: relative_path,
12137                    };
12138                    if let Some(local_lsp_store) = self.as_local_mut() {
12139                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12140                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12141                    }
12142                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12143                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12144                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12145                        acc.entry(server_id)
12146                            .or_insert_with(HashMap::default)
12147                            .entry(new_registration_id.clone())
12148                            .or_insert_with(Vec::new)
12149                            .push(DocumentDiagnosticsUpdate {
12150                                server_id,
12151                                diagnostics: lsp::PublishDiagnosticsParams {
12152                                    uri,
12153                                    diagnostics,
12154                                    version,
12155                                },
12156                                result_id,
12157                                disk_based_sources,
12158                                registration_id: new_registration_id,
12159                            });
12160                    }
12161                    acc
12162                },
12163            );
12164
12165        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12166            for (registration_id, diagnostic_updates) in diagnostic_updates {
12167                self.merge_lsp_diagnostics(
12168                    DiagnosticSourceKind::Pulled,
12169                    diagnostic_updates,
12170                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12171                        DiagnosticSourceKind::Pulled => {
12172                            old_diagnostic.registration_id != registration_id
12173                                || unchanged_buffers
12174                                    .get(&old_diagnostic.registration_id)
12175                                    .is_some_and(|unchanged_buffers| {
12176                                        unchanged_buffers.contains(&document_uri)
12177                                    })
12178                        }
12179                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12180                    },
12181                    cx,
12182                )
12183                .log_err();
12184            }
12185        }
12186    }
12187
12188    fn register_server_capabilities(
12189        &mut self,
12190        server_id: LanguageServerId,
12191        params: lsp::RegistrationParams,
12192        cx: &mut Context<Self>,
12193    ) -> anyhow::Result<()> {
12194        let server = self
12195            .language_server_for_id(server_id)
12196            .with_context(|| format!("no server {server_id} found"))?;
12197        for reg in params.registrations {
12198            match reg.method.as_str() {
12199                "workspace/didChangeWatchedFiles" => {
12200                    if let Some(options) = reg.register_options {
12201                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12202                            let caps = serde_json::from_value(options)?;
12203                            local_lsp_store
12204                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12205                            true
12206                        } else {
12207                            false
12208                        };
12209                        if notify {
12210                            notify_server_capabilities_updated(&server, cx);
12211                        }
12212                    }
12213                }
12214                "workspace/didChangeConfiguration" => {
12215                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12216                }
12217                "workspace/didChangeWorkspaceFolders" => {
12218                    // In this case register options is an empty object, we can ignore it
12219                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12220                        supported: Some(true),
12221                        change_notifications: Some(OneOf::Right(reg.id)),
12222                    };
12223                    server.update_capabilities(|capabilities| {
12224                        capabilities
12225                            .workspace
12226                            .get_or_insert_default()
12227                            .workspace_folders = Some(caps);
12228                    });
12229                    notify_server_capabilities_updated(&server, cx);
12230                }
12231                "workspace/symbol" => {
12232                    let options = parse_register_capabilities(reg)?;
12233                    server.update_capabilities(|capabilities| {
12234                        capabilities.workspace_symbol_provider = Some(options);
12235                    });
12236                    notify_server_capabilities_updated(&server, cx);
12237                }
12238                "workspace/fileOperations" => {
12239                    if let Some(options) = reg.register_options {
12240                        let caps = serde_json::from_value(options)?;
12241                        server.update_capabilities(|capabilities| {
12242                            capabilities
12243                                .workspace
12244                                .get_or_insert_default()
12245                                .file_operations = Some(caps);
12246                        });
12247                        notify_server_capabilities_updated(&server, cx);
12248                    }
12249                }
12250                "workspace/executeCommand" => {
12251                    if let Some(options) = reg.register_options {
12252                        let options = serde_json::from_value(options)?;
12253                        server.update_capabilities(|capabilities| {
12254                            capabilities.execute_command_provider = Some(options);
12255                        });
12256                        notify_server_capabilities_updated(&server, cx);
12257                    }
12258                }
12259                "textDocument/rangeFormatting" => {
12260                    let options = parse_register_capabilities(reg)?;
12261                    server.update_capabilities(|capabilities| {
12262                        capabilities.document_range_formatting_provider = Some(options);
12263                    });
12264                    notify_server_capabilities_updated(&server, cx);
12265                }
12266                "textDocument/onTypeFormatting" => {
12267                    if let Some(options) = reg
12268                        .register_options
12269                        .map(serde_json::from_value)
12270                        .transpose()?
12271                    {
12272                        server.update_capabilities(|capabilities| {
12273                            capabilities.document_on_type_formatting_provider = Some(options);
12274                        });
12275                        notify_server_capabilities_updated(&server, cx);
12276                    }
12277                }
12278                "textDocument/formatting" => {
12279                    let options = parse_register_capabilities(reg)?;
12280                    server.update_capabilities(|capabilities| {
12281                        capabilities.document_formatting_provider = Some(options);
12282                    });
12283                    notify_server_capabilities_updated(&server, cx);
12284                }
12285                "textDocument/rename" => {
12286                    let options = parse_register_capabilities(reg)?;
12287                    server.update_capabilities(|capabilities| {
12288                        capabilities.rename_provider = Some(options);
12289                    });
12290                    notify_server_capabilities_updated(&server, cx);
12291                }
12292                "textDocument/inlayHint" => {
12293                    let options = parse_register_capabilities(reg)?;
12294                    server.update_capabilities(|capabilities| {
12295                        capabilities.inlay_hint_provider = Some(options);
12296                    });
12297                    notify_server_capabilities_updated(&server, cx);
12298                }
12299                "textDocument/documentSymbol" => {
12300                    let options = parse_register_capabilities(reg)?;
12301                    server.update_capabilities(|capabilities| {
12302                        capabilities.document_symbol_provider = Some(options);
12303                    });
12304                    notify_server_capabilities_updated(&server, cx);
12305                }
12306                "textDocument/codeAction" => {
12307                    let options = parse_register_capabilities(reg)?;
12308                    let provider = match options {
12309                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12310                        OneOf::Right(caps) => caps,
12311                    };
12312                    server.update_capabilities(|capabilities| {
12313                        capabilities.code_action_provider = Some(provider);
12314                    });
12315                    notify_server_capabilities_updated(&server, cx);
12316                }
12317                "textDocument/definition" => {
12318                    let options = parse_register_capabilities(reg)?;
12319                    server.update_capabilities(|capabilities| {
12320                        capabilities.definition_provider = Some(options);
12321                    });
12322                    notify_server_capabilities_updated(&server, cx);
12323                }
12324                "textDocument/completion" => {
12325                    if let Some(caps) = reg
12326                        .register_options
12327                        .map(serde_json::from_value::<CompletionOptions>)
12328                        .transpose()?
12329                    {
12330                        server.update_capabilities(|capabilities| {
12331                            capabilities.completion_provider = Some(caps.clone());
12332                        });
12333
12334                        if let Some(local) = self.as_local() {
12335                            let mut buffers_with_language_server = Vec::new();
12336                            for handle in self.buffer_store.read(cx).buffers() {
12337                                let buffer_id = handle.read(cx).remote_id();
12338                                if local
12339                                    .buffers_opened_in_servers
12340                                    .get(&buffer_id)
12341                                    .filter(|s| s.contains(&server_id))
12342                                    .is_some()
12343                                {
12344                                    buffers_with_language_server.push(handle);
12345                                }
12346                            }
12347                            let triggers = caps
12348                                .trigger_characters
12349                                .unwrap_or_default()
12350                                .into_iter()
12351                                .collect::<BTreeSet<_>>();
12352                            for handle in buffers_with_language_server {
12353                                let triggers = triggers.clone();
12354                                let _ = handle.update(cx, move |buffer, cx| {
12355                                    buffer.set_completion_triggers(server_id, triggers, cx);
12356                                });
12357                            }
12358                        }
12359                        notify_server_capabilities_updated(&server, cx);
12360                    }
12361                }
12362                "textDocument/hover" => {
12363                    let options = parse_register_capabilities(reg)?;
12364                    let provider = match options {
12365                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12366                        OneOf::Right(caps) => caps,
12367                    };
12368                    server.update_capabilities(|capabilities| {
12369                        capabilities.hover_provider = Some(provider);
12370                    });
12371                    notify_server_capabilities_updated(&server, cx);
12372                }
12373                "textDocument/signatureHelp" => {
12374                    if let Some(caps) = reg
12375                        .register_options
12376                        .map(serde_json::from_value)
12377                        .transpose()?
12378                    {
12379                        server.update_capabilities(|capabilities| {
12380                            capabilities.signature_help_provider = Some(caps);
12381                        });
12382                        notify_server_capabilities_updated(&server, cx);
12383                    }
12384                }
12385                "textDocument/didChange" => {
12386                    if let Some(sync_kind) = reg
12387                        .register_options
12388                        .and_then(|opts| opts.get("syncKind").cloned())
12389                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12390                        .transpose()?
12391                    {
12392                        server.update_capabilities(|capabilities| {
12393                            let mut sync_options =
12394                                Self::take_text_document_sync_options(capabilities);
12395                            sync_options.change = Some(sync_kind);
12396                            capabilities.text_document_sync =
12397                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12398                        });
12399                        notify_server_capabilities_updated(&server, cx);
12400                    }
12401                }
12402                "textDocument/didSave" => {
12403                    if let Some(include_text) = reg
12404                        .register_options
12405                        .map(|opts| {
12406                            let transpose = opts
12407                                .get("includeText")
12408                                .cloned()
12409                                .map(serde_json::from_value::<Option<bool>>)
12410                                .transpose();
12411                            match transpose {
12412                                Ok(value) => Ok(value.flatten()),
12413                                Err(e) => Err(e),
12414                            }
12415                        })
12416                        .transpose()?
12417                    {
12418                        server.update_capabilities(|capabilities| {
12419                            let mut sync_options =
12420                                Self::take_text_document_sync_options(capabilities);
12421                            sync_options.save =
12422                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12423                                    include_text,
12424                                }));
12425                            capabilities.text_document_sync =
12426                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12427                        });
12428                        notify_server_capabilities_updated(&server, cx);
12429                    }
12430                }
12431                "textDocument/codeLens" => {
12432                    if let Some(caps) = reg
12433                        .register_options
12434                        .map(serde_json::from_value)
12435                        .transpose()?
12436                    {
12437                        server.update_capabilities(|capabilities| {
12438                            capabilities.code_lens_provider = Some(caps);
12439                        });
12440                        notify_server_capabilities_updated(&server, cx);
12441                    }
12442                }
12443                "textDocument/diagnostic" => {
12444                    if let Some(caps) = reg
12445                        .register_options
12446                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12447                        .transpose()?
12448                    {
12449                        let local = self
12450                            .as_local_mut()
12451                            .context("Expected LSP Store to be local")?;
12452                        let state = local
12453                            .language_servers
12454                            .get_mut(&server_id)
12455                            .context("Could not obtain Language Servers state")?;
12456                        local
12457                            .language_server_dynamic_registrations
12458                            .entry(server_id)
12459                            .or_default()
12460                            .diagnostics
12461                            .insert(Some(reg.id.clone()), caps.clone());
12462
12463                        let supports_workspace_diagnostics =
12464                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12465                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12466                                    diagnostic_options.workspace_diagnostics
12467                                }
12468                                DiagnosticServerCapabilities::RegistrationOptions(
12469                                    diagnostic_registration_options,
12470                                ) => {
12471                                    diagnostic_registration_options
12472                                        .diagnostic_options
12473                                        .workspace_diagnostics
12474                                }
12475                            };
12476
12477                        if supports_workspace_diagnostics(&caps) {
12478                            if let LanguageServerState::Running {
12479                                workspace_diagnostics_refresh_tasks,
12480                                ..
12481                            } = state
12482                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12483                                    Some(reg.id.clone()),
12484                                    caps.clone(),
12485                                    server.clone(),
12486                                    cx,
12487                                )
12488                            {
12489                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12490                            }
12491                        }
12492
12493                        server.update_capabilities(|capabilities| {
12494                            capabilities.diagnostic_provider = Some(caps);
12495                        });
12496
12497                        notify_server_capabilities_updated(&server, cx);
12498                    }
12499                }
12500                "textDocument/documentColor" => {
12501                    let options = parse_register_capabilities(reg)?;
12502                    let provider = match options {
12503                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12504                        OneOf::Right(caps) => caps,
12505                    };
12506                    server.update_capabilities(|capabilities| {
12507                        capabilities.color_provider = Some(provider);
12508                    });
12509                    notify_server_capabilities_updated(&server, cx);
12510                }
12511                _ => log::warn!("unhandled capability registration: {reg:?}"),
12512            }
12513        }
12514
12515        Ok(())
12516    }
12517
12518    fn unregister_server_capabilities(
12519        &mut self,
12520        server_id: LanguageServerId,
12521        params: lsp::UnregistrationParams,
12522        cx: &mut Context<Self>,
12523    ) -> anyhow::Result<()> {
12524        let server = self
12525            .language_server_for_id(server_id)
12526            .with_context(|| format!("no server {server_id} found"))?;
12527        for unreg in params.unregisterations.iter() {
12528            match unreg.method.as_str() {
12529                "workspace/didChangeWatchedFiles" => {
12530                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12531                        local_lsp_store
12532                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12533                        true
12534                    } else {
12535                        false
12536                    };
12537                    if notify {
12538                        notify_server_capabilities_updated(&server, cx);
12539                    }
12540                }
12541                "workspace/didChangeConfiguration" => {
12542                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12543                }
12544                "workspace/didChangeWorkspaceFolders" => {
12545                    server.update_capabilities(|capabilities| {
12546                        capabilities
12547                            .workspace
12548                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12549                                workspace_folders: None,
12550                                file_operations: None,
12551                            })
12552                            .workspace_folders = None;
12553                    });
12554                    notify_server_capabilities_updated(&server, cx);
12555                }
12556                "workspace/symbol" => {
12557                    server.update_capabilities(|capabilities| {
12558                        capabilities.workspace_symbol_provider = None
12559                    });
12560                    notify_server_capabilities_updated(&server, cx);
12561                }
12562                "workspace/fileOperations" => {
12563                    server.update_capabilities(|capabilities| {
12564                        capabilities
12565                            .workspace
12566                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12567                                workspace_folders: None,
12568                                file_operations: None,
12569                            })
12570                            .file_operations = None;
12571                    });
12572                    notify_server_capabilities_updated(&server, cx);
12573                }
12574                "workspace/executeCommand" => {
12575                    server.update_capabilities(|capabilities| {
12576                        capabilities.execute_command_provider = None;
12577                    });
12578                    notify_server_capabilities_updated(&server, cx);
12579                }
12580                "textDocument/rangeFormatting" => {
12581                    server.update_capabilities(|capabilities| {
12582                        capabilities.document_range_formatting_provider = None
12583                    });
12584                    notify_server_capabilities_updated(&server, cx);
12585                }
12586                "textDocument/onTypeFormatting" => {
12587                    server.update_capabilities(|capabilities| {
12588                        capabilities.document_on_type_formatting_provider = None;
12589                    });
12590                    notify_server_capabilities_updated(&server, cx);
12591                }
12592                "textDocument/formatting" => {
12593                    server.update_capabilities(|capabilities| {
12594                        capabilities.document_formatting_provider = None;
12595                    });
12596                    notify_server_capabilities_updated(&server, cx);
12597                }
12598                "textDocument/rename" => {
12599                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12600                    notify_server_capabilities_updated(&server, cx);
12601                }
12602                "textDocument/codeAction" => {
12603                    server.update_capabilities(|capabilities| {
12604                        capabilities.code_action_provider = None;
12605                    });
12606                    notify_server_capabilities_updated(&server, cx);
12607                }
12608                "textDocument/definition" => {
12609                    server.update_capabilities(|capabilities| {
12610                        capabilities.definition_provider = None;
12611                    });
12612                    notify_server_capabilities_updated(&server, cx);
12613                }
12614                "textDocument/completion" => {
12615                    server.update_capabilities(|capabilities| {
12616                        capabilities.completion_provider = None;
12617                    });
12618                    notify_server_capabilities_updated(&server, cx);
12619                }
12620                "textDocument/hover" => {
12621                    server.update_capabilities(|capabilities| {
12622                        capabilities.hover_provider = None;
12623                    });
12624                    notify_server_capabilities_updated(&server, cx);
12625                }
12626                "textDocument/signatureHelp" => {
12627                    server.update_capabilities(|capabilities| {
12628                        capabilities.signature_help_provider = None;
12629                    });
12630                    notify_server_capabilities_updated(&server, cx);
12631                }
12632                "textDocument/didChange" => {
12633                    server.update_capabilities(|capabilities| {
12634                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12635                        sync_options.change = None;
12636                        capabilities.text_document_sync =
12637                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12638                    });
12639                    notify_server_capabilities_updated(&server, cx);
12640                }
12641                "textDocument/didSave" => {
12642                    server.update_capabilities(|capabilities| {
12643                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12644                        sync_options.save = None;
12645                        capabilities.text_document_sync =
12646                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12647                    });
12648                    notify_server_capabilities_updated(&server, cx);
12649                }
12650                "textDocument/codeLens" => {
12651                    server.update_capabilities(|capabilities| {
12652                        capabilities.code_lens_provider = None;
12653                    });
12654                    notify_server_capabilities_updated(&server, cx);
12655                }
12656                "textDocument/diagnostic" => {
12657                    let local = self
12658                        .as_local_mut()
12659                        .context("Expected LSP Store to be local")?;
12660
12661                    let state = local
12662                        .language_servers
12663                        .get_mut(&server_id)
12664                        .context("Could not obtain Language Servers state")?;
12665                    let registrations = local
12666                        .language_server_dynamic_registrations
12667                        .get_mut(&server_id)
12668                        .with_context(|| {
12669                            format!("Expected dynamic registration to exist for server {server_id}")
12670                        })?;
12671                    registrations.diagnostics
12672                        .remove(&Some(unreg.id.clone()))
12673                        .with_context(|| format!(
12674                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12675                            unreg.id)
12676                        )?;
12677                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12678
12679                    if let LanguageServerState::Running {
12680                        workspace_diagnostics_refresh_tasks,
12681                        ..
12682                    } = state
12683                    {
12684                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12685                    }
12686
12687                    if removed_last_diagnostic_provider {
12688                        server.update_capabilities(|capabilities| {
12689                            debug_assert!(capabilities.diagnostic_provider.is_some());
12690                            capabilities.diagnostic_provider = None;
12691                        });
12692                    }
12693
12694                    notify_server_capabilities_updated(&server, cx);
12695                }
12696                "textDocument/documentColor" => {
12697                    server.update_capabilities(|capabilities| {
12698                        capabilities.color_provider = None;
12699                    });
12700                    notify_server_capabilities_updated(&server, cx);
12701                }
12702                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12703            }
12704        }
12705
12706        Ok(())
12707    }
12708
12709    async fn deduplicate_range_based_lsp_requests<T>(
12710        lsp_store: &Entity<Self>,
12711        server_id: Option<LanguageServerId>,
12712        lsp_request_id: LspRequestId,
12713        proto_request: &T::ProtoRequest,
12714        range: Range<Anchor>,
12715        cx: &mut AsyncApp,
12716    ) -> Result<()>
12717    where
12718        T: LspCommand,
12719        T::ProtoRequest: proto::LspRequestMessage,
12720    {
12721        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12722        let version = deserialize_version(proto_request.buffer_version());
12723        let buffer = lsp_store.update(cx, |this, cx| {
12724            this.buffer_store.read(cx).get_existing(buffer_id)
12725        })??;
12726        buffer
12727            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12728            .await?;
12729        lsp_store.update(cx, |lsp_store, cx| {
12730            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12731            let chunks_queried_for = lsp_data
12732                .inlay_hints
12733                .applicable_chunks(&[range])
12734                .collect::<Vec<_>>();
12735            match chunks_queried_for.as_slice() {
12736                &[chunk] => {
12737                    let key = LspKey {
12738                        request_type: TypeId::of::<T>(),
12739                        server_queried: server_id,
12740                    };
12741                    let previous_request = lsp_data
12742                        .chunk_lsp_requests
12743                        .entry(key)
12744                        .or_default()
12745                        .insert(chunk, lsp_request_id);
12746                    if let Some((previous_request, running_requests)) =
12747                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12748                    {
12749                        running_requests.remove(&previous_request);
12750                    }
12751                }
12752                _ambiguous_chunks => {
12753                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12754                    // there, a buffer version-based check will be performed and outdated requests discarded.
12755                }
12756            }
12757            anyhow::Ok(())
12758        })??;
12759
12760        Ok(())
12761    }
12762
12763    async fn query_lsp_locally<T>(
12764        lsp_store: Entity<Self>,
12765        for_server_id: Option<LanguageServerId>,
12766        sender_id: proto::PeerId,
12767        lsp_request_id: LspRequestId,
12768        proto_request: T::ProtoRequest,
12769        position: Option<Anchor>,
12770        cx: &mut AsyncApp,
12771    ) -> Result<()>
12772    where
12773        T: LspCommand + Clone,
12774        T::ProtoRequest: proto::LspRequestMessage,
12775        <T::ProtoRequest as proto::RequestMessage>::Response:
12776            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12777    {
12778        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12779        let version = deserialize_version(proto_request.buffer_version());
12780        let buffer = lsp_store.update(cx, |this, cx| {
12781            this.buffer_store.read(cx).get_existing(buffer_id)
12782        })??;
12783        buffer
12784            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12785            .await?;
12786        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12787        let request =
12788            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12789        let key = LspKey {
12790            request_type: TypeId::of::<T>(),
12791            server_queried: for_server_id,
12792        };
12793        lsp_store.update(cx, |lsp_store, cx| {
12794            let request_task = match for_server_id {
12795                Some(server_id) => {
12796                    let server_task = lsp_store.request_lsp(
12797                        buffer.clone(),
12798                        LanguageServerToQuery::Other(server_id),
12799                        request.clone(),
12800                        cx,
12801                    );
12802                    cx.background_spawn(async move {
12803                        let mut responses = Vec::new();
12804                        match server_task.await {
12805                            Ok(response) => responses.push((server_id, response)),
12806                            // rust-analyzer likes to error with this when its still loading up
12807                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12808                            Err(e) => log::error!(
12809                                "Error handling response for request {request:?}: {e:#}"
12810                            ),
12811                        }
12812                        responses
12813                    })
12814                }
12815                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12816            };
12817            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12818            if T::ProtoRequest::stop_previous_requests() {
12819                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12820                    lsp_requests.clear();
12821                }
12822            }
12823            lsp_data.lsp_requests.entry(key).or_default().insert(
12824                lsp_request_id,
12825                cx.spawn(async move |lsp_store, cx| {
12826                    let response = request_task.await;
12827                    lsp_store
12828                        .update(cx, |lsp_store, cx| {
12829                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12830                            {
12831                                let response = response
12832                                    .into_iter()
12833                                    .map(|(server_id, response)| {
12834                                        (
12835                                            server_id.to_proto(),
12836                                            T::response_to_proto(
12837                                                response,
12838                                                lsp_store,
12839                                                sender_id,
12840                                                &buffer_version,
12841                                                cx,
12842                                            )
12843                                            .into(),
12844                                        )
12845                                    })
12846                                    .collect::<HashMap<_, _>>();
12847                                match client.send_lsp_response::<T::ProtoRequest>(
12848                                    project_id,
12849                                    lsp_request_id,
12850                                    response,
12851                                ) {
12852                                    Ok(()) => {}
12853                                    Err(e) => {
12854                                        log::error!("Failed to send LSP response: {e:#}",)
12855                                    }
12856                                }
12857                            }
12858                        })
12859                        .ok();
12860                }),
12861            );
12862        })?;
12863        Ok(())
12864    }
12865
12866    fn take_text_document_sync_options(
12867        capabilities: &mut lsp::ServerCapabilities,
12868    ) -> lsp::TextDocumentSyncOptions {
12869        match capabilities.text_document_sync.take() {
12870            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12871            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12872                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12873                sync_options.change = Some(sync_kind);
12874                sync_options
12875            }
12876            None => lsp::TextDocumentSyncOptions::default(),
12877        }
12878    }
12879
12880    #[cfg(any(test, feature = "test-support"))]
12881    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12882        Some(
12883            self.lsp_data
12884                .get_mut(&buffer_id)?
12885                .code_lens
12886                .take()?
12887                .update
12888                .take()?
12889                .1,
12890        )
12891    }
12892
12893    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12894        self.downstream_client.clone()
12895    }
12896
12897    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12898        self.worktree_store.clone()
12899    }
12900
12901    /// Gets what's stored in the LSP data for the given buffer.
12902    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12903        self.lsp_data.get_mut(&buffer_id)
12904    }
12905
12906    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12907    /// new [`BufferLspData`] will be created to replace the previous state.
12908    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12909        let (buffer_id, buffer_version) =
12910            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12911        let lsp_data = self
12912            .lsp_data
12913            .entry(buffer_id)
12914            .or_insert_with(|| BufferLspData::new(buffer, cx));
12915        if buffer_version.changed_since(&lsp_data.buffer_version) {
12916            *lsp_data = BufferLspData::new(buffer, cx);
12917        }
12918        lsp_data
12919    }
12920}
12921
12922// Registration with registerOptions as null, should fallback to true.
12923// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12924fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12925    reg: lsp::Registration,
12926) -> Result<OneOf<bool, T>> {
12927    Ok(match reg.register_options {
12928        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12929        None => OneOf::Left(true),
12930    })
12931}
12932
12933fn subscribe_to_binary_statuses(
12934    languages: &Arc<LanguageRegistry>,
12935    cx: &mut Context<'_, LspStore>,
12936) -> Task<()> {
12937    let mut server_statuses = languages.language_server_binary_statuses();
12938    cx.spawn(async move |lsp_store, cx| {
12939        while let Some((server_name, binary_status)) = server_statuses.next().await {
12940            if lsp_store
12941                .update(cx, |_, cx| {
12942                    let mut message = None;
12943                    let binary_status = match binary_status {
12944                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12945                        BinaryStatus::CheckingForUpdate => {
12946                            proto::ServerBinaryStatus::CheckingForUpdate
12947                        }
12948                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12949                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12950                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12951                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12952                        BinaryStatus::Failed { error } => {
12953                            message = Some(error);
12954                            proto::ServerBinaryStatus::Failed
12955                        }
12956                    };
12957                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12958                        // Binary updates are about the binary that might not have any language server id at that point.
12959                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12960                        language_server_id: LanguageServerId(0),
12961                        name: Some(server_name),
12962                        message: proto::update_language_server::Variant::StatusUpdate(
12963                            proto::StatusUpdate {
12964                                message,
12965                                status: Some(proto::status_update::Status::Binary(
12966                                    binary_status as i32,
12967                                )),
12968                            },
12969                        ),
12970                    });
12971                })
12972                .is_err()
12973            {
12974                break;
12975            }
12976        }
12977    })
12978}
12979
12980fn lsp_workspace_diagnostics_refresh(
12981    registration_id: Option<String>,
12982    options: DiagnosticServerCapabilities,
12983    server: Arc<LanguageServer>,
12984    cx: &mut Context<'_, LspStore>,
12985) -> Option<WorkspaceRefreshTask> {
12986    let identifier = workspace_diagnostic_identifier(&options)?;
12987    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
12988
12989    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12990    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12991    refresh_tx.try_send(()).ok();
12992
12993    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12994        let mut attempts = 0;
12995        let max_attempts = 50;
12996        let mut requests = 0;
12997
12998        loop {
12999            let Some(()) = refresh_rx.recv().await else {
13000                return;
13001            };
13002
13003            'request: loop {
13004                requests += 1;
13005                if attempts > max_attempts {
13006                    log::error!(
13007                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13008                    );
13009                    return;
13010                }
13011                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13012                cx.background_executor()
13013                    .timer(Duration::from_millis(backoff_millis))
13014                    .await;
13015                attempts += 1;
13016
13017                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13018                    lsp_store
13019                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13020                        .into_iter()
13021                        .filter_map(|(abs_path, result_id)| {
13022                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13023                            Some(lsp::PreviousResultId {
13024                                uri,
13025                                value: result_id.to_string(),
13026                            })
13027                        })
13028                        .collect()
13029                }) else {
13030                    return;
13031                };
13032
13033                let token = if let Some(registration_id) = &registration_id {
13034                    format!(
13035                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13036                        server.server_id(),
13037                    )
13038                } else {
13039                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13040                };
13041
13042                progress_rx.try_recv().ok();
13043                let timer =
13044                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13045                let progress = pin!(progress_rx.recv().fuse());
13046                let response_result = server
13047                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13048                        lsp::WorkspaceDiagnosticParams {
13049                            previous_result_ids,
13050                            identifier: identifier.clone(),
13051                            work_done_progress_params: Default::default(),
13052                            partial_result_params: lsp::PartialResultParams {
13053                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13054                            },
13055                        },
13056                        select(timer, progress).then(|either| match either {
13057                            Either::Left((message, ..)) => ready(message).left_future(),
13058                            Either::Right(..) => pending::<String>().right_future(),
13059                        }),
13060                    )
13061                    .await;
13062
13063                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13064                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13065                match response_result {
13066                    ConnectionResult::Timeout => {
13067                        log::error!("Timeout during workspace diagnostics pull");
13068                        continue 'request;
13069                    }
13070                    ConnectionResult::ConnectionReset => {
13071                        log::error!("Server closed a workspace diagnostics pull request");
13072                        continue 'request;
13073                    }
13074                    ConnectionResult::Result(Err(e)) => {
13075                        log::error!("Error during workspace diagnostics pull: {e:#}");
13076                        break 'request;
13077                    }
13078                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13079                        attempts = 0;
13080                        if lsp_store
13081                            .update(cx, |lsp_store, cx| {
13082                                lsp_store.apply_workspace_diagnostic_report(
13083                                    server.server_id(),
13084                                    pulled_diagnostics,
13085                                    registration_id_shared.clone(),
13086                                    cx,
13087                                )
13088                            })
13089                            .is_err()
13090                        {
13091                            return;
13092                        }
13093                        break 'request;
13094                    }
13095                }
13096            }
13097        }
13098    });
13099
13100    Some(WorkspaceRefreshTask {
13101        refresh_tx,
13102        progress_tx,
13103        task: workspace_query_language_server,
13104    })
13105}
13106
13107fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13108    match &options {
13109        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13110            diagnostic_options.identifier.clone()
13111        }
13112        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13113            let diagnostic_options = &registration_options.diagnostic_options;
13114            diagnostic_options.identifier.clone()
13115        }
13116    }
13117}
13118
13119fn workspace_diagnostic_identifier(
13120    options: &DiagnosticServerCapabilities,
13121) -> Option<Option<String>> {
13122    match &options {
13123        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13124            if !diagnostic_options.workspace_diagnostics {
13125                return None;
13126            }
13127            Some(diagnostic_options.identifier.clone())
13128        }
13129        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13130            let diagnostic_options = &registration_options.diagnostic_options;
13131            if !diagnostic_options.workspace_diagnostics {
13132                return None;
13133            }
13134            Some(diagnostic_options.identifier.clone())
13135        }
13136    }
13137}
13138
13139fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13140    let CompletionSource::BufferWord {
13141        word_range,
13142        resolved,
13143    } = &mut completion.source
13144    else {
13145        return;
13146    };
13147    if *resolved {
13148        return;
13149    }
13150
13151    if completion.new_text
13152        != snapshot
13153            .text_for_range(word_range.clone())
13154            .collect::<String>()
13155    {
13156        return;
13157    }
13158
13159    let mut offset = 0;
13160    for chunk in snapshot.chunks(word_range.clone(), true) {
13161        let end_offset = offset + chunk.text.len();
13162        if let Some(highlight_id) = chunk.syntax_highlight_id {
13163            completion
13164                .label
13165                .runs
13166                .push((offset..end_offset, highlight_id));
13167        }
13168        offset = end_offset;
13169    }
13170    *resolved = true;
13171}
13172
13173impl EventEmitter<LspStoreEvent> for LspStore {}
13174
13175fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13176    hover
13177        .contents
13178        .retain(|hover_block| !hover_block.text.trim().is_empty());
13179    if hover.contents.is_empty() {
13180        None
13181    } else {
13182        Some(hover)
13183    }
13184}
13185
13186async fn populate_labels_for_completions(
13187    new_completions: Vec<CoreCompletion>,
13188    language: Option<Arc<Language>>,
13189    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13190) -> Vec<Completion> {
13191    let lsp_completions = new_completions
13192        .iter()
13193        .filter_map(|new_completion| {
13194            new_completion
13195                .source
13196                .lsp_completion(true)
13197                .map(|lsp_completion| lsp_completion.into_owned())
13198        })
13199        .collect::<Vec<_>>();
13200
13201    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13202        lsp_adapter
13203            .labels_for_completions(&lsp_completions, language)
13204            .await
13205            .log_err()
13206            .unwrap_or_default()
13207    } else {
13208        Vec::new()
13209    }
13210    .into_iter()
13211    .fuse();
13212
13213    let mut completions = Vec::new();
13214    for completion in new_completions {
13215        match completion.source.lsp_completion(true) {
13216            Some(lsp_completion) => {
13217                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13218
13219                let mut label = labels.next().flatten().unwrap_or_else(|| {
13220                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13221                });
13222                ensure_uniform_list_compatible_label(&mut label);
13223                completions.push(Completion {
13224                    label,
13225                    documentation,
13226                    replace_range: completion.replace_range,
13227                    new_text: completion.new_text,
13228                    insert_text_mode: lsp_completion.insert_text_mode,
13229                    source: completion.source,
13230                    icon_path: None,
13231                    confirm: None,
13232                    match_start: None,
13233                    snippet_deduplication_key: None,
13234                });
13235            }
13236            None => {
13237                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13238                ensure_uniform_list_compatible_label(&mut label);
13239                completions.push(Completion {
13240                    label,
13241                    documentation: None,
13242                    replace_range: completion.replace_range,
13243                    new_text: completion.new_text,
13244                    source: completion.source,
13245                    insert_text_mode: None,
13246                    icon_path: None,
13247                    confirm: None,
13248                    match_start: None,
13249                    snippet_deduplication_key: None,
13250                });
13251            }
13252        }
13253    }
13254    completions
13255}
13256
13257#[derive(Debug)]
13258pub enum LanguageServerToQuery {
13259    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13260    FirstCapable,
13261    /// Query a specific language server.
13262    Other(LanguageServerId),
13263}
13264
13265#[derive(Default)]
13266struct RenamePathsWatchedForServer {
13267    did_rename: Vec<RenameActionPredicate>,
13268    will_rename: Vec<RenameActionPredicate>,
13269}
13270
13271impl RenamePathsWatchedForServer {
13272    fn with_did_rename_patterns(
13273        mut self,
13274        did_rename: Option<&FileOperationRegistrationOptions>,
13275    ) -> Self {
13276        if let Some(did_rename) = did_rename {
13277            self.did_rename = did_rename
13278                .filters
13279                .iter()
13280                .filter_map(|filter| filter.try_into().log_err())
13281                .collect();
13282        }
13283        self
13284    }
13285    fn with_will_rename_patterns(
13286        mut self,
13287        will_rename: Option<&FileOperationRegistrationOptions>,
13288    ) -> Self {
13289        if let Some(will_rename) = will_rename {
13290            self.will_rename = will_rename
13291                .filters
13292                .iter()
13293                .filter_map(|filter| filter.try_into().log_err())
13294                .collect();
13295        }
13296        self
13297    }
13298
13299    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13300        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13301    }
13302    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13303        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13304    }
13305}
13306
13307impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13308    type Error = globset::Error;
13309    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13310        Ok(Self {
13311            kind: ops.pattern.matches.clone(),
13312            glob: GlobBuilder::new(&ops.pattern.glob)
13313                .case_insensitive(
13314                    ops.pattern
13315                        .options
13316                        .as_ref()
13317                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13318                )
13319                .build()?
13320                .compile_matcher(),
13321        })
13322    }
13323}
13324struct RenameActionPredicate {
13325    glob: GlobMatcher,
13326    kind: Option<FileOperationPatternKind>,
13327}
13328
13329impl RenameActionPredicate {
13330    // Returns true if language server should be notified
13331    fn eval(&self, path: &str, is_dir: bool) -> bool {
13332        self.kind.as_ref().is_none_or(|kind| {
13333            let expected_kind = if is_dir {
13334                FileOperationPatternKind::Folder
13335            } else {
13336                FileOperationPatternKind::File
13337            };
13338            kind == &expected_kind
13339        }) && self.glob.is_match(path)
13340    }
13341}
13342
13343#[derive(Default)]
13344struct LanguageServerWatchedPaths {
13345    worktree_paths: HashMap<WorktreeId, GlobSet>,
13346    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13347}
13348
13349#[derive(Default)]
13350struct LanguageServerWatchedPathsBuilder {
13351    worktree_paths: HashMap<WorktreeId, GlobSet>,
13352    abs_paths: HashMap<Arc<Path>, GlobSet>,
13353}
13354
13355impl LanguageServerWatchedPathsBuilder {
13356    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13357        self.worktree_paths.insert(worktree_id, glob_set);
13358    }
13359    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13360        self.abs_paths.insert(path, glob_set);
13361    }
13362    fn build(
13363        self,
13364        fs: Arc<dyn Fs>,
13365        language_server_id: LanguageServerId,
13366        cx: &mut Context<LspStore>,
13367    ) -> LanguageServerWatchedPaths {
13368        let lsp_store = cx.weak_entity();
13369
13370        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13371        let abs_paths = self
13372            .abs_paths
13373            .into_iter()
13374            .map(|(abs_path, globset)| {
13375                let task = cx.spawn({
13376                    let abs_path = abs_path.clone();
13377                    let fs = fs.clone();
13378
13379                    let lsp_store = lsp_store.clone();
13380                    async move |_, cx| {
13381                        maybe!(async move {
13382                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13383                            while let Some(update) = push_updates.0.next().await {
13384                                let action = lsp_store
13385                                    .update(cx, |this, _| {
13386                                        let Some(local) = this.as_local() else {
13387                                            return ControlFlow::Break(());
13388                                        };
13389                                        let Some(watcher) = local
13390                                            .language_server_watched_paths
13391                                            .get(&language_server_id)
13392                                        else {
13393                                            return ControlFlow::Break(());
13394                                        };
13395                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13396                                            "Watched abs path is not registered with a watcher",
13397                                        );
13398                                        let matching_entries = update
13399                                            .into_iter()
13400                                            .filter(|event| globs.is_match(&event.path))
13401                                            .collect::<Vec<_>>();
13402                                        this.lsp_notify_abs_paths_changed(
13403                                            language_server_id,
13404                                            matching_entries,
13405                                        );
13406                                        ControlFlow::Continue(())
13407                                    })
13408                                    .ok()?;
13409
13410                                if action.is_break() {
13411                                    break;
13412                                }
13413                            }
13414                            Some(())
13415                        })
13416                        .await;
13417                    }
13418                });
13419                (abs_path, (globset, task))
13420            })
13421            .collect();
13422        LanguageServerWatchedPaths {
13423            worktree_paths: self.worktree_paths,
13424            abs_paths,
13425        }
13426    }
13427}
13428
13429struct LspBufferSnapshot {
13430    version: i32,
13431    snapshot: TextBufferSnapshot,
13432}
13433
13434/// A prompt requested by LSP server.
13435#[derive(Clone, Debug)]
13436pub struct LanguageServerPromptRequest {
13437    pub level: PromptLevel,
13438    pub message: String,
13439    pub actions: Vec<MessageActionItem>,
13440    pub lsp_name: String,
13441    pub(crate) response_channel: Sender<MessageActionItem>,
13442}
13443
13444impl LanguageServerPromptRequest {
13445    pub async fn respond(self, index: usize) -> Option<()> {
13446        if let Some(response) = self.actions.into_iter().nth(index) {
13447            self.response_channel.send(response).await.ok()
13448        } else {
13449            None
13450        }
13451    }
13452}
13453impl PartialEq for LanguageServerPromptRequest {
13454    fn eq(&self, other: &Self) -> bool {
13455        self.message == other.message && self.actions == other.actions
13456    }
13457}
13458
13459#[derive(Clone, Debug, PartialEq)]
13460pub enum LanguageServerLogType {
13461    Log(MessageType),
13462    Trace { verbose_info: Option<String> },
13463    Rpc { received: bool },
13464}
13465
13466impl LanguageServerLogType {
13467    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13468        match self {
13469            Self::Log(log_type) => {
13470                use proto::log_message::LogLevel;
13471                let level = match *log_type {
13472                    MessageType::ERROR => LogLevel::Error,
13473                    MessageType::WARNING => LogLevel::Warning,
13474                    MessageType::INFO => LogLevel::Info,
13475                    MessageType::LOG => LogLevel::Log,
13476                    other => {
13477                        log::warn!("Unknown lsp log message type: {other:?}");
13478                        LogLevel::Log
13479                    }
13480                };
13481                proto::language_server_log::LogType::Log(proto::LogMessage {
13482                    level: level as i32,
13483                })
13484            }
13485            Self::Trace { verbose_info } => {
13486                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13487                    verbose_info: verbose_info.to_owned(),
13488                })
13489            }
13490            Self::Rpc { received } => {
13491                let kind = if *received {
13492                    proto::rpc_message::Kind::Received
13493                } else {
13494                    proto::rpc_message::Kind::Sent
13495                };
13496                let kind = kind as i32;
13497                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13498            }
13499        }
13500    }
13501
13502    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13503        use proto::log_message::LogLevel;
13504        use proto::rpc_message;
13505        match log_type {
13506            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13507                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13508                    LogLevel::Error => MessageType::ERROR,
13509                    LogLevel::Warning => MessageType::WARNING,
13510                    LogLevel::Info => MessageType::INFO,
13511                    LogLevel::Log => MessageType::LOG,
13512                },
13513            ),
13514            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13515                verbose_info: trace_message.verbose_info,
13516            },
13517            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13518                received: match rpc_message::Kind::from_i32(message.kind)
13519                    .unwrap_or(rpc_message::Kind::Received)
13520                {
13521                    rpc_message::Kind::Received => true,
13522                    rpc_message::Kind::Sent => false,
13523                },
13524            },
13525        }
13526    }
13527}
13528
13529pub struct WorkspaceRefreshTask {
13530    refresh_tx: mpsc::Sender<()>,
13531    progress_tx: mpsc::Sender<()>,
13532    #[allow(dead_code)]
13533    task: Task<()>,
13534}
13535
13536pub enum LanguageServerState {
13537    Starting {
13538        startup: Task<Option<Arc<LanguageServer>>>,
13539        /// List of language servers that will be added to the workspace once it's initialization completes.
13540        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13541    },
13542
13543    Running {
13544        adapter: Arc<CachedLspAdapter>,
13545        server: Arc<LanguageServer>,
13546        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13547        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13548    },
13549}
13550
13551impl LanguageServerState {
13552    fn add_workspace_folder(&self, uri: Uri) {
13553        match self {
13554            LanguageServerState::Starting {
13555                pending_workspace_folders,
13556                ..
13557            } => {
13558                pending_workspace_folders.lock().insert(uri);
13559            }
13560            LanguageServerState::Running { server, .. } => {
13561                server.add_workspace_folder(uri);
13562            }
13563        }
13564    }
13565    fn _remove_workspace_folder(&self, uri: Uri) {
13566        match self {
13567            LanguageServerState::Starting {
13568                pending_workspace_folders,
13569                ..
13570            } => {
13571                pending_workspace_folders.lock().remove(&uri);
13572            }
13573            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13574        }
13575    }
13576}
13577
13578impl std::fmt::Debug for LanguageServerState {
13579    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13580        match self {
13581            LanguageServerState::Starting { .. } => {
13582                f.debug_struct("LanguageServerState::Starting").finish()
13583            }
13584            LanguageServerState::Running { .. } => {
13585                f.debug_struct("LanguageServerState::Running").finish()
13586            }
13587        }
13588    }
13589}
13590
13591#[derive(Clone, Debug, Serialize)]
13592pub struct LanguageServerProgress {
13593    pub is_disk_based_diagnostics_progress: bool,
13594    pub is_cancellable: bool,
13595    pub title: Option<String>,
13596    pub message: Option<String>,
13597    pub percentage: Option<usize>,
13598    #[serde(skip_serializing)]
13599    pub last_update_at: Instant,
13600}
13601
13602#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13603pub struct DiagnosticSummary {
13604    pub error_count: usize,
13605    pub warning_count: usize,
13606}
13607
13608impl DiagnosticSummary {
13609    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13610        let mut this = Self {
13611            error_count: 0,
13612            warning_count: 0,
13613        };
13614
13615        for entry in diagnostics {
13616            if entry.diagnostic.is_primary {
13617                match entry.diagnostic.severity {
13618                    DiagnosticSeverity::ERROR => this.error_count += 1,
13619                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13620                    _ => {}
13621                }
13622            }
13623        }
13624
13625        this
13626    }
13627
13628    pub fn is_empty(&self) -> bool {
13629        self.error_count == 0 && self.warning_count == 0
13630    }
13631
13632    pub fn to_proto(
13633        self,
13634        language_server_id: LanguageServerId,
13635        path: &RelPath,
13636    ) -> proto::DiagnosticSummary {
13637        proto::DiagnosticSummary {
13638            path: path.to_proto(),
13639            language_server_id: language_server_id.0 as u64,
13640            error_count: self.error_count as u32,
13641            warning_count: self.warning_count as u32,
13642        }
13643    }
13644}
13645
13646#[derive(Clone, Debug)]
13647pub enum CompletionDocumentation {
13648    /// There is no documentation for this completion.
13649    Undocumented,
13650    /// A single line of documentation.
13651    SingleLine(SharedString),
13652    /// Multiple lines of plain text documentation.
13653    MultiLinePlainText(SharedString),
13654    /// Markdown documentation.
13655    MultiLineMarkdown(SharedString),
13656    /// Both single line and multiple lines of plain text documentation.
13657    SingleLineAndMultiLinePlainText {
13658        single_line: SharedString,
13659        plain_text: Option<SharedString>,
13660    },
13661}
13662
13663impl CompletionDocumentation {
13664    #[cfg(any(test, feature = "test-support"))]
13665    pub fn text(&self) -> SharedString {
13666        match self {
13667            CompletionDocumentation::Undocumented => "".into(),
13668            CompletionDocumentation::SingleLine(s) => s.clone(),
13669            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13670            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13671            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13672                single_line.clone()
13673            }
13674        }
13675    }
13676}
13677
13678impl From<lsp::Documentation> for CompletionDocumentation {
13679    fn from(docs: lsp::Documentation) -> Self {
13680        match docs {
13681            lsp::Documentation::String(text) => {
13682                if text.lines().count() <= 1 {
13683                    CompletionDocumentation::SingleLine(text.into())
13684                } else {
13685                    CompletionDocumentation::MultiLinePlainText(text.into())
13686                }
13687            }
13688
13689            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13690                lsp::MarkupKind::PlainText => {
13691                    if value.lines().count() <= 1 {
13692                        CompletionDocumentation::SingleLine(value.into())
13693                    } else {
13694                        CompletionDocumentation::MultiLinePlainText(value.into())
13695                    }
13696                }
13697
13698                lsp::MarkupKind::Markdown => {
13699                    CompletionDocumentation::MultiLineMarkdown(value.into())
13700                }
13701            },
13702        }
13703    }
13704}
13705
13706pub enum ResolvedHint {
13707    Resolved(InlayHint),
13708    Resolving(Shared<Task<()>>),
13709}
13710
13711fn glob_literal_prefix(glob: &Path) -> PathBuf {
13712    glob.components()
13713        .take_while(|component| match component {
13714            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13715            _ => true,
13716        })
13717        .collect()
13718}
13719
13720pub struct SshLspAdapter {
13721    name: LanguageServerName,
13722    binary: LanguageServerBinary,
13723    initialization_options: Option<String>,
13724    code_action_kinds: Option<Vec<CodeActionKind>>,
13725}
13726
13727impl SshLspAdapter {
13728    pub fn new(
13729        name: LanguageServerName,
13730        binary: LanguageServerBinary,
13731        initialization_options: Option<String>,
13732        code_action_kinds: Option<String>,
13733    ) -> Self {
13734        Self {
13735            name,
13736            binary,
13737            initialization_options,
13738            code_action_kinds: code_action_kinds
13739                .as_ref()
13740                .and_then(|c| serde_json::from_str(c).ok()),
13741        }
13742    }
13743}
13744
13745impl LspInstaller for SshLspAdapter {
13746    type BinaryVersion = ();
13747    async fn check_if_user_installed(
13748        &self,
13749        _: &dyn LspAdapterDelegate,
13750        _: Option<Toolchain>,
13751        _: &AsyncApp,
13752    ) -> Option<LanguageServerBinary> {
13753        Some(self.binary.clone())
13754    }
13755
13756    async fn cached_server_binary(
13757        &self,
13758        _: PathBuf,
13759        _: &dyn LspAdapterDelegate,
13760    ) -> Option<LanguageServerBinary> {
13761        None
13762    }
13763
13764    async fn fetch_latest_server_version(
13765        &self,
13766        _: &dyn LspAdapterDelegate,
13767        _: bool,
13768        _: &mut AsyncApp,
13769    ) -> Result<()> {
13770        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13771    }
13772
13773    async fn fetch_server_binary(
13774        &self,
13775        _: (),
13776        _: PathBuf,
13777        _: &dyn LspAdapterDelegate,
13778    ) -> Result<LanguageServerBinary> {
13779        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13780    }
13781}
13782
13783#[async_trait(?Send)]
13784impl LspAdapter for SshLspAdapter {
13785    fn name(&self) -> LanguageServerName {
13786        self.name.clone()
13787    }
13788
13789    async fn initialization_options(
13790        self: Arc<Self>,
13791        _: &Arc<dyn LspAdapterDelegate>,
13792    ) -> Result<Option<serde_json::Value>> {
13793        let Some(options) = &self.initialization_options else {
13794            return Ok(None);
13795        };
13796        let result = serde_json::from_str(options)?;
13797        Ok(result)
13798    }
13799
13800    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13801        self.code_action_kinds.clone()
13802    }
13803}
13804
13805pub fn language_server_settings<'a>(
13806    delegate: &'a dyn LspAdapterDelegate,
13807    language: &LanguageServerName,
13808    cx: &'a App,
13809) -> Option<&'a LspSettings> {
13810    language_server_settings_for(
13811        SettingsLocation {
13812            worktree_id: delegate.worktree_id(),
13813            path: RelPath::empty(),
13814        },
13815        language,
13816        cx,
13817    )
13818}
13819
13820pub fn language_server_settings_for<'a>(
13821    location: SettingsLocation<'a>,
13822    language: &LanguageServerName,
13823    cx: &'a App,
13824) -> Option<&'a LspSettings> {
13825    ProjectSettings::get(Some(location), cx).lsp.get(language)
13826}
13827
13828pub struct LocalLspAdapterDelegate {
13829    lsp_store: WeakEntity<LspStore>,
13830    worktree: worktree::Snapshot,
13831    fs: Arc<dyn Fs>,
13832    http_client: Arc<dyn HttpClient>,
13833    language_registry: Arc<LanguageRegistry>,
13834    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13835}
13836
13837impl LocalLspAdapterDelegate {
13838    pub fn new(
13839        language_registry: Arc<LanguageRegistry>,
13840        environment: &Entity<ProjectEnvironment>,
13841        lsp_store: WeakEntity<LspStore>,
13842        worktree: &Entity<Worktree>,
13843        http_client: Arc<dyn HttpClient>,
13844        fs: Arc<dyn Fs>,
13845        cx: &mut App,
13846    ) -> Arc<Self> {
13847        let load_shell_env_task =
13848            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13849
13850        Arc::new(Self {
13851            lsp_store,
13852            worktree: worktree.read(cx).snapshot(),
13853            fs,
13854            http_client,
13855            language_registry,
13856            load_shell_env_task,
13857        })
13858    }
13859
13860    fn from_local_lsp(
13861        local: &LocalLspStore,
13862        worktree: &Entity<Worktree>,
13863        cx: &mut App,
13864    ) -> Arc<Self> {
13865        Self::new(
13866            local.languages.clone(),
13867            &local.environment,
13868            local.weak.clone(),
13869            worktree,
13870            local.http_client.clone(),
13871            local.fs.clone(),
13872            cx,
13873        )
13874    }
13875}
13876
13877#[async_trait]
13878impl LspAdapterDelegate for LocalLspAdapterDelegate {
13879    fn show_notification(&self, message: &str, cx: &mut App) {
13880        self.lsp_store
13881            .update(cx, |_, cx| {
13882                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13883            })
13884            .ok();
13885    }
13886
13887    fn http_client(&self) -> Arc<dyn HttpClient> {
13888        self.http_client.clone()
13889    }
13890
13891    fn worktree_id(&self) -> WorktreeId {
13892        self.worktree.id()
13893    }
13894
13895    fn worktree_root_path(&self) -> &Path {
13896        self.worktree.abs_path().as_ref()
13897    }
13898
13899    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13900        self.worktree.resolve_executable_path(path)
13901    }
13902
13903    async fn shell_env(&self) -> HashMap<String, String> {
13904        let task = self.load_shell_env_task.clone();
13905        task.await.unwrap_or_default()
13906    }
13907
13908    async fn npm_package_installed_version(
13909        &self,
13910        package_name: &str,
13911    ) -> Result<Option<(PathBuf, String)>> {
13912        let local_package_directory = self.worktree_root_path();
13913        let node_modules_directory = local_package_directory.join("node_modules");
13914
13915        if let Some(version) =
13916            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13917        {
13918            return Ok(Some((node_modules_directory, version)));
13919        }
13920        let Some(npm) = self.which("npm".as_ref()).await else {
13921            log::warn!(
13922                "Failed to find npm executable for {:?}",
13923                local_package_directory
13924            );
13925            return Ok(None);
13926        };
13927
13928        let env = self.shell_env().await;
13929        let output = util::command::new_smol_command(&npm)
13930            .args(["root", "-g"])
13931            .envs(env)
13932            .current_dir(local_package_directory)
13933            .output()
13934            .await?;
13935        let global_node_modules =
13936            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13937
13938        if let Some(version) =
13939            read_package_installed_version(global_node_modules.clone(), package_name).await?
13940        {
13941            return Ok(Some((global_node_modules, version)));
13942        }
13943        return Ok(None);
13944    }
13945
13946    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13947        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13948        if self.fs.is_file(&worktree_abs_path).await {
13949            worktree_abs_path.pop();
13950        }
13951
13952        let env = self.shell_env().await;
13953
13954        let shell_path = env.get("PATH").cloned();
13955
13956        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13957    }
13958
13959    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13960        let mut working_dir = self.worktree_root_path().to_path_buf();
13961        if self.fs.is_file(&working_dir).await {
13962            working_dir.pop();
13963        }
13964        let output = util::command::new_smol_command(&command.path)
13965            .args(command.arguments)
13966            .envs(command.env.clone().unwrap_or_default())
13967            .current_dir(working_dir)
13968            .output()
13969            .await?;
13970
13971        anyhow::ensure!(
13972            output.status.success(),
13973            "{}, stdout: {:?}, stderr: {:?}",
13974            output.status,
13975            String::from_utf8_lossy(&output.stdout),
13976            String::from_utf8_lossy(&output.stderr)
13977        );
13978        Ok(())
13979    }
13980
13981    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13982        self.language_registry
13983            .update_lsp_binary_status(server_name, status);
13984    }
13985
13986    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13987        self.language_registry
13988            .all_lsp_adapters()
13989            .into_iter()
13990            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13991            .collect()
13992    }
13993
13994    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13995        let dir = self.language_registry.language_server_download_dir(name)?;
13996
13997        if !dir.exists() {
13998            smol::fs::create_dir_all(&dir)
13999                .await
14000                .context("failed to create container directory")
14001                .log_err()?;
14002        }
14003
14004        Some(dir)
14005    }
14006
14007    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14008        let entry = self
14009            .worktree
14010            .entry_for_path(path)
14011            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14012        let abs_path = self.worktree.absolutize(&entry.path);
14013        self.fs.load(&abs_path).await
14014    }
14015}
14016
14017async fn populate_labels_for_symbols(
14018    symbols: Vec<CoreSymbol>,
14019    language_registry: &Arc<LanguageRegistry>,
14020    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14021    output: &mut Vec<Symbol>,
14022) {
14023    #[allow(clippy::mutable_key_type)]
14024    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14025
14026    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14027    for symbol in symbols {
14028        let Some(file_name) = symbol.path.file_name() else {
14029            continue;
14030        };
14031        let language = language_registry
14032            .load_language_for_file_path(Path::new(file_name))
14033            .await
14034            .ok()
14035            .or_else(|| {
14036                unknown_paths.insert(file_name.into());
14037                None
14038            });
14039        symbols_by_language
14040            .entry(language)
14041            .or_default()
14042            .push(symbol);
14043    }
14044
14045    for unknown_path in unknown_paths {
14046        log::info!("no language found for symbol in file {unknown_path:?}");
14047    }
14048
14049    let mut label_params = Vec::new();
14050    for (language, mut symbols) in symbols_by_language {
14051        label_params.clear();
14052        label_params.extend(
14053            symbols
14054                .iter_mut()
14055                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14056        );
14057
14058        let mut labels = Vec::new();
14059        if let Some(language) = language {
14060            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14061                language_registry
14062                    .lsp_adapters(&language.name())
14063                    .first()
14064                    .cloned()
14065            });
14066            if let Some(lsp_adapter) = lsp_adapter {
14067                labels = lsp_adapter
14068                    .labels_for_symbols(&label_params, &language)
14069                    .await
14070                    .log_err()
14071                    .unwrap_or_default();
14072            }
14073        }
14074
14075        for ((symbol, (name, _)), label) in symbols
14076            .into_iter()
14077            .zip(label_params.drain(..))
14078            .zip(labels.into_iter().chain(iter::repeat(None)))
14079        {
14080            output.push(Symbol {
14081                language_server_name: symbol.language_server_name,
14082                source_worktree_id: symbol.source_worktree_id,
14083                source_language_server_id: symbol.source_language_server_id,
14084                path: symbol.path,
14085                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14086                name,
14087                kind: symbol.kind,
14088                range: symbol.range,
14089            });
14090        }
14091    }
14092}
14093
14094fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14095    match server.capabilities().text_document_sync.as_ref()? {
14096        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14097            // Server wants didSave but didn't specify includeText.
14098            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14099            // Server doesn't want didSave at all.
14100            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14101            // Server provided SaveOptions.
14102            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14103                Some(save_options.include_text.unwrap_or(false))
14104            }
14105        },
14106        // We do not have any save info. Kind affects didChange only.
14107        lsp::TextDocumentSyncCapability::Kind(_) => None,
14108    }
14109}
14110
14111/// Completion items are displayed in a `UniformList`.
14112/// Usually, those items are single-line strings, but in LSP responses,
14113/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14114/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14115/// 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,
14116/// breaking the completions menu presentation.
14117///
14118/// 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.
14119fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14120    let mut new_text = String::with_capacity(label.text.len());
14121    let mut offset_map = vec![0; label.text.len() + 1];
14122    let mut last_char_was_space = false;
14123    let mut new_idx = 0;
14124    let chars = label.text.char_indices().fuse();
14125    let mut newlines_removed = false;
14126
14127    for (idx, c) in chars {
14128        offset_map[idx] = new_idx;
14129
14130        match c {
14131            '\n' if last_char_was_space => {
14132                newlines_removed = true;
14133            }
14134            '\t' | ' ' if last_char_was_space => {}
14135            '\n' if !last_char_was_space => {
14136                new_text.push(' ');
14137                new_idx += 1;
14138                last_char_was_space = true;
14139                newlines_removed = true;
14140            }
14141            ' ' | '\t' => {
14142                new_text.push(' ');
14143                new_idx += 1;
14144                last_char_was_space = true;
14145            }
14146            _ => {
14147                new_text.push(c);
14148                new_idx += c.len_utf8();
14149                last_char_was_space = false;
14150            }
14151        }
14152    }
14153    offset_map[label.text.len()] = new_idx;
14154
14155    // Only modify the label if newlines were removed.
14156    if !newlines_removed {
14157        return;
14158    }
14159
14160    let last_index = new_idx;
14161    let mut run_ranges_errors = Vec::new();
14162    label.runs.retain_mut(|(range, _)| {
14163        match offset_map.get(range.start) {
14164            Some(&start) => range.start = start,
14165            None => {
14166                run_ranges_errors.push(range.clone());
14167                return false;
14168            }
14169        }
14170
14171        match offset_map.get(range.end) {
14172            Some(&end) => range.end = end,
14173            None => {
14174                run_ranges_errors.push(range.clone());
14175                range.end = last_index;
14176            }
14177        }
14178        true
14179    });
14180    if !run_ranges_errors.is_empty() {
14181        log::error!(
14182            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14183            label.text
14184        );
14185    }
14186
14187    let mut wrong_filter_range = None;
14188    if label.filter_range == (0..label.text.len()) {
14189        label.filter_range = 0..new_text.len();
14190    } else {
14191        let mut original_filter_range = Some(label.filter_range.clone());
14192        match offset_map.get(label.filter_range.start) {
14193            Some(&start) => label.filter_range.start = start,
14194            None => {
14195                wrong_filter_range = original_filter_range.take();
14196                label.filter_range.start = last_index;
14197            }
14198        }
14199
14200        match offset_map.get(label.filter_range.end) {
14201            Some(&end) => label.filter_range.end = end,
14202            None => {
14203                wrong_filter_range = original_filter_range.take();
14204                label.filter_range.end = last_index;
14205            }
14206        }
14207    }
14208    if let Some(wrong_filter_range) = wrong_filter_range {
14209        log::error!(
14210            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14211            label.text
14212        );
14213    }
14214
14215    label.text = new_text;
14216}
14217
14218#[cfg(test)]
14219mod tests {
14220    use language::HighlightId;
14221
14222    use super::*;
14223
14224    #[test]
14225    fn test_glob_literal_prefix() {
14226        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14227        assert_eq!(
14228            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14229            Path::new("node_modules")
14230        );
14231        assert_eq!(
14232            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14233            Path::new("foo")
14234        );
14235        assert_eq!(
14236            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14237            Path::new("foo/bar/baz.js")
14238        );
14239
14240        #[cfg(target_os = "windows")]
14241        {
14242            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14243            assert_eq!(
14244                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14245                Path::new("node_modules")
14246            );
14247            assert_eq!(
14248                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14249                Path::new("foo")
14250            );
14251            assert_eq!(
14252                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14253                Path::new("foo/bar/baz.js")
14254            );
14255        }
14256    }
14257
14258    #[test]
14259    fn test_multi_len_chars_normalization() {
14260        let mut label = CodeLabel::new(
14261            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14262            0..6,
14263            vec![(0..6, HighlightId(1))],
14264        );
14265        ensure_uniform_list_compatible_label(&mut label);
14266        assert_eq!(
14267            label,
14268            CodeLabel::new(
14269                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14270                0..6,
14271                vec![(0..6, HighlightId(1))],
14272            )
14273        );
14274    }
14275}