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;
   17
   18use crate::{
   19    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   20    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, LocationLink, LspAction,
   21    LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   22    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   23    buffer_store::{BufferStore, BufferStoreEvent},
   24    environment::ProjectEnvironment,
   25    lsp_command::{self, *},
   26    lsp_store::{
   27        self,
   28        log_store::{GlobalLogStore, LanguageServerKind},
   29    },
   30    manifest_tree::{
   31        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   32        ManifestTree,
   33    },
   34    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   35    project_settings::{LspSettings, ProjectSettings},
   36    relativize_path, resolve_path,
   37    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   38    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   39    yarn::YarnPathStore,
   40};
   41use anyhow::{Context as _, Result, anyhow};
   42use async_trait::async_trait;
   43use client::{TypedEnvelope, proto};
   44use clock::Global;
   45use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   46use futures::{
   47    AsyncWriteExt, Future, FutureExt, StreamExt,
   48    future::{Either, Shared, join_all, pending, select},
   49    select, select_biased,
   50    stream::FuturesUnordered,
   51};
   52use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   53use gpui::{
   54    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   55    WeakEntity,
   56};
   57use http_client::HttpClient;
   58use itertools::Itertools as _;
   59use language::{
   60    Bias, BinaryStatus, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   61    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   62    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, ManifestDelegate, ManifestName,
   63    Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPoint, ToPointUtf16, Toolchain, Transaction,
   64    Unclipped,
   65    language_settings::{
   66        FormatOnSave, Formatter, LanguageSettings, SelectedFormatter, language_settings,
   67    },
   68    point_to_lsp,
   69    proto::{
   70        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   71        serialize_lsp_edit, serialize_version,
   72    },
   73    range_from_lsp, range_to_lsp,
   74};
   75use lsp::{
   76    AdapterServerCapabilities, CodeActionKind, CompletionContext, DiagnosticSeverity,
   77    DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter,
   78    FileOperationPatternKind, FileOperationRegistrationOptions, FileRename, FileSystemWatcher,
   79    LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions,
   80    LanguageServerId, LanguageServerName, LanguageServerSelector, LspRequestFuture,
   81    MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind,
   82    TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles, WorkDoneProgressCancelParams,
   83    WorkspaceFolder, notification::DidRenameFiles,
   84};
   85use node_runtime::read_package_installed_version;
   86use parking_lot::Mutex;
   87use postage::{mpsc, sink::Sink, stream::Stream, watch};
   88use rand::prelude::*;
   89use rpc::{
   90    AnyProtoClient,
   91    proto::{FromProto, LspRequestId, LspRequestMessage as _, ToProto},
   92};
   93use serde::Serialize;
   94use settings::{Settings, SettingsLocation, SettingsStore};
   95use sha2::{Digest, Sha256};
   96use smol::channel::Sender;
   97use snippet::Snippet;
   98use std::{
   99    any::{Any, TypeId},
  100    borrow::Cow,
  101    cell::RefCell,
  102    cmp::{Ordering, Reverse},
  103    convert::TryInto,
  104    ffi::OsStr,
  105    future::ready,
  106    iter, mem,
  107    ops::{ControlFlow, Range},
  108    path::{self, Path, PathBuf},
  109    pin::pin,
  110    rc::Rc,
  111    sync::Arc,
  112    time::{Duration, Instant},
  113};
  114use sum_tree::Dimensions;
  115use text::{Anchor, BufferId, LineEnding, OffsetRangeExt};
  116
  117use util::{
  118    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  119    paths::{PathExt, SanitizedPath},
  120    post_inc,
  121};
  122
  123pub use fs::*;
  124pub use language::Location;
  125#[cfg(any(test, feature = "test-support"))]
  126pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  127pub use worktree::{
  128    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  129    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  130};
  131
  132const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  133pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  134
  135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  136pub enum FormatTrigger {
  137    Save,
  138    Manual,
  139}
  140
  141pub enum LspFormatTarget {
  142    Buffers,
  143    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  144}
  145
  146pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  147
  148impl FormatTrigger {
  149    fn from_proto(value: i32) -> FormatTrigger {
  150        match value {
  151            0 => FormatTrigger::Save,
  152            1 => FormatTrigger::Manual,
  153            _ => FormatTrigger::Save,
  154        }
  155    }
  156}
  157
  158#[derive(Clone)]
  159struct UnifiedLanguageServer {
  160    id: LanguageServerId,
  161    project_roots: HashSet<Arc<Path>>,
  162}
  163
  164#[derive(Clone, Hash, PartialEq, Eq)]
  165struct LanguageServerSeed {
  166    worktree_id: WorktreeId,
  167    name: LanguageServerName,
  168    toolchain: Option<Toolchain>,
  169    settings: Arc<LspSettings>,
  170}
  171
  172#[derive(Debug)]
  173pub struct DocumentDiagnosticsUpdate<'a, D> {
  174    pub diagnostics: D,
  175    pub result_id: Option<String>,
  176    pub server_id: LanguageServerId,
  177    pub disk_based_sources: Cow<'a, [String]>,
  178}
  179
  180pub struct DocumentDiagnostics {
  181    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  182    document_abs_path: PathBuf,
  183    version: Option<i32>,
  184}
  185
  186pub struct LocalLspStore {
  187    weak: WeakEntity<LspStore>,
  188    worktree_store: Entity<WorktreeStore>,
  189    toolchain_store: Entity<LocalToolchainStore>,
  190    http_client: Arc<dyn HttpClient>,
  191    environment: Entity<ProjectEnvironment>,
  192    fs: Arc<dyn Fs>,
  193    languages: Arc<LanguageRegistry>,
  194    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  195    yarn: Entity<YarnPathStore>,
  196    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  197    buffers_being_formatted: HashSet<BufferId>,
  198    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  199    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  200    watched_manifest_filenames: HashSet<ManifestName>,
  201    language_server_paths_watched_for_rename:
  202        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  203    language_server_watcher_registrations:
  204        HashMap<LanguageServerId, HashMap<String, Vec<FileSystemWatcher>>>,
  205    supplementary_language_servers:
  206        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  207    prettier_store: Entity<PrettierStore>,
  208    next_diagnostic_group_id: usize,
  209    diagnostics: HashMap<
  210        WorktreeId,
  211        HashMap<
  212            Arc<Path>,
  213            Vec<(
  214                LanguageServerId,
  215                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  216            )>,
  217        >,
  218    >,
  219    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  220    _subscription: gpui::Subscription,
  221    lsp_tree: LanguageServerTree,
  222    registered_buffers: HashMap<BufferId, usize>,
  223    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  224    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  225}
  226
  227impl LocalLspStore {
  228    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  229    pub fn running_language_server_for_id(
  230        &self,
  231        id: LanguageServerId,
  232    ) -> Option<&Arc<LanguageServer>> {
  233        let language_server_state = self.language_servers.get(&id)?;
  234
  235        match language_server_state {
  236            LanguageServerState::Running { server, .. } => Some(server),
  237            LanguageServerState::Starting { .. } => None,
  238        }
  239    }
  240
  241    fn get_or_insert_language_server(
  242        &mut self,
  243        worktree_handle: &Entity<Worktree>,
  244        delegate: Arc<LocalLspAdapterDelegate>,
  245        disposition: &Arc<LaunchDisposition>,
  246        language_name: &LanguageName,
  247        cx: &mut App,
  248    ) -> LanguageServerId {
  249        let key = LanguageServerSeed {
  250            worktree_id: worktree_handle.read(cx).id(),
  251            name: disposition.server_name.clone(),
  252            settings: disposition.settings.clone(),
  253            toolchain: disposition.toolchain.clone(),
  254        };
  255        if let Some(state) = self.language_server_ids.get_mut(&key) {
  256            state.project_roots.insert(disposition.path.path.clone());
  257            state.id
  258        } else {
  259            let adapter = self
  260                .languages
  261                .lsp_adapters(language_name)
  262                .into_iter()
  263                .find(|adapter| adapter.name() == disposition.server_name)
  264                .expect("To find LSP adapter");
  265            let new_language_server_id = self.start_language_server(
  266                worktree_handle,
  267                delegate,
  268                adapter,
  269                disposition.settings.clone(),
  270                key.clone(),
  271                cx,
  272            );
  273            if let Some(state) = self.language_server_ids.get_mut(&key) {
  274                state.project_roots.insert(disposition.path.path.clone());
  275            } else {
  276                debug_assert!(
  277                    false,
  278                    "Expected `start_language_server` to ensure that `key` exists in a map"
  279                );
  280            }
  281            new_language_server_id
  282        }
  283    }
  284
  285    fn start_language_server(
  286        &mut self,
  287        worktree_handle: &Entity<Worktree>,
  288        delegate: Arc<LocalLspAdapterDelegate>,
  289        adapter: Arc<CachedLspAdapter>,
  290        settings: Arc<LspSettings>,
  291        key: LanguageServerSeed,
  292        cx: &mut App,
  293    ) -> LanguageServerId {
  294        let worktree = worktree_handle.read(cx);
  295
  296        let root_path = worktree.abs_path();
  297        let toolchain = key.toolchain.clone();
  298        let override_options = settings.initialization_options.clone();
  299
  300        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  301
  302        let server_id = self.languages.next_language_server_id();
  303        log::trace!(
  304            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  305            adapter.name.0
  306        );
  307
  308        let binary = self.get_language_server_binary(
  309            adapter.clone(),
  310            settings,
  311            toolchain.clone(),
  312            delegate.clone(),
  313            true,
  314            cx,
  315        );
  316        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  317
  318        let pending_server = cx.spawn({
  319            let adapter = adapter.clone();
  320            let server_name = adapter.name.clone();
  321            let stderr_capture = stderr_capture.clone();
  322            #[cfg(any(test, feature = "test-support"))]
  323            let lsp_store = self.weak.clone();
  324            let pending_workspace_folders = pending_workspace_folders.clone();
  325            async move |cx| {
  326                let binary = binary.await?;
  327                #[cfg(any(test, feature = "test-support"))]
  328                if let Some(server) = lsp_store
  329                    .update(&mut cx.clone(), |this, cx| {
  330                        this.languages.create_fake_language_server(
  331                            server_id,
  332                            &server_name,
  333                            binary.clone(),
  334                            &mut cx.to_async(),
  335                        )
  336                    })
  337                    .ok()
  338                    .flatten()
  339                {
  340                    return Ok(server);
  341                }
  342
  343                let code_action_kinds = adapter.code_action_kinds();
  344                lsp::LanguageServer::new(
  345                    stderr_capture,
  346                    server_id,
  347                    server_name,
  348                    binary,
  349                    &root_path,
  350                    code_action_kinds,
  351                    Some(pending_workspace_folders),
  352                    cx,
  353                )
  354            }
  355        });
  356
  357        let startup = {
  358            let server_name = adapter.name.0.clone();
  359            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  360            let key = key.clone();
  361            let adapter = adapter.clone();
  362            let lsp_store = self.weak.clone();
  363            let pending_workspace_folders = pending_workspace_folders.clone();
  364            let fs = self.fs.clone();
  365            let pull_diagnostics = ProjectSettings::get_global(cx)
  366                .diagnostics
  367                .lsp_pull_diagnostics
  368                .enabled;
  369            cx.spawn(async move |cx| {
  370                let result = async {
  371                    let language_server = pending_server.await?;
  372
  373                    let workspace_config = Self::workspace_configuration_for_adapter(
  374                        adapter.adapter.clone(),
  375                        fs.as_ref(),
  376                        &delegate,
  377                        toolchain,
  378                        cx,
  379                    )
  380                    .await?;
  381
  382                    let mut initialization_options = Self::initialization_options_for_adapter(
  383                        adapter.adapter.clone(),
  384                        fs.as_ref(),
  385                        &delegate,
  386                    )
  387                    .await?;
  388
  389                    match (&mut initialization_options, override_options) {
  390                        (Some(initialization_options), Some(override_options)) => {
  391                            merge_json_value_into(override_options, initialization_options);
  392                        }
  393                        (None, override_options) => initialization_options = override_options,
  394                        _ => {}
  395                    }
  396
  397                    let initialization_params = cx.update(|cx| {
  398                        let mut params =
  399                            language_server.default_initialize_params(pull_diagnostics, cx);
  400                        params.initialization_options = initialization_options;
  401                        adapter.adapter.prepare_initialize_params(params, cx)
  402                    })??;
  403
  404                    Self::setup_lsp_messages(
  405                        lsp_store.clone(),
  406                        fs,
  407                        &language_server,
  408                        delegate.clone(),
  409                        adapter.clone(),
  410                    );
  411
  412                    let did_change_configuration_params =
  413                        Arc::new(lsp::DidChangeConfigurationParams {
  414                            settings: workspace_config,
  415                        });
  416                    let language_server = cx
  417                        .update(|cx| {
  418                            language_server.initialize(
  419                                initialization_params,
  420                                did_change_configuration_params.clone(),
  421                                cx,
  422                            )
  423                        })?
  424                        .await
  425                        .inspect_err(|_| {
  426                            if let Some(lsp_store) = lsp_store.upgrade() {
  427                                lsp_store
  428                                    .update(cx, |lsp_store, cx| {
  429                                        lsp_store.cleanup_lsp_data(server_id);
  430                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  431                                    })
  432                                    .ok();
  433                            }
  434                        })?;
  435
  436                    language_server
  437                        .notify::<lsp::notification::DidChangeConfiguration>(
  438                            &did_change_configuration_params,
  439                        )
  440                        .ok();
  441
  442                    anyhow::Ok(language_server)
  443                }
  444                .await;
  445
  446                match result {
  447                    Ok(server) => {
  448                        lsp_store
  449                            .update(cx, |lsp_store, cx| {
  450                                lsp_store.insert_newly_running_language_server(
  451                                    adapter,
  452                                    server.clone(),
  453                                    server_id,
  454                                    key,
  455                                    pending_workspace_folders,
  456                                    cx,
  457                                );
  458                            })
  459                            .ok();
  460                        stderr_capture.lock().take();
  461                        Some(server)
  462                    }
  463
  464                    Err(err) => {
  465                        let log = stderr_capture.lock().take().unwrap_or_default();
  466                        delegate.update_status(
  467                            adapter.name(),
  468                            BinaryStatus::Failed {
  469                                error: if log.is_empty() {
  470                                    format!("{err:#}")
  471                                } else {
  472                                    format!("{err:#}\n-- stderr --\n{log}")
  473                                },
  474                            },
  475                        );
  476                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  477                        if !log.is_empty() {
  478                            log::error!("server stderr: {log}");
  479                        }
  480                        None
  481                    }
  482                }
  483            })
  484        };
  485        let state = LanguageServerState::Starting {
  486            startup,
  487            pending_workspace_folders,
  488        };
  489
  490        self.languages
  491            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  492
  493        self.language_servers.insert(server_id, state);
  494        self.language_server_ids
  495            .entry(key)
  496            .or_insert(UnifiedLanguageServer {
  497                id: server_id,
  498                project_roots: Default::default(),
  499            });
  500        server_id
  501    }
  502
  503    fn get_language_server_binary(
  504        &self,
  505        adapter: Arc<CachedLspAdapter>,
  506        settings: Arc<LspSettings>,
  507        toolchain: Option<Toolchain>,
  508        delegate: Arc<dyn LspAdapterDelegate>,
  509        allow_binary_download: bool,
  510        cx: &mut App,
  511    ) -> Task<Result<LanguageServerBinary>> {
  512        if let Some(settings) = settings.binary.as_ref()
  513            && settings.path.is_some()
  514        {
  515            let settings = settings.clone();
  516
  517            return cx.background_spawn(async move {
  518                let mut env = delegate.shell_env().await;
  519                env.extend(settings.env.unwrap_or_default());
  520
  521                Ok(LanguageServerBinary {
  522                    path: PathBuf::from(&settings.path.unwrap()),
  523                    env: Some(env),
  524                    arguments: settings
  525                        .arguments
  526                        .unwrap_or_default()
  527                        .iter()
  528                        .map(Into::into)
  529                        .collect(),
  530                })
  531            });
  532        }
  533        let lsp_binary_options = LanguageServerBinaryOptions {
  534            allow_path_lookup: !settings
  535                .binary
  536                .as_ref()
  537                .and_then(|b| b.ignore_system_version)
  538                .unwrap_or_default(),
  539            allow_binary_download,
  540        };
  541
  542        cx.spawn(async move |cx| {
  543            let binary_result = adapter
  544                .clone()
  545                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  546                .await;
  547
  548            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  549
  550            let mut binary = binary_result?;
  551            let mut shell_env = delegate.shell_env().await;
  552
  553            shell_env.extend(binary.env.unwrap_or_default());
  554
  555            if let Some(settings) = settings.binary.as_ref() {
  556                if let Some(arguments) = &settings.arguments {
  557                    binary.arguments = arguments.iter().map(Into::into).collect();
  558                }
  559                if let Some(env) = &settings.env {
  560                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  561                }
  562            }
  563
  564            binary.env = Some(shell_env);
  565            Ok(binary)
  566        })
  567    }
  568
  569    fn setup_lsp_messages(
  570        this: WeakEntity<LspStore>,
  571        fs: Arc<dyn Fs>,
  572        language_server: &LanguageServer,
  573        delegate: Arc<dyn LspAdapterDelegate>,
  574        adapter: Arc<CachedLspAdapter>,
  575    ) {
  576        let name = language_server.name();
  577        let server_id = language_server.server_id();
  578        language_server
  579            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  580                let adapter = adapter.clone();
  581                let this = this.clone();
  582                move |mut params, cx| {
  583                    let adapter = adapter.clone();
  584                    if let Some(this) = this.upgrade() {
  585                        this.update(cx, |this, cx| {
  586                            {
  587                                let buffer = params
  588                                    .uri
  589                                    .to_file_path()
  590                                    .map(|file_path| this.get_buffer(&file_path, cx))
  591                                    .ok()
  592                                    .flatten();
  593                                adapter.process_diagnostics(&mut params, server_id, buffer);
  594                            }
  595
  596                            this.merge_lsp_diagnostics(
  597                                DiagnosticSourceKind::Pushed,
  598                                vec![DocumentDiagnosticsUpdate {
  599                                    server_id,
  600                                    diagnostics: params,
  601                                    result_id: None,
  602                                    disk_based_sources: Cow::Borrowed(
  603                                        &adapter.disk_based_diagnostic_sources,
  604                                    ),
  605                                }],
  606                                |_, diagnostic, cx| match diagnostic.source_kind {
  607                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  608                                        adapter.retain_old_diagnostic(diagnostic, cx)
  609                                    }
  610                                    DiagnosticSourceKind::Pulled => true,
  611                                },
  612                                cx,
  613                            )
  614                            .log_err();
  615                        })
  616                        .ok();
  617                    }
  618                }
  619            })
  620            .detach();
  621        language_server
  622            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  623                let adapter = adapter.adapter.clone();
  624                let delegate = delegate.clone();
  625                let this = this.clone();
  626                let fs = fs.clone();
  627                move |params, cx| {
  628                    let adapter = adapter.clone();
  629                    let delegate = delegate.clone();
  630                    let this = this.clone();
  631                    let fs = fs.clone();
  632                    let mut cx = cx.clone();
  633                    async move {
  634                        let toolchain_for_id = this
  635                            .update(&mut cx, |this, _| {
  636                                this.as_local()?.language_server_ids.iter().find_map(
  637                                    |(seed, value)| {
  638                                        (value.id == server_id).then(|| seed.toolchain.clone())
  639                                    },
  640                                )
  641                            })?
  642                            .context("Expected the LSP store to be in a local mode")?;
  643                        let workspace_config = Self::workspace_configuration_for_adapter(
  644                            adapter.clone(),
  645                            fs.as_ref(),
  646                            &delegate,
  647                            toolchain_for_id,
  648                            &mut cx,
  649                        )
  650                        .await?;
  651
  652                        Ok(params
  653                            .items
  654                            .into_iter()
  655                            .map(|item| {
  656                                if let Some(section) = &item.section {
  657                                    workspace_config
  658                                        .get(section)
  659                                        .cloned()
  660                                        .unwrap_or(serde_json::Value::Null)
  661                                } else {
  662                                    workspace_config.clone()
  663                                }
  664                            })
  665                            .collect())
  666                    }
  667                }
  668            })
  669            .detach();
  670
  671        language_server
  672            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  673                let this = this.clone();
  674                move |_, cx| {
  675                    let this = this.clone();
  676                    let cx = cx.clone();
  677                    async move {
  678                        let Some(server) =
  679                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  680                        else {
  681                            return Ok(None);
  682                        };
  683                        let root = server.workspace_folders();
  684                        Ok(Some(
  685                            root.into_iter()
  686                                .map(|uri| WorkspaceFolder {
  687                                    uri,
  688                                    name: Default::default(),
  689                                })
  690                                .collect(),
  691                        ))
  692                    }
  693                }
  694            })
  695            .detach();
  696        // Even though we don't have handling for these requests, respond to them to
  697        // avoid stalling any language server like `gopls` which waits for a response
  698        // to these requests when initializing.
  699        language_server
  700            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  701                let this = this.clone();
  702                move |params, cx| {
  703                    let this = this.clone();
  704                    let mut cx = cx.clone();
  705                    async move {
  706                        this.update(&mut cx, |this, _| {
  707                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  708                                && let lsp::NumberOrString::String(token) = params.token
  709                            {
  710                                status.progress_tokens.insert(token);
  711                            }
  712                        })?;
  713
  714                        Ok(())
  715                    }
  716                }
  717            })
  718            .detach();
  719
  720        language_server
  721            .on_request::<lsp::request::RegisterCapability, _, _>({
  722                let lsp_store = this.clone();
  723                move |params, cx| {
  724                    let lsp_store = lsp_store.clone();
  725                    let mut cx = cx.clone();
  726                    async move {
  727                        lsp_store
  728                            .update(&mut cx, |lsp_store, cx| {
  729                                if lsp_store.as_local().is_some() {
  730                                    match lsp_store
  731                                        .register_server_capabilities(server_id, params, cx)
  732                                    {
  733                                        Ok(()) => {}
  734                                        Err(e) => {
  735                                            log::error!(
  736                                                "Failed to register server capabilities: {e:#}"
  737                                            );
  738                                        }
  739                                    };
  740                                }
  741                            })
  742                            .ok();
  743                        Ok(())
  744                    }
  745                }
  746            })
  747            .detach();
  748
  749        language_server
  750            .on_request::<lsp::request::UnregisterCapability, _, _>({
  751                let lsp_store = this.clone();
  752                move |params, cx| {
  753                    let lsp_store = lsp_store.clone();
  754                    let mut cx = cx.clone();
  755                    async move {
  756                        lsp_store
  757                            .update(&mut cx, |lsp_store, cx| {
  758                                if lsp_store.as_local().is_some() {
  759                                    match lsp_store
  760                                        .unregister_server_capabilities(server_id, params, cx)
  761                                    {
  762                                        Ok(()) => {}
  763                                        Err(e) => {
  764                                            log::error!(
  765                                                "Failed to unregister server capabilities: {e:#}"
  766                                            );
  767                                        }
  768                                    }
  769                                }
  770                            })
  771                            .ok();
  772                        Ok(())
  773                    }
  774                }
  775            })
  776            .detach();
  777
  778        language_server
  779            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  780                let this = this.clone();
  781                move |params, cx| {
  782                    let mut cx = cx.clone();
  783                    let this = this.clone();
  784                    async move {
  785                        LocalLspStore::on_lsp_workspace_edit(
  786                            this.clone(),
  787                            params,
  788                            server_id,
  789                            &mut cx,
  790                        )
  791                        .await
  792                    }
  793                }
  794            })
  795            .detach();
  796
  797        language_server
  798            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  799                let this = this.clone();
  800                move |(), cx| {
  801                    let this = this.clone();
  802                    let mut cx = cx.clone();
  803                    async move {
  804                        this.update(&mut cx, |this, cx| {
  805                            cx.emit(LspStoreEvent::RefreshInlayHints);
  806                            this.downstream_client.as_ref().map(|(client, project_id)| {
  807                                client.send(proto::RefreshInlayHints {
  808                                    project_id: *project_id,
  809                                })
  810                            })
  811                        })?
  812                        .transpose()?;
  813                        Ok(())
  814                    }
  815                }
  816            })
  817            .detach();
  818
  819        language_server
  820            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  821                let this = this.clone();
  822                move |(), cx| {
  823                    let this = this.clone();
  824                    let mut cx = cx.clone();
  825                    async move {
  826                        this.update(&mut cx, |this, cx| {
  827                            cx.emit(LspStoreEvent::RefreshCodeLens);
  828                            this.downstream_client.as_ref().map(|(client, project_id)| {
  829                                client.send(proto::RefreshCodeLens {
  830                                    project_id: *project_id,
  831                                })
  832                            })
  833                        })?
  834                        .transpose()?;
  835                        Ok(())
  836                    }
  837                }
  838            })
  839            .detach();
  840
  841        language_server
  842            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  843                let this = this.clone();
  844                move |(), cx| {
  845                    let this = this.clone();
  846                    let mut cx = cx.clone();
  847                    async move {
  848                        this.update(&mut cx, |lsp_store, _| {
  849                            lsp_store.pull_workspace_diagnostics(server_id);
  850                            lsp_store
  851                                .downstream_client
  852                                .as_ref()
  853                                .map(|(client, project_id)| {
  854                                    client.send(proto::PullWorkspaceDiagnostics {
  855                                        project_id: *project_id,
  856                                        server_id: server_id.to_proto(),
  857                                    })
  858                                })
  859                        })?
  860                        .transpose()?;
  861                        Ok(())
  862                    }
  863                }
  864            })
  865            .detach();
  866
  867        language_server
  868            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  869                let this = this.clone();
  870                let name = name.to_string();
  871                move |params, cx| {
  872                    let this = this.clone();
  873                    let name = name.to_string();
  874                    let mut cx = cx.clone();
  875                    async move {
  876                        let actions = params.actions.unwrap_or_default();
  877                        let (tx, rx) = smol::channel::bounded(1);
  878                        let request = LanguageServerPromptRequest {
  879                            level: match params.typ {
  880                                lsp::MessageType::ERROR => PromptLevel::Critical,
  881                                lsp::MessageType::WARNING => PromptLevel::Warning,
  882                                _ => PromptLevel::Info,
  883                            },
  884                            message: params.message,
  885                            actions,
  886                            response_channel: tx,
  887                            lsp_name: name.clone(),
  888                        };
  889
  890                        let did_update = this
  891                            .update(&mut cx, |_, cx| {
  892                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  893                            })
  894                            .is_ok();
  895                        if did_update {
  896                            let response = rx.recv().await.ok();
  897                            Ok(response)
  898                        } else {
  899                            Ok(None)
  900                        }
  901                    }
  902                }
  903            })
  904            .detach();
  905        language_server
  906            .on_notification::<lsp::notification::ShowMessage, _>({
  907                let this = this.clone();
  908                let name = name.to_string();
  909                move |params, cx| {
  910                    let this = this.clone();
  911                    let name = name.to_string();
  912                    let mut cx = cx.clone();
  913
  914                    let (tx, _) = smol::channel::bounded(1);
  915                    let request = LanguageServerPromptRequest {
  916                        level: match params.typ {
  917                            lsp::MessageType::ERROR => PromptLevel::Critical,
  918                            lsp::MessageType::WARNING => PromptLevel::Warning,
  919                            _ => PromptLevel::Info,
  920                        },
  921                        message: params.message,
  922                        actions: vec![],
  923                        response_channel: tx,
  924                        lsp_name: name,
  925                    };
  926
  927                    let _ = this.update(&mut cx, |_, cx| {
  928                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  929                    });
  930                }
  931            })
  932            .detach();
  933
  934        let disk_based_diagnostics_progress_token =
  935            adapter.disk_based_diagnostics_progress_token.clone();
  936
  937        language_server
  938            .on_notification::<lsp::notification::Progress, _>({
  939                let this = this.clone();
  940                move |params, cx| {
  941                    if let Some(this) = this.upgrade() {
  942                        this.update(cx, |this, cx| {
  943                            this.on_lsp_progress(
  944                                params,
  945                                server_id,
  946                                disk_based_diagnostics_progress_token.clone(),
  947                                cx,
  948                            );
  949                        })
  950                        .ok();
  951                    }
  952                }
  953            })
  954            .detach();
  955
  956        language_server
  957            .on_notification::<lsp::notification::LogMessage, _>({
  958                let this = this.clone();
  959                move |params, cx| {
  960                    if let Some(this) = this.upgrade() {
  961                        this.update(cx, |_, cx| {
  962                            cx.emit(LspStoreEvent::LanguageServerLog(
  963                                server_id,
  964                                LanguageServerLogType::Log(params.typ),
  965                                params.message,
  966                            ));
  967                        })
  968                        .ok();
  969                    }
  970                }
  971            })
  972            .detach();
  973
  974        language_server
  975            .on_notification::<lsp::notification::LogTrace, _>({
  976                let this = this.clone();
  977                move |params, cx| {
  978                    let mut cx = cx.clone();
  979                    if let Some(this) = this.upgrade() {
  980                        this.update(&mut cx, |_, cx| {
  981                            cx.emit(LspStoreEvent::LanguageServerLog(
  982                                server_id,
  983                                LanguageServerLogType::Trace {
  984                                    verbose_info: params.verbose,
  985                                },
  986                                params.message,
  987                            ));
  988                        })
  989                        .ok();
  990                    }
  991                }
  992            })
  993            .detach();
  994
  995        json_language_server_ext::register_requests(this.clone(), language_server);
  996        rust_analyzer_ext::register_notifications(this.clone(), language_server);
  997        clangd_ext::register_notifications(this, language_server, adapter);
  998    }
  999
 1000    fn shutdown_language_servers_on_quit(
 1001        &mut self,
 1002        _: &mut Context<LspStore>,
 1003    ) -> impl Future<Output = ()> + use<> {
 1004        let shutdown_futures = self
 1005            .language_servers
 1006            .drain()
 1007            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1008            .collect::<Vec<_>>();
 1009
 1010        async move {
 1011            join_all(shutdown_futures).await;
 1012        }
 1013    }
 1014
 1015    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1016        match server_state {
 1017            LanguageServerState::Running { server, .. } => {
 1018                if let Some(shutdown) = server.shutdown() {
 1019                    shutdown.await;
 1020                }
 1021            }
 1022            LanguageServerState::Starting { startup, .. } => {
 1023                if let Some(server) = startup.await
 1024                    && let Some(shutdown) = server.shutdown()
 1025                {
 1026                    shutdown.await;
 1027                }
 1028            }
 1029        }
 1030        Ok(())
 1031    }
 1032
 1033    fn language_servers_for_worktree(
 1034        &self,
 1035        worktree_id: WorktreeId,
 1036    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1037        self.language_server_ids
 1038            .iter()
 1039            .filter_map(move |(seed, state)| {
 1040                if seed.worktree_id != worktree_id {
 1041                    return None;
 1042                }
 1043
 1044                if let Some(LanguageServerState::Running { server, .. }) =
 1045                    self.language_servers.get(&state.id)
 1046                {
 1047                    Some(server)
 1048                } else {
 1049                    None
 1050                }
 1051            })
 1052    }
 1053
 1054    fn language_server_ids_for_project_path(
 1055        &self,
 1056        project_path: ProjectPath,
 1057        language: &Language,
 1058        cx: &mut App,
 1059    ) -> Vec<LanguageServerId> {
 1060        let Some(worktree) = self
 1061            .worktree_store
 1062            .read(cx)
 1063            .worktree_for_id(project_path.worktree_id, cx)
 1064        else {
 1065            return Vec::new();
 1066        };
 1067        let delegate: Arc<dyn ManifestDelegate> =
 1068            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1069
 1070        self.lsp_tree
 1071            .get(
 1072                project_path,
 1073                language.name(),
 1074                language.manifest(),
 1075                &delegate,
 1076                cx,
 1077            )
 1078            .collect::<Vec<_>>()
 1079    }
 1080
 1081    fn language_server_ids_for_buffer(
 1082        &self,
 1083        buffer: &Buffer,
 1084        cx: &mut App,
 1085    ) -> Vec<LanguageServerId> {
 1086        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1087            let worktree_id = file.worktree_id(cx);
 1088
 1089            let path: Arc<Path> = file
 1090                .path()
 1091                .parent()
 1092                .map(Arc::from)
 1093                .unwrap_or_else(|| file.path().clone());
 1094            let worktree_path = ProjectPath { worktree_id, path };
 1095            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1096        } else {
 1097            Vec::new()
 1098        }
 1099    }
 1100
 1101    fn language_servers_for_buffer<'a>(
 1102        &'a self,
 1103        buffer: &'a Buffer,
 1104        cx: &'a mut App,
 1105    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1106        self.language_server_ids_for_buffer(buffer, cx)
 1107            .into_iter()
 1108            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1109                LanguageServerState::Running {
 1110                    adapter, server, ..
 1111                } => Some((adapter, server)),
 1112                _ => None,
 1113            })
 1114    }
 1115
 1116    async fn execute_code_action_kind_locally(
 1117        lsp_store: WeakEntity<LspStore>,
 1118        mut buffers: Vec<Entity<Buffer>>,
 1119        kind: CodeActionKind,
 1120        push_to_history: bool,
 1121        cx: &mut AsyncApp,
 1122    ) -> anyhow::Result<ProjectTransaction> {
 1123        // Do not allow multiple concurrent code actions requests for the
 1124        // same buffer.
 1125        lsp_store.update(cx, |this, cx| {
 1126            let this = this.as_local_mut().unwrap();
 1127            buffers.retain(|buffer| {
 1128                this.buffers_being_formatted
 1129                    .insert(buffer.read(cx).remote_id())
 1130            });
 1131        })?;
 1132        let _cleanup = defer({
 1133            let this = lsp_store.clone();
 1134            let mut cx = cx.clone();
 1135            let buffers = &buffers;
 1136            move || {
 1137                this.update(&mut cx, |this, cx| {
 1138                    let this = this.as_local_mut().unwrap();
 1139                    for buffer in buffers {
 1140                        this.buffers_being_formatted
 1141                            .remove(&buffer.read(cx).remote_id());
 1142                    }
 1143                })
 1144                .ok();
 1145            }
 1146        });
 1147        let mut project_transaction = ProjectTransaction::default();
 1148
 1149        for buffer in &buffers {
 1150            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1151                buffer.update(cx, |buffer, cx| {
 1152                    lsp_store
 1153                        .as_local()
 1154                        .unwrap()
 1155                        .language_servers_for_buffer(buffer, cx)
 1156                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1157                        .collect::<Vec<_>>()
 1158                })
 1159            })?;
 1160            for (_, language_server) in adapters_and_servers.iter() {
 1161                let actions = Self::get_server_code_actions_from_action_kinds(
 1162                    &lsp_store,
 1163                    language_server.server_id(),
 1164                    vec![kind.clone()],
 1165                    buffer,
 1166                    cx,
 1167                )
 1168                .await?;
 1169                Self::execute_code_actions_on_server(
 1170                    &lsp_store,
 1171                    language_server,
 1172                    actions,
 1173                    push_to_history,
 1174                    &mut project_transaction,
 1175                    cx,
 1176                )
 1177                .await?;
 1178            }
 1179        }
 1180        Ok(project_transaction)
 1181    }
 1182
 1183    async fn format_locally(
 1184        lsp_store: WeakEntity<LspStore>,
 1185        mut buffers: Vec<FormattableBuffer>,
 1186        push_to_history: bool,
 1187        trigger: FormatTrigger,
 1188        logger: zlog::Logger,
 1189        cx: &mut AsyncApp,
 1190    ) -> anyhow::Result<ProjectTransaction> {
 1191        // Do not allow multiple concurrent formatting requests for the
 1192        // same buffer.
 1193        lsp_store.update(cx, |this, cx| {
 1194            let this = this.as_local_mut().unwrap();
 1195            buffers.retain(|buffer| {
 1196                this.buffers_being_formatted
 1197                    .insert(buffer.handle.read(cx).remote_id())
 1198            });
 1199        })?;
 1200
 1201        let _cleanup = defer({
 1202            let this = lsp_store.clone();
 1203            let mut cx = cx.clone();
 1204            let buffers = &buffers;
 1205            move || {
 1206                this.update(&mut cx, |this, cx| {
 1207                    let this = this.as_local_mut().unwrap();
 1208                    for buffer in buffers {
 1209                        this.buffers_being_formatted
 1210                            .remove(&buffer.handle.read(cx).remote_id());
 1211                    }
 1212                })
 1213                .ok();
 1214            }
 1215        });
 1216
 1217        let mut project_transaction = ProjectTransaction::default();
 1218
 1219        for buffer in &buffers {
 1220            zlog::debug!(
 1221                logger =>
 1222                "formatting buffer '{:?}'",
 1223                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1224            );
 1225            // Create an empty transaction to hold all of the formatting edits.
 1226            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1227                // ensure no transactions created while formatting are
 1228                // grouped with the previous transaction in the history
 1229                // based on the transaction group interval
 1230                buffer.finalize_last_transaction();
 1231                buffer
 1232                    .start_transaction()
 1233                    .context("transaction already open")?;
 1234                buffer.end_transaction(cx);
 1235                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1236                buffer.finalize_last_transaction();
 1237                anyhow::Ok(transaction_id)
 1238            })??;
 1239
 1240            let result = Self::format_buffer_locally(
 1241                lsp_store.clone(),
 1242                buffer,
 1243                formatting_transaction_id,
 1244                trigger,
 1245                logger,
 1246                cx,
 1247            )
 1248            .await;
 1249
 1250            buffer.handle.update(cx, |buffer, cx| {
 1251                let Some(formatting_transaction) =
 1252                    buffer.get_transaction(formatting_transaction_id).cloned()
 1253                else {
 1254                    zlog::warn!(logger => "no formatting transaction");
 1255                    return;
 1256                };
 1257                if formatting_transaction.edit_ids.is_empty() {
 1258                    zlog::debug!(logger => "no changes made while formatting");
 1259                    buffer.forget_transaction(formatting_transaction_id);
 1260                    return;
 1261                }
 1262                if !push_to_history {
 1263                    zlog::trace!(logger => "forgetting format transaction");
 1264                    buffer.forget_transaction(formatting_transaction.id);
 1265                }
 1266                project_transaction
 1267                    .0
 1268                    .insert(cx.entity(), formatting_transaction);
 1269            })?;
 1270
 1271            result?;
 1272        }
 1273
 1274        Ok(project_transaction)
 1275    }
 1276
 1277    async fn format_buffer_locally(
 1278        lsp_store: WeakEntity<LspStore>,
 1279        buffer: &FormattableBuffer,
 1280        formatting_transaction_id: clock::Lamport,
 1281        trigger: FormatTrigger,
 1282        logger: zlog::Logger,
 1283        cx: &mut AsyncApp,
 1284    ) -> Result<()> {
 1285        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1286            buffer.handle.update(cx, |buffer, cx| {
 1287                let adapters_and_servers = lsp_store
 1288                    .as_local()
 1289                    .unwrap()
 1290                    .language_servers_for_buffer(buffer, cx)
 1291                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1292                    .collect::<Vec<_>>();
 1293                let settings =
 1294                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1295                        .into_owned();
 1296                (adapters_and_servers, settings)
 1297            })
 1298        })?;
 1299
 1300        /// Apply edits to the buffer that will become part of the formatting transaction.
 1301        /// Fails if the buffer has been edited since the start of that transaction.
 1302        fn extend_formatting_transaction(
 1303            buffer: &FormattableBuffer,
 1304            formatting_transaction_id: text::TransactionId,
 1305            cx: &mut AsyncApp,
 1306            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1307        ) -> anyhow::Result<()> {
 1308            buffer.handle.update(cx, |buffer, cx| {
 1309                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1310                if last_transaction_id != Some(formatting_transaction_id) {
 1311                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1312                }
 1313                buffer.start_transaction();
 1314                operation(buffer, cx);
 1315                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1316                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1317                }
 1318                Ok(())
 1319            })?
 1320        }
 1321
 1322        // handle whitespace formatting
 1323        if settings.remove_trailing_whitespace_on_save {
 1324            zlog::trace!(logger => "removing trailing whitespace");
 1325            let diff = buffer
 1326                .handle
 1327                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1328                .await;
 1329            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1330                buffer.apply_diff(diff, cx);
 1331            })?;
 1332        }
 1333
 1334        if settings.ensure_final_newline_on_save {
 1335            zlog::trace!(logger => "ensuring final newline");
 1336            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1337                buffer.ensure_final_newline(cx);
 1338            })?;
 1339        }
 1340
 1341        // Formatter for `code_actions_on_format` that runs before
 1342        // the rest of the formatters
 1343        let mut code_actions_on_format_formatter = None;
 1344        let should_run_code_actions_on_format = !matches!(
 1345            (trigger, &settings.format_on_save),
 1346            (FormatTrigger::Save, &FormatOnSave::Off)
 1347        );
 1348        if should_run_code_actions_on_format {
 1349            let have_code_actions_to_run_on_format = settings
 1350                .code_actions_on_format
 1351                .values()
 1352                .any(|enabled| *enabled);
 1353            if have_code_actions_to_run_on_format {
 1354                zlog::trace!(logger => "going to run code actions on format");
 1355                code_actions_on_format_formatter = Some(Formatter::CodeActions(
 1356                    settings.code_actions_on_format.clone(),
 1357                ));
 1358            }
 1359        }
 1360
 1361        let formatters = match (trigger, &settings.format_on_save) {
 1362            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1363            (FormatTrigger::Save, FormatOnSave::List(formatters)) => formatters.as_ref(),
 1364            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1365                match &settings.formatter {
 1366                    SelectedFormatter::Auto => {
 1367                        if settings.prettier.allowed {
 1368                            zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1369                            std::slice::from_ref(&Formatter::Prettier)
 1370                        } else {
 1371                            zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1372                            std::slice::from_ref(&Formatter::LanguageServer { name: None })
 1373                        }
 1374                    }
 1375                    SelectedFormatter::List(formatter_list) => formatter_list.as_ref(),
 1376                }
 1377            }
 1378        };
 1379
 1380        let formatters = code_actions_on_format_formatter.iter().chain(formatters);
 1381
 1382        for formatter in formatters {
 1383            match formatter {
 1384                Formatter::Prettier => {
 1385                    let logger = zlog::scoped!(logger => "prettier");
 1386                    zlog::trace!(logger => "formatting");
 1387                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1388
 1389                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1390                        lsp_store.prettier_store().unwrap().downgrade()
 1391                    })?;
 1392                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1393                        .await
 1394                        .transpose()?;
 1395                    let Some(diff) = diff else {
 1396                        zlog::trace!(logger => "No changes");
 1397                        continue;
 1398                    };
 1399
 1400                    extend_formatting_transaction(
 1401                        buffer,
 1402                        formatting_transaction_id,
 1403                        cx,
 1404                        |buffer, cx| {
 1405                            buffer.apply_diff(diff, cx);
 1406                        },
 1407                    )?;
 1408                }
 1409                Formatter::External { command, arguments } => {
 1410                    let logger = zlog::scoped!(logger => "command");
 1411                    zlog::trace!(logger => "formatting");
 1412                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1413
 1414                    let diff = Self::format_via_external_command(
 1415                        buffer,
 1416                        command.as_ref(),
 1417                        arguments.as_deref(),
 1418                        cx,
 1419                    )
 1420                    .await
 1421                    .with_context(|| {
 1422                        format!("Failed to format buffer via external command: {}", command)
 1423                    })?;
 1424                    let Some(diff) = diff else {
 1425                        zlog::trace!(logger => "No changes");
 1426                        continue;
 1427                    };
 1428
 1429                    extend_formatting_transaction(
 1430                        buffer,
 1431                        formatting_transaction_id,
 1432                        cx,
 1433                        |buffer, cx| {
 1434                            buffer.apply_diff(diff, cx);
 1435                        },
 1436                    )?;
 1437                }
 1438                Formatter::LanguageServer { name } => {
 1439                    let logger = zlog::scoped!(logger => "language-server");
 1440                    zlog::trace!(logger => "formatting");
 1441                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1442
 1443                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1444                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1445                        continue;
 1446                    };
 1447
 1448                    let language_server = if let Some(name) = name.as_deref() {
 1449                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1450                            if adapter.name.0.as_ref() == name {
 1451                                Some(server.clone())
 1452                            } else {
 1453                                None
 1454                            }
 1455                        })
 1456                    } else {
 1457                        adapters_and_servers.first().map(|e| e.1.clone())
 1458                    };
 1459
 1460                    let Some(language_server) = language_server else {
 1461                        log::debug!(
 1462                            "No language server found to format buffer '{:?}'. Skipping",
 1463                            buffer_path_abs.as_path().to_string_lossy()
 1464                        );
 1465                        continue;
 1466                    };
 1467
 1468                    zlog::trace!(
 1469                        logger =>
 1470                        "Formatting buffer '{:?}' using language server '{:?}'",
 1471                        buffer_path_abs.as_path().to_string_lossy(),
 1472                        language_server.name()
 1473                    );
 1474
 1475                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1476                        zlog::trace!(logger => "formatting ranges");
 1477                        Self::format_ranges_via_lsp(
 1478                            &lsp_store,
 1479                            &buffer.handle,
 1480                            ranges,
 1481                            buffer_path_abs,
 1482                            &language_server,
 1483                            &settings,
 1484                            cx,
 1485                        )
 1486                        .await
 1487                        .context("Failed to format ranges via language server")?
 1488                    } else {
 1489                        zlog::trace!(logger => "formatting full");
 1490                        Self::format_via_lsp(
 1491                            &lsp_store,
 1492                            &buffer.handle,
 1493                            buffer_path_abs,
 1494                            &language_server,
 1495                            &settings,
 1496                            cx,
 1497                        )
 1498                        .await
 1499                        .context("failed to format via language server")?
 1500                    };
 1501
 1502                    if edits.is_empty() {
 1503                        zlog::trace!(logger => "No changes");
 1504                        continue;
 1505                    }
 1506                    extend_formatting_transaction(
 1507                        buffer,
 1508                        formatting_transaction_id,
 1509                        cx,
 1510                        |buffer, cx| {
 1511                            buffer.edit(edits, None, cx);
 1512                        },
 1513                    )?;
 1514                }
 1515                Formatter::CodeActions(code_actions) => {
 1516                    let logger = zlog::scoped!(logger => "code-actions");
 1517                    zlog::trace!(logger => "formatting");
 1518                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1519
 1520                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1521                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1522                        continue;
 1523                    };
 1524                    let code_action_kinds = code_actions
 1525                        .iter()
 1526                        .filter_map(|(action_kind, enabled)| {
 1527                            enabled.then_some(action_kind.clone().into())
 1528                        })
 1529                        .collect::<Vec<_>>();
 1530                    if code_action_kinds.is_empty() {
 1531                        zlog::trace!(logger => "No code action kinds enabled, skipping");
 1532                        continue;
 1533                    }
 1534                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kinds);
 1535
 1536                    let mut actions_and_servers = Vec::new();
 1537
 1538                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1539                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1540                            &lsp_store,
 1541                            language_server.server_id(),
 1542                            code_action_kinds.clone(),
 1543                            &buffer.handle,
 1544                            cx,
 1545                        )
 1546                        .await
 1547                        .with_context(
 1548                            || format!("Failed to resolve code actions with kinds {:?} for language server {}",
 1549                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1550                                language_server.name())
 1551                        );
 1552                        let Ok(actions) = actions_result else {
 1553                            // note: it may be better to set result to the error and break formatters here
 1554                            // but for now we try to execute the actions that we can resolve and skip the rest
 1555                            zlog::error!(
 1556                                logger =>
 1557                                "Failed to resolve code actions with kinds {:?} with language server {}",
 1558                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1559                                language_server.name()
 1560                            );
 1561                            continue;
 1562                        };
 1563                        for action in actions {
 1564                            actions_and_servers.push((action, index));
 1565                        }
 1566                    }
 1567
 1568                    if actions_and_servers.is_empty() {
 1569                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1570                        continue;
 1571                    }
 1572
 1573                    'actions: for (mut action, server_index) in actions_and_servers {
 1574                        let server = &adapters_and_servers[server_index].1;
 1575
 1576                        let describe_code_action = |action: &CodeAction| {
 1577                            format!(
 1578                                "code action '{}' with title \"{}\" on server {}",
 1579                                action
 1580                                    .lsp_action
 1581                                    .action_kind()
 1582                                    .unwrap_or("unknown".into())
 1583                                    .as_str(),
 1584                                action.lsp_action.title(),
 1585                                server.name(),
 1586                            )
 1587                        };
 1588
 1589                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1590
 1591                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1592                            zlog::error!(
 1593                                logger =>
 1594                                "Failed to resolve {}. Error: {}",
 1595                                describe_code_action(&action),
 1596                                err
 1597                            );
 1598                            continue;
 1599                        }
 1600
 1601                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1602                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1603                            // but filters out and logs warnings for code actions that cause unreasonably
 1604                            // difficult handling on our part, such as:
 1605                            // - applying edits that call commands
 1606                            //   which can result in arbitrary workspace edits being sent from the server that
 1607                            //   have no way of being tied back to the command that initiated them (i.e. we
 1608                            //   can't know which edits are part of the format request, or if the server is done sending
 1609                            //   actions in response to the command)
 1610                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1611                            //   as we then would need to handle such changes correctly in the local history as well
 1612                            //   as the remote history through the ProjectTransaction
 1613                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1614                            // Supporting these actions is not impossible, but not supported as of yet.
 1615                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1616                                zlog::trace!(
 1617                                    logger =>
 1618                                    "No changes for code action. Skipping {}",
 1619                                    describe_code_action(&action),
 1620                                );
 1621                                continue;
 1622                            }
 1623
 1624                            let mut operations = Vec::new();
 1625                            if let Some(document_changes) = edit.document_changes {
 1626                                match document_changes {
 1627                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1628                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1629                                    ),
 1630                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1631                                }
 1632                            } else if let Some(changes) = edit.changes {
 1633                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1634                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1635                                        text_document:
 1636                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1637                                                uri,
 1638                                                version: None,
 1639                                            },
 1640                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1641                                    })
 1642                                }));
 1643                            }
 1644
 1645                            let mut edits = Vec::with_capacity(operations.len());
 1646
 1647                            if operations.is_empty() {
 1648                                zlog::trace!(
 1649                                    logger =>
 1650                                    "No changes for code action. Skipping {}",
 1651                                    describe_code_action(&action),
 1652                                );
 1653                                continue;
 1654                            }
 1655                            for operation in operations {
 1656                                let op = match operation {
 1657                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1658                                    lsp::DocumentChangeOperation::Op(_) => {
 1659                                        zlog::warn!(
 1660                                            logger =>
 1661                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1662                                            describe_code_action(&action),
 1663                                        );
 1664                                        continue 'actions;
 1665                                    }
 1666                                };
 1667                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1668                                    zlog::warn!(
 1669                                        logger =>
 1670                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1671                                        &op.text_document.uri,
 1672                                        describe_code_action(&action),
 1673                                    );
 1674                                    continue 'actions;
 1675                                };
 1676                                if &file_path != buffer_path_abs {
 1677                                    zlog::warn!(
 1678                                        logger =>
 1679                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1680                                        file_path,
 1681                                        buffer_path_abs,
 1682                                        describe_code_action(&action),
 1683                                    );
 1684                                    continue 'actions;
 1685                                }
 1686
 1687                                let mut lsp_edits = Vec::new();
 1688                                for edit in op.edits {
 1689                                    match edit {
 1690                                        Edit::Plain(edit) => {
 1691                                            if !lsp_edits.contains(&edit) {
 1692                                                lsp_edits.push(edit);
 1693                                            }
 1694                                        }
 1695                                        Edit::Annotated(edit) => {
 1696                                            if !lsp_edits.contains(&edit.text_edit) {
 1697                                                lsp_edits.push(edit.text_edit);
 1698                                            }
 1699                                        }
 1700                                        Edit::Snippet(_) => {
 1701                                            zlog::warn!(
 1702                                                logger =>
 1703                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1704                                                describe_code_action(&action),
 1705                                            );
 1706                                            continue 'actions;
 1707                                        }
 1708                                    }
 1709                                }
 1710                                let edits_result = lsp_store
 1711                                    .update(cx, |lsp_store, cx| {
 1712                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1713                                            &buffer.handle,
 1714                                            lsp_edits,
 1715                                            server.server_id(),
 1716                                            op.text_document.version,
 1717                                            cx,
 1718                                        )
 1719                                    })?
 1720                                    .await;
 1721                                let Ok(resolved_edits) = edits_result else {
 1722                                    zlog::warn!(
 1723                                        logger =>
 1724                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1725                                        buffer_path_abs.as_path(),
 1726                                        describe_code_action(&action),
 1727                                    );
 1728                                    continue 'actions;
 1729                                };
 1730                                edits.extend(resolved_edits);
 1731                            }
 1732
 1733                            if edits.is_empty() {
 1734                                zlog::warn!(logger => "No edits resolved from LSP");
 1735                                continue;
 1736                            }
 1737
 1738                            extend_formatting_transaction(
 1739                                buffer,
 1740                                formatting_transaction_id,
 1741                                cx,
 1742                                |buffer, cx| {
 1743                                    buffer.edit(edits, None, cx);
 1744                                },
 1745                            )?;
 1746                        }
 1747
 1748                        if let Some(command) = action.lsp_action.command() {
 1749                            zlog::warn!(
 1750                                logger =>
 1751                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1752                                &command.command,
 1753                            );
 1754
 1755                            // bail early if command is invalid
 1756                            let server_capabilities = server.capabilities();
 1757                            let available_commands = server_capabilities
 1758                                .execute_command_provider
 1759                                .as_ref()
 1760                                .map(|options| options.commands.as_slice())
 1761                                .unwrap_or_default();
 1762                            if !available_commands.contains(&command.command) {
 1763                                zlog::warn!(
 1764                                    logger =>
 1765                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1766                                    command.command,
 1767                                    server.name(),
 1768                                );
 1769                                continue;
 1770                            }
 1771
 1772                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1773                            extend_formatting_transaction(
 1774                                buffer,
 1775                                formatting_transaction_id,
 1776                                cx,
 1777                                |_, _| {},
 1778                            )?;
 1779                            zlog::info!(logger => "Executing command {}", &command.command);
 1780
 1781                            lsp_store.update(cx, |this, _| {
 1782                                this.as_local_mut()
 1783                                    .unwrap()
 1784                                    .last_workspace_edits_by_language_server
 1785                                    .remove(&server.server_id());
 1786                            })?;
 1787
 1788                            let execute_command_result = server
 1789                                .request::<lsp::request::ExecuteCommand>(
 1790                                    lsp::ExecuteCommandParams {
 1791                                        command: command.command.clone(),
 1792                                        arguments: command.arguments.clone().unwrap_or_default(),
 1793                                        ..Default::default()
 1794                                    },
 1795                                )
 1796                                .await
 1797                                .into_response();
 1798
 1799                            if execute_command_result.is_err() {
 1800                                zlog::error!(
 1801                                    logger =>
 1802                                    "Failed to execute command '{}' as part of {}",
 1803                                    &command.command,
 1804                                    describe_code_action(&action),
 1805                                );
 1806                                continue 'actions;
 1807                            }
 1808
 1809                            let mut project_transaction_command =
 1810                                lsp_store.update(cx, |this, _| {
 1811                                    this.as_local_mut()
 1812                                        .unwrap()
 1813                                        .last_workspace_edits_by_language_server
 1814                                        .remove(&server.server_id())
 1815                                        .unwrap_or_default()
 1816                                })?;
 1817
 1818                            if let Some(transaction) =
 1819                                project_transaction_command.0.remove(&buffer.handle)
 1820                            {
 1821                                zlog::trace!(
 1822                                    logger =>
 1823                                    "Successfully captured {} edits that resulted from command {}",
 1824                                    transaction.edit_ids.len(),
 1825                                    &command.command,
 1826                                );
 1827                                let transaction_id_project_transaction = transaction.id;
 1828                                buffer.handle.update(cx, |buffer, _| {
 1829                                    // it may have been removed from history if push_to_history was
 1830                                    // false in deserialize_workspace_edit. If so push it so we
 1831                                    // can merge it with the format transaction
 1832                                    // and pop the combined transaction off the history stack
 1833                                    // later if push_to_history is false
 1834                                    if buffer.get_transaction(transaction.id).is_none() {
 1835                                        buffer.push_transaction(transaction, Instant::now());
 1836                                    }
 1837                                    buffer.merge_transactions(
 1838                                        transaction_id_project_transaction,
 1839                                        formatting_transaction_id,
 1840                                    );
 1841                                })?;
 1842                            }
 1843
 1844                            if !project_transaction_command.0.is_empty() {
 1845                                let extra_buffers = project_transaction_command
 1846                                    .0
 1847                                    .keys()
 1848                                    .filter_map(|buffer_handle| {
 1849                                        buffer_handle
 1850                                            .read_with(cx, |b, cx| b.project_path(cx))
 1851                                            .ok()
 1852                                            .flatten()
 1853                                    })
 1854                                    .map(|p| p.path.to_sanitized_string())
 1855                                    .join(", ");
 1856                                zlog::warn!(
 1857                                    logger =>
 1858                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1859                                    &command.command,
 1860                                    extra_buffers,
 1861                                );
 1862                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1863                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1864                                // add it so it's included, and merge it into the format transaction when its created later
 1865                            }
 1866                        }
 1867                    }
 1868                }
 1869            }
 1870        }
 1871
 1872        Ok(())
 1873    }
 1874
 1875    pub async fn format_ranges_via_lsp(
 1876        this: &WeakEntity<LspStore>,
 1877        buffer_handle: &Entity<Buffer>,
 1878        ranges: &[Range<Anchor>],
 1879        abs_path: &Path,
 1880        language_server: &Arc<LanguageServer>,
 1881        settings: &LanguageSettings,
 1882        cx: &mut AsyncApp,
 1883    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1884        let capabilities = &language_server.capabilities();
 1885        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1886        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1887            anyhow::bail!(
 1888                "{} language server does not support range formatting",
 1889                language_server.name()
 1890            );
 1891        }
 1892
 1893        let uri = file_path_to_lsp_url(abs_path)?;
 1894        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1895
 1896        let lsp_edits = {
 1897            let mut lsp_ranges = Vec::new();
 1898            this.update(cx, |_this, cx| {
 1899                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1900                // not have been sent to the language server. This seems like a fairly systemic
 1901                // issue, though, the resolution probably is not specific to formatting.
 1902                //
 1903                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1904                // LSP.
 1905                let snapshot = buffer_handle.read(cx).snapshot();
 1906                for range in ranges {
 1907                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1908                }
 1909                anyhow::Ok(())
 1910            })??;
 1911
 1912            let mut edits = None;
 1913            for range in lsp_ranges {
 1914                if let Some(mut edit) = language_server
 1915                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1916                        text_document: text_document.clone(),
 1917                        range,
 1918                        options: lsp_command::lsp_formatting_options(settings),
 1919                        work_done_progress_params: Default::default(),
 1920                    })
 1921                    .await
 1922                    .into_response()?
 1923                {
 1924                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 1925                }
 1926            }
 1927            edits
 1928        };
 1929
 1930        if let Some(lsp_edits) = lsp_edits {
 1931            this.update(cx, |this, cx| {
 1932                this.as_local_mut().unwrap().edits_from_lsp(
 1933                    buffer_handle,
 1934                    lsp_edits,
 1935                    language_server.server_id(),
 1936                    None,
 1937                    cx,
 1938                )
 1939            })?
 1940            .await
 1941        } else {
 1942            Ok(Vec::with_capacity(0))
 1943        }
 1944    }
 1945
 1946    async fn format_via_lsp(
 1947        this: &WeakEntity<LspStore>,
 1948        buffer: &Entity<Buffer>,
 1949        abs_path: &Path,
 1950        language_server: &Arc<LanguageServer>,
 1951        settings: &LanguageSettings,
 1952        cx: &mut AsyncApp,
 1953    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1954        let logger = zlog::scoped!("lsp_format");
 1955        zlog::info!(logger => "Formatting via LSP");
 1956
 1957        let uri = file_path_to_lsp_url(abs_path)?;
 1958        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1959        let capabilities = &language_server.capabilities();
 1960
 1961        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 1962        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1963
 1964        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1965            let _timer = zlog::time!(logger => "format-full");
 1966            language_server
 1967                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 1968                    text_document,
 1969                    options: lsp_command::lsp_formatting_options(settings),
 1970                    work_done_progress_params: Default::default(),
 1971                })
 1972                .await
 1973                .into_response()?
 1974        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1975            let _timer = zlog::time!(logger => "format-range");
 1976            let buffer_start = lsp::Position::new(0, 0);
 1977            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 1978            language_server
 1979                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1980                    text_document: text_document.clone(),
 1981                    range: lsp::Range::new(buffer_start, buffer_end),
 1982                    options: lsp_command::lsp_formatting_options(settings),
 1983                    work_done_progress_params: Default::default(),
 1984                })
 1985                .await
 1986                .into_response()?
 1987        } else {
 1988            None
 1989        };
 1990
 1991        if let Some(lsp_edits) = lsp_edits {
 1992            this.update(cx, |this, cx| {
 1993                this.as_local_mut().unwrap().edits_from_lsp(
 1994                    buffer,
 1995                    lsp_edits,
 1996                    language_server.server_id(),
 1997                    None,
 1998                    cx,
 1999                )
 2000            })?
 2001            .await
 2002        } else {
 2003            Ok(Vec::with_capacity(0))
 2004        }
 2005    }
 2006
 2007    async fn format_via_external_command(
 2008        buffer: &FormattableBuffer,
 2009        command: &str,
 2010        arguments: Option<&[String]>,
 2011        cx: &mut AsyncApp,
 2012    ) -> Result<Option<Diff>> {
 2013        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2014            let file = File::from_dyn(buffer.file())?;
 2015            let worktree = file.worktree.read(cx);
 2016            let mut worktree_path = worktree.abs_path().to_path_buf();
 2017            if worktree.root_entry()?.is_file() {
 2018                worktree_path.pop();
 2019            }
 2020            Some(worktree_path)
 2021        })?;
 2022
 2023        let mut child = util::command::new_smol_command(command);
 2024
 2025        if let Some(buffer_env) = buffer.env.as_ref() {
 2026            child.envs(buffer_env);
 2027        }
 2028
 2029        if let Some(working_dir_path) = working_dir_path {
 2030            child.current_dir(working_dir_path);
 2031        }
 2032
 2033        if let Some(arguments) = arguments {
 2034            child.args(arguments.iter().map(|arg| {
 2035                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2036                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2037                } else {
 2038                    arg.replace("{buffer_path}", "Untitled")
 2039                }
 2040            }));
 2041        }
 2042
 2043        let mut child = child
 2044            .stdin(smol::process::Stdio::piped())
 2045            .stdout(smol::process::Stdio::piped())
 2046            .stderr(smol::process::Stdio::piped())
 2047            .spawn()?;
 2048
 2049        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2050        let text = buffer
 2051            .handle
 2052            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2053        for chunk in text.chunks() {
 2054            stdin.write_all(chunk.as_bytes()).await?;
 2055        }
 2056        stdin.flush().await?;
 2057
 2058        let output = child.output().await?;
 2059        anyhow::ensure!(
 2060            output.status.success(),
 2061            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2062            output.status.code(),
 2063            String::from_utf8_lossy(&output.stdout),
 2064            String::from_utf8_lossy(&output.stderr),
 2065        );
 2066
 2067        let stdout = String::from_utf8(output.stdout)?;
 2068        Ok(Some(
 2069            buffer
 2070                .handle
 2071                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2072                .await,
 2073        ))
 2074    }
 2075
 2076    async fn try_resolve_code_action(
 2077        lang_server: &LanguageServer,
 2078        action: &mut CodeAction,
 2079    ) -> anyhow::Result<()> {
 2080        match &mut action.lsp_action {
 2081            LspAction::Action(lsp_action) => {
 2082                if !action.resolved
 2083                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2084                    && lsp_action.data.is_some()
 2085                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2086                {
 2087                    *lsp_action = Box::new(
 2088                        lang_server
 2089                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2090                            .await
 2091                            .into_response()?,
 2092                    );
 2093                }
 2094            }
 2095            LspAction::CodeLens(lens) => {
 2096                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2097                    *lens = lang_server
 2098                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2099                        .await
 2100                        .into_response()?;
 2101                }
 2102            }
 2103            LspAction::Command(_) => {}
 2104        }
 2105
 2106        action.resolved = true;
 2107        anyhow::Ok(())
 2108    }
 2109
 2110    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2111        let buffer = buffer_handle.read(cx);
 2112
 2113        let file = buffer.file().cloned();
 2114
 2115        let Some(file) = File::from_dyn(file.as_ref()) else {
 2116            return;
 2117        };
 2118        if !file.is_local() {
 2119            return;
 2120        }
 2121        let path = ProjectPath::from_file(file, cx);
 2122        let worktree_id = file.worktree_id(cx);
 2123        let language = buffer.language().cloned();
 2124
 2125        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2126            for (server_id, diagnostics) in
 2127                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2128            {
 2129                self.update_buffer_diagnostics(
 2130                    buffer_handle,
 2131                    server_id,
 2132                    None,
 2133                    None,
 2134                    diagnostics,
 2135                    Vec::new(),
 2136                    cx,
 2137                )
 2138                .log_err();
 2139            }
 2140        }
 2141        let Some(language) = language else {
 2142            return;
 2143        };
 2144        let Some(snapshot) = self
 2145            .worktree_store
 2146            .read(cx)
 2147            .worktree_for_id(worktree_id, cx)
 2148            .map(|worktree| worktree.read(cx).snapshot())
 2149        else {
 2150            return;
 2151        };
 2152        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2153
 2154        for server_id in
 2155            self.lsp_tree
 2156                .get(path, language.name(), language.manifest(), &delegate, cx)
 2157        {
 2158            let server = self
 2159                .language_servers
 2160                .get(&server_id)
 2161                .and_then(|server_state| {
 2162                    if let LanguageServerState::Running { server, .. } = server_state {
 2163                        Some(server.clone())
 2164                    } else {
 2165                        None
 2166                    }
 2167                });
 2168            let server = match server {
 2169                Some(server) => server,
 2170                None => continue,
 2171            };
 2172
 2173            buffer_handle.update(cx, |buffer, cx| {
 2174                buffer.set_completion_triggers(
 2175                    server.server_id(),
 2176                    server
 2177                        .capabilities()
 2178                        .completion_provider
 2179                        .as_ref()
 2180                        .and_then(|provider| {
 2181                            provider
 2182                                .trigger_characters
 2183                                .as_ref()
 2184                                .map(|characters| characters.iter().cloned().collect())
 2185                        })
 2186                        .unwrap_or_default(),
 2187                    cx,
 2188                );
 2189            });
 2190        }
 2191    }
 2192
 2193    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2194        buffer.update(cx, |buffer, cx| {
 2195            let Some(language) = buffer.language() else {
 2196                return;
 2197            };
 2198            let path = ProjectPath {
 2199                worktree_id: old_file.worktree_id(cx),
 2200                path: old_file.path.clone(),
 2201            };
 2202            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2203                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2204                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2205            }
 2206        });
 2207    }
 2208
 2209    fn update_buffer_diagnostics(
 2210        &mut self,
 2211        buffer: &Entity<Buffer>,
 2212        server_id: LanguageServerId,
 2213        result_id: Option<String>,
 2214        version: Option<i32>,
 2215        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2216        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2217        cx: &mut Context<LspStore>,
 2218    ) -> Result<()> {
 2219        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2220            Ordering::Equal
 2221                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2222                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2223                .then_with(|| a.severity.cmp(&b.severity))
 2224                .then_with(|| a.message.cmp(&b.message))
 2225        }
 2226
 2227        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2228        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2229        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2230
 2231        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2232            Ordering::Equal
 2233                .then_with(|| a.range.start.cmp(&b.range.start))
 2234                .then_with(|| b.range.end.cmp(&a.range.end))
 2235                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2236        });
 2237
 2238        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2239
 2240        let edits_since_save = std::cell::LazyCell::new(|| {
 2241            let saved_version = buffer.read(cx).saved_version();
 2242            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2243        });
 2244
 2245        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2246
 2247        for (new_diagnostic, entry) in diagnostics {
 2248            let start;
 2249            let end;
 2250            if new_diagnostic && entry.diagnostic.is_disk_based {
 2251                // Some diagnostics are based on files on disk instead of buffers'
 2252                // current contents. Adjust these diagnostics' ranges to reflect
 2253                // any unsaved edits.
 2254                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2255                // and were properly adjusted on reuse.
 2256                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2257                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2258            } else {
 2259                start = entry.range.start;
 2260                end = entry.range.end;
 2261            }
 2262
 2263            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2264                ..snapshot.clip_point_utf16(end, Bias::Right);
 2265
 2266            // Expand empty ranges by one codepoint
 2267            if range.start == range.end {
 2268                // This will be go to the next boundary when being clipped
 2269                range.end.column += 1;
 2270                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2271                if range.start == range.end && range.end.column > 0 {
 2272                    range.start.column -= 1;
 2273                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2274                }
 2275            }
 2276
 2277            sanitized_diagnostics.push(DiagnosticEntry {
 2278                range,
 2279                diagnostic: entry.diagnostic,
 2280            });
 2281        }
 2282        drop(edits_since_save);
 2283
 2284        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2285        buffer.update(cx, |buffer, cx| {
 2286            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2287                self.buffer_pull_diagnostics_result_ids
 2288                    .entry(server_id)
 2289                    .or_default()
 2290                    .insert(abs_path, result_id);
 2291            }
 2292
 2293            buffer.update_diagnostics(server_id, set, cx)
 2294        });
 2295
 2296        Ok(())
 2297    }
 2298
 2299    fn register_language_server_for_invisible_worktree(
 2300        &mut self,
 2301        worktree: &Entity<Worktree>,
 2302        language_server_id: LanguageServerId,
 2303        cx: &mut App,
 2304    ) {
 2305        let worktree = worktree.read(cx);
 2306        let worktree_id = worktree.id();
 2307        debug_assert!(!worktree.is_visible());
 2308        let Some(mut origin_seed) = self
 2309            .language_server_ids
 2310            .iter()
 2311            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2312        else {
 2313            return;
 2314        };
 2315        origin_seed.worktree_id = worktree_id;
 2316        self.language_server_ids
 2317            .entry(origin_seed)
 2318            .or_insert_with(|| UnifiedLanguageServer {
 2319                id: language_server_id,
 2320                project_roots: Default::default(),
 2321            });
 2322    }
 2323
 2324    fn register_buffer_with_language_servers(
 2325        &mut self,
 2326        buffer_handle: &Entity<Buffer>,
 2327        only_register_servers: HashSet<LanguageServerSelector>,
 2328        cx: &mut Context<LspStore>,
 2329    ) {
 2330        let buffer = buffer_handle.read(cx);
 2331        let buffer_id = buffer.remote_id();
 2332
 2333        let Some(file) = File::from_dyn(buffer.file()) else {
 2334            return;
 2335        };
 2336        if !file.is_local() {
 2337            return;
 2338        }
 2339
 2340        let abs_path = file.abs_path(cx);
 2341        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2342            return;
 2343        };
 2344        let initial_snapshot = buffer.text_snapshot();
 2345        let worktree_id = file.worktree_id(cx);
 2346
 2347        let Some(language) = buffer.language().cloned() else {
 2348            return;
 2349        };
 2350        let path: Arc<Path> = file
 2351            .path()
 2352            .parent()
 2353            .map(Arc::from)
 2354            .unwrap_or_else(|| file.path().clone());
 2355        let Some(worktree) = self
 2356            .worktree_store
 2357            .read(cx)
 2358            .worktree_for_id(worktree_id, cx)
 2359        else {
 2360            return;
 2361        };
 2362        let language_name = language.name();
 2363        let (reused, delegate, servers) = self
 2364            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2365            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2366            .unwrap_or_else(|| {
 2367                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2368                let delegate: Arc<dyn ManifestDelegate> =
 2369                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2370
 2371                let servers = self
 2372                    .lsp_tree
 2373                    .walk(
 2374                        ProjectPath { worktree_id, path },
 2375                        language.name(),
 2376                        language.manifest(),
 2377                        &delegate,
 2378                        cx,
 2379                    )
 2380                    .collect::<Vec<_>>();
 2381                (false, lsp_delegate, servers)
 2382            });
 2383        let servers_and_adapters = servers
 2384            .into_iter()
 2385            .filter_map(|server_node| {
 2386                if reused && server_node.server_id().is_none() {
 2387                    return None;
 2388                }
 2389                if !only_register_servers.is_empty() {
 2390                    if let Some(server_id) = server_node.server_id()
 2391                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2392                    {
 2393                        return None;
 2394                    }
 2395                    if let Some(name) = server_node.name()
 2396                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2397                    {
 2398                        return None;
 2399                    }
 2400                }
 2401
 2402                let server_id = server_node.server_id_or_init(|disposition| {
 2403                    let path = &disposition.path;
 2404
 2405                    {
 2406                        let uri =
 2407                            Uri::from_file_path(worktree.read(cx).abs_path().join(&path.path));
 2408
 2409                        let server_id = self.get_or_insert_language_server(
 2410                            &worktree,
 2411                            delegate.clone(),
 2412                            disposition,
 2413                            &language_name,
 2414                            cx,
 2415                        );
 2416
 2417                        if let Some(state) = self.language_servers.get(&server_id)
 2418                            && let Ok(uri) = uri
 2419                        {
 2420                            state.add_workspace_folder(uri);
 2421                        };
 2422                        server_id
 2423                    }
 2424                })?;
 2425                let server_state = self.language_servers.get(&server_id)?;
 2426                if let LanguageServerState::Running {
 2427                    server, adapter, ..
 2428                } = server_state
 2429                {
 2430                    Some((server.clone(), adapter.clone()))
 2431                } else {
 2432                    None
 2433                }
 2434            })
 2435            .collect::<Vec<_>>();
 2436        for (server, adapter) in servers_and_adapters {
 2437            buffer_handle.update(cx, |buffer, cx| {
 2438                buffer.set_completion_triggers(
 2439                    server.server_id(),
 2440                    server
 2441                        .capabilities()
 2442                        .completion_provider
 2443                        .as_ref()
 2444                        .and_then(|provider| {
 2445                            provider
 2446                                .trigger_characters
 2447                                .as_ref()
 2448                                .map(|characters| characters.iter().cloned().collect())
 2449                        })
 2450                        .unwrap_or_default(),
 2451                    cx,
 2452                );
 2453            });
 2454
 2455            let snapshot = LspBufferSnapshot {
 2456                version: 0,
 2457                snapshot: initial_snapshot.clone(),
 2458            };
 2459
 2460            let mut registered = false;
 2461            self.buffer_snapshots
 2462                .entry(buffer_id)
 2463                .or_default()
 2464                .entry(server.server_id())
 2465                .or_insert_with(|| {
 2466                    registered = true;
 2467                    server.register_buffer(
 2468                        uri.clone(),
 2469                        adapter.language_id(&language.name()),
 2470                        0,
 2471                        initial_snapshot.text(),
 2472                    );
 2473
 2474                    vec![snapshot]
 2475                });
 2476
 2477            self.buffers_opened_in_servers
 2478                .entry(buffer_id)
 2479                .or_default()
 2480                .insert(server.server_id());
 2481            if registered {
 2482                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2483                    language_server_id: server.server_id(),
 2484                    name: None,
 2485                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2486                        proto::RegisteredForBuffer {
 2487                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 2488                            buffer_id: buffer_id.to_proto(),
 2489                        },
 2490                    ),
 2491                });
 2492            }
 2493        }
 2494    }
 2495
 2496    fn reuse_existing_language_server<'lang_name>(
 2497        &self,
 2498        server_tree: &LanguageServerTree,
 2499        worktree: &Entity<Worktree>,
 2500        language_name: &'lang_name LanguageName,
 2501        cx: &mut App,
 2502    ) -> Option<(
 2503        Arc<LocalLspAdapterDelegate>,
 2504        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2505    )> {
 2506        if worktree.read(cx).is_visible() {
 2507            return None;
 2508        }
 2509
 2510        let worktree_store = self.worktree_store.read(cx);
 2511        let servers = server_tree
 2512            .instances
 2513            .iter()
 2514            .filter(|(worktree_id, _)| {
 2515                worktree_store
 2516                    .worktree_for_id(**worktree_id, cx)
 2517                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2518            })
 2519            .flat_map(|(worktree_id, servers)| {
 2520                servers
 2521                    .roots
 2522                    .iter()
 2523                    .flat_map(|(_, language_servers)| language_servers)
 2524                    .map(move |(_, (server_node, server_languages))| {
 2525                        (worktree_id, server_node, server_languages)
 2526                    })
 2527                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2528                    .map(|(worktree_id, server_node, _)| {
 2529                        (
 2530                            *worktree_id,
 2531                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2532                        )
 2533                    })
 2534            })
 2535            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2536                acc.entry(worktree_id)
 2537                    .or_insert_with(Vec::new)
 2538                    .push(server_node);
 2539                acc
 2540            })
 2541            .into_values()
 2542            .max_by_key(|servers| servers.len())?;
 2543
 2544        let worktree_id = worktree.read(cx).id();
 2545        let apply = move |tree: &mut LanguageServerTree| {
 2546            for server_node in &servers {
 2547                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2548            }
 2549            servers
 2550        };
 2551
 2552        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2553        Some((delegate, apply))
 2554    }
 2555
 2556    pub(crate) fn unregister_old_buffer_from_language_servers(
 2557        &mut self,
 2558        buffer: &Entity<Buffer>,
 2559        old_file: &File,
 2560        cx: &mut App,
 2561    ) {
 2562        let old_path = match old_file.as_local() {
 2563            Some(local) => local.abs_path(cx),
 2564            None => return,
 2565        };
 2566
 2567        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2568            debug_panic!("{old_path:?} is not parseable as an URI");
 2569            return;
 2570        };
 2571        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2572    }
 2573
 2574    pub(crate) fn unregister_buffer_from_language_servers(
 2575        &mut self,
 2576        buffer: &Entity<Buffer>,
 2577        file_url: &lsp::Uri,
 2578        cx: &mut App,
 2579    ) {
 2580        buffer.update(cx, |buffer, cx| {
 2581            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2582
 2583            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2584                language_server.unregister_buffer(file_url.clone());
 2585            }
 2586        });
 2587    }
 2588
 2589    fn buffer_snapshot_for_lsp_version(
 2590        &mut self,
 2591        buffer: &Entity<Buffer>,
 2592        server_id: LanguageServerId,
 2593        version: Option<i32>,
 2594        cx: &App,
 2595    ) -> Result<TextBufferSnapshot> {
 2596        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2597
 2598        if let Some(version) = version {
 2599            let buffer_id = buffer.read(cx).remote_id();
 2600            let snapshots = if let Some(snapshots) = self
 2601                .buffer_snapshots
 2602                .get_mut(&buffer_id)
 2603                .and_then(|m| m.get_mut(&server_id))
 2604            {
 2605                snapshots
 2606            } else if version == 0 {
 2607                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2608                // We detect this case and treat it as if the version was `None`.
 2609                return Ok(buffer.read(cx).text_snapshot());
 2610            } else {
 2611                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2612            };
 2613
 2614            let found_snapshot = snapshots
 2615                    .binary_search_by_key(&version, |e| e.version)
 2616                    .map(|ix| snapshots[ix].snapshot.clone())
 2617                    .map_err(|_| {
 2618                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2619                    })?;
 2620
 2621            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2622            Ok(found_snapshot)
 2623        } else {
 2624            Ok((buffer.read(cx)).text_snapshot())
 2625        }
 2626    }
 2627
 2628    async fn get_server_code_actions_from_action_kinds(
 2629        lsp_store: &WeakEntity<LspStore>,
 2630        language_server_id: LanguageServerId,
 2631        code_action_kinds: Vec<lsp::CodeActionKind>,
 2632        buffer: &Entity<Buffer>,
 2633        cx: &mut AsyncApp,
 2634    ) -> Result<Vec<CodeAction>> {
 2635        let actions = lsp_store
 2636            .update(cx, move |this, cx| {
 2637                let request = GetCodeActions {
 2638                    range: text::Anchor::MIN..text::Anchor::MAX,
 2639                    kinds: Some(code_action_kinds),
 2640                };
 2641                let server = LanguageServerToQuery::Other(language_server_id);
 2642                this.request_lsp(buffer.clone(), server, request, cx)
 2643            })?
 2644            .await?;
 2645        Ok(actions)
 2646    }
 2647
 2648    pub async fn execute_code_actions_on_server(
 2649        lsp_store: &WeakEntity<LspStore>,
 2650        language_server: &Arc<LanguageServer>,
 2651
 2652        actions: Vec<CodeAction>,
 2653        push_to_history: bool,
 2654        project_transaction: &mut ProjectTransaction,
 2655        cx: &mut AsyncApp,
 2656    ) -> anyhow::Result<()> {
 2657        for mut action in actions {
 2658            Self::try_resolve_code_action(language_server, &mut action)
 2659                .await
 2660                .context("resolving a formatting code action")?;
 2661
 2662            if let Some(edit) = action.lsp_action.edit() {
 2663                if edit.changes.is_none() && edit.document_changes.is_none() {
 2664                    continue;
 2665                }
 2666
 2667                let new = Self::deserialize_workspace_edit(
 2668                    lsp_store.upgrade().context("project dropped")?,
 2669                    edit.clone(),
 2670                    push_to_history,
 2671                    language_server.clone(),
 2672                    cx,
 2673                )
 2674                .await?;
 2675                project_transaction.0.extend(new.0);
 2676            }
 2677
 2678            if let Some(command) = action.lsp_action.command() {
 2679                let server_capabilities = language_server.capabilities();
 2680                let available_commands = server_capabilities
 2681                    .execute_command_provider
 2682                    .as_ref()
 2683                    .map(|options| options.commands.as_slice())
 2684                    .unwrap_or_default();
 2685                if available_commands.contains(&command.command) {
 2686                    lsp_store.update(cx, |lsp_store, _| {
 2687                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2688                            mode.last_workspace_edits_by_language_server
 2689                                .remove(&language_server.server_id());
 2690                        }
 2691                    })?;
 2692
 2693                    language_server
 2694                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2695                            command: command.command.clone(),
 2696                            arguments: command.arguments.clone().unwrap_or_default(),
 2697                            ..Default::default()
 2698                        })
 2699                        .await
 2700                        .into_response()
 2701                        .context("execute command")?;
 2702
 2703                    lsp_store.update(cx, |this, _| {
 2704                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2705                            project_transaction.0.extend(
 2706                                mode.last_workspace_edits_by_language_server
 2707                                    .remove(&language_server.server_id())
 2708                                    .unwrap_or_default()
 2709                                    .0,
 2710                            )
 2711                        }
 2712                    })?;
 2713                } else {
 2714                    log::warn!(
 2715                        "Cannot execute a command {} not listed in the language server capabilities",
 2716                        command.command
 2717                    )
 2718                }
 2719            }
 2720        }
 2721        Ok(())
 2722    }
 2723
 2724    pub async fn deserialize_text_edits(
 2725        this: Entity<LspStore>,
 2726        buffer_to_edit: Entity<Buffer>,
 2727        edits: Vec<lsp::TextEdit>,
 2728        push_to_history: bool,
 2729        _: Arc<CachedLspAdapter>,
 2730        language_server: Arc<LanguageServer>,
 2731        cx: &mut AsyncApp,
 2732    ) -> Result<Option<Transaction>> {
 2733        let edits = this
 2734            .update(cx, |this, cx| {
 2735                this.as_local_mut().unwrap().edits_from_lsp(
 2736                    &buffer_to_edit,
 2737                    edits,
 2738                    language_server.server_id(),
 2739                    None,
 2740                    cx,
 2741                )
 2742            })?
 2743            .await?;
 2744
 2745        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2746            buffer.finalize_last_transaction();
 2747            buffer.start_transaction();
 2748            for (range, text) in edits {
 2749                buffer.edit([(range, text)], None, cx);
 2750            }
 2751
 2752            if buffer.end_transaction(cx).is_some() {
 2753                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2754                if !push_to_history {
 2755                    buffer.forget_transaction(transaction.id);
 2756                }
 2757                Some(transaction)
 2758            } else {
 2759                None
 2760            }
 2761        })?;
 2762
 2763        Ok(transaction)
 2764    }
 2765
 2766    #[allow(clippy::type_complexity)]
 2767    pub(crate) fn edits_from_lsp(
 2768        &mut self,
 2769        buffer: &Entity<Buffer>,
 2770        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2771        server_id: LanguageServerId,
 2772        version: Option<i32>,
 2773        cx: &mut Context<LspStore>,
 2774    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2775        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2776        cx.background_spawn(async move {
 2777            let snapshot = snapshot?;
 2778            let mut lsp_edits = lsp_edits
 2779                .into_iter()
 2780                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2781                .collect::<Vec<_>>();
 2782
 2783            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2784
 2785            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2786            let mut edits = Vec::new();
 2787            while let Some((range, mut new_text)) = lsp_edits.next() {
 2788                // Clip invalid ranges provided by the language server.
 2789                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2790                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2791
 2792                // Combine any LSP edits that are adjacent.
 2793                //
 2794                // Also, combine LSP edits that are separated from each other by only
 2795                // a newline. This is important because for some code actions,
 2796                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2797                // are separated by unchanged newline characters.
 2798                //
 2799                // In order for the diffing logic below to work properly, any edits that
 2800                // cancel each other out must be combined into one.
 2801                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2802                    if next_range.start.0 > range.end {
 2803                        if next_range.start.0.row > range.end.row + 1
 2804                            || next_range.start.0.column > 0
 2805                            || snapshot.clip_point_utf16(
 2806                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2807                                Bias::Left,
 2808                            ) > range.end
 2809                        {
 2810                            break;
 2811                        }
 2812                        new_text.push('\n');
 2813                    }
 2814                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2815                    new_text.push_str(next_text);
 2816                    lsp_edits.next();
 2817                }
 2818
 2819                // For multiline edits, perform a diff of the old and new text so that
 2820                // we can identify the changes more precisely, preserving the locations
 2821                // of any anchors positioned in the unchanged regions.
 2822                if range.end.row > range.start.row {
 2823                    let offset = range.start.to_offset(&snapshot);
 2824                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2825                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2826                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2827                        (
 2828                            snapshot.anchor_after(offset + range.start)
 2829                                ..snapshot.anchor_before(offset + range.end),
 2830                            replacement,
 2831                        )
 2832                    }));
 2833                } else if range.end == range.start {
 2834                    let anchor = snapshot.anchor_after(range.start);
 2835                    edits.push((anchor..anchor, new_text.into()));
 2836                } else {
 2837                    let edit_start = snapshot.anchor_after(range.start);
 2838                    let edit_end = snapshot.anchor_before(range.end);
 2839                    edits.push((edit_start..edit_end, new_text.into()));
 2840                }
 2841            }
 2842
 2843            Ok(edits)
 2844        })
 2845    }
 2846
 2847    pub(crate) async fn deserialize_workspace_edit(
 2848        this: Entity<LspStore>,
 2849        edit: lsp::WorkspaceEdit,
 2850        push_to_history: bool,
 2851        language_server: Arc<LanguageServer>,
 2852        cx: &mut AsyncApp,
 2853    ) -> Result<ProjectTransaction> {
 2854        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2855
 2856        let mut operations = Vec::new();
 2857        if let Some(document_changes) = edit.document_changes {
 2858            match document_changes {
 2859                lsp::DocumentChanges::Edits(edits) => {
 2860                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2861                }
 2862                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2863            }
 2864        } else if let Some(changes) = edit.changes {
 2865            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2866                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2867                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2868                        uri,
 2869                        version: None,
 2870                    },
 2871                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2872                })
 2873            }));
 2874        }
 2875
 2876        let mut project_transaction = ProjectTransaction::default();
 2877        for operation in operations {
 2878            match operation {
 2879                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2880                    let abs_path = op
 2881                        .uri
 2882                        .to_file_path()
 2883                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2884
 2885                    if let Some(parent_path) = abs_path.parent() {
 2886                        fs.create_dir(parent_path).await?;
 2887                    }
 2888                    if abs_path.ends_with("/") {
 2889                        fs.create_dir(&abs_path).await?;
 2890                    } else {
 2891                        fs.create_file(
 2892                            &abs_path,
 2893                            op.options
 2894                                .map(|options| fs::CreateOptions {
 2895                                    overwrite: options.overwrite.unwrap_or(false),
 2896                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2897                                })
 2898                                .unwrap_or_default(),
 2899                        )
 2900                        .await?;
 2901                    }
 2902                }
 2903
 2904                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2905                    let source_abs_path = op
 2906                        .old_uri
 2907                        .to_file_path()
 2908                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2909                    let target_abs_path = op
 2910                        .new_uri
 2911                        .to_file_path()
 2912                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2913                    fs.rename(
 2914                        &source_abs_path,
 2915                        &target_abs_path,
 2916                        op.options
 2917                            .map(|options| fs::RenameOptions {
 2918                                overwrite: options.overwrite.unwrap_or(false),
 2919                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2920                            })
 2921                            .unwrap_or_default(),
 2922                    )
 2923                    .await?;
 2924                }
 2925
 2926                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 2927                    let abs_path = op
 2928                        .uri
 2929                        .to_file_path()
 2930                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2931                    let options = op
 2932                        .options
 2933                        .map(|options| fs::RemoveOptions {
 2934                            recursive: options.recursive.unwrap_or(false),
 2935                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 2936                        })
 2937                        .unwrap_or_default();
 2938                    if abs_path.ends_with("/") {
 2939                        fs.remove_dir(&abs_path, options).await?;
 2940                    } else {
 2941                        fs.remove_file(&abs_path, options).await?;
 2942                    }
 2943                }
 2944
 2945                lsp::DocumentChangeOperation::Edit(op) => {
 2946                    let buffer_to_edit = this
 2947                        .update(cx, |this, cx| {
 2948                            this.open_local_buffer_via_lsp(
 2949                                op.text_document.uri.clone(),
 2950                                language_server.server_id(),
 2951                                cx,
 2952                            )
 2953                        })?
 2954                        .await?;
 2955
 2956                    let edits = this
 2957                        .update(cx, |this, cx| {
 2958                            let path = buffer_to_edit.read(cx).project_path(cx);
 2959                            let active_entry = this.active_entry;
 2960                            let is_active_entry = path.is_some_and(|project_path| {
 2961                                this.worktree_store
 2962                                    .read(cx)
 2963                                    .entry_for_path(&project_path, cx)
 2964                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 2965                            });
 2966                            let local = this.as_local_mut().unwrap();
 2967
 2968                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 2969                            for edit in op.edits {
 2970                                match edit {
 2971                                    Edit::Plain(edit) => {
 2972                                        if !edits.contains(&edit) {
 2973                                            edits.push(edit)
 2974                                        }
 2975                                    }
 2976                                    Edit::Annotated(edit) => {
 2977                                        if !edits.contains(&edit.text_edit) {
 2978                                            edits.push(edit.text_edit)
 2979                                        }
 2980                                    }
 2981                                    Edit::Snippet(edit) => {
 2982                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 2983                                        else {
 2984                                            continue;
 2985                                        };
 2986
 2987                                        if is_active_entry {
 2988                                            snippet_edits.push((edit.range, snippet));
 2989                                        } else {
 2990                                            // Since this buffer is not focused, apply a normal edit.
 2991                                            let new_edit = TextEdit {
 2992                                                range: edit.range,
 2993                                                new_text: snippet.text,
 2994                                            };
 2995                                            if !edits.contains(&new_edit) {
 2996                                                edits.push(new_edit);
 2997                                            }
 2998                                        }
 2999                                    }
 3000                                }
 3001                            }
 3002                            if !snippet_edits.is_empty() {
 3003                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3004                                let version = if let Some(buffer_version) = op.text_document.version
 3005                                {
 3006                                    local
 3007                                        .buffer_snapshot_for_lsp_version(
 3008                                            &buffer_to_edit,
 3009                                            language_server.server_id(),
 3010                                            Some(buffer_version),
 3011                                            cx,
 3012                                        )
 3013                                        .ok()
 3014                                        .map(|snapshot| snapshot.version)
 3015                                } else {
 3016                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3017                                };
 3018
 3019                                let most_recent_edit = version.and_then(|version| {
 3020                                    version.iter().max_by_key(|timestamp| timestamp.value)
 3021                                });
 3022                                // Check if the edit that triggered that edit has been made by this participant.
 3023
 3024                                if let Some(most_recent_edit) = most_recent_edit {
 3025                                    cx.emit(LspStoreEvent::SnippetEdit {
 3026                                        buffer_id,
 3027                                        edits: snippet_edits,
 3028                                        most_recent_edit,
 3029                                    });
 3030                                }
 3031                            }
 3032
 3033                            local.edits_from_lsp(
 3034                                &buffer_to_edit,
 3035                                edits,
 3036                                language_server.server_id(),
 3037                                op.text_document.version,
 3038                                cx,
 3039                            )
 3040                        })?
 3041                        .await?;
 3042
 3043                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3044                        buffer.finalize_last_transaction();
 3045                        buffer.start_transaction();
 3046                        for (range, text) in edits {
 3047                            buffer.edit([(range, text)], None, cx);
 3048                        }
 3049
 3050                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3051                            if push_to_history {
 3052                                buffer.finalize_last_transaction();
 3053                                buffer.get_transaction(transaction_id).cloned()
 3054                            } else {
 3055                                buffer.forget_transaction(transaction_id)
 3056                            }
 3057                        })
 3058                    })?;
 3059                    if let Some(transaction) = transaction {
 3060                        project_transaction.0.insert(buffer_to_edit, transaction);
 3061                    }
 3062                }
 3063            }
 3064        }
 3065
 3066        Ok(project_transaction)
 3067    }
 3068
 3069    async fn on_lsp_workspace_edit(
 3070        this: WeakEntity<LspStore>,
 3071        params: lsp::ApplyWorkspaceEditParams,
 3072        server_id: LanguageServerId,
 3073        cx: &mut AsyncApp,
 3074    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3075        let this = this.upgrade().context("project project closed")?;
 3076        let language_server = this
 3077            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3078            .context("language server not found")?;
 3079        let transaction = Self::deserialize_workspace_edit(
 3080            this.clone(),
 3081            params.edit,
 3082            true,
 3083            language_server.clone(),
 3084            cx,
 3085        )
 3086        .await
 3087        .log_err();
 3088        this.update(cx, |this, _| {
 3089            if let Some(transaction) = transaction {
 3090                this.as_local_mut()
 3091                    .unwrap()
 3092                    .last_workspace_edits_by_language_server
 3093                    .insert(server_id, transaction);
 3094            }
 3095        })?;
 3096        Ok(lsp::ApplyWorkspaceEditResponse {
 3097            applied: true,
 3098            failed_change: None,
 3099            failure_reason: None,
 3100        })
 3101    }
 3102
 3103    fn remove_worktree(
 3104        &mut self,
 3105        id_to_remove: WorktreeId,
 3106        cx: &mut Context<LspStore>,
 3107    ) -> Vec<LanguageServerId> {
 3108        self.diagnostics.remove(&id_to_remove);
 3109        self.prettier_store.update(cx, |prettier_store, cx| {
 3110            prettier_store.remove_worktree(id_to_remove, cx);
 3111        });
 3112
 3113        let mut servers_to_remove = BTreeSet::default();
 3114        let mut servers_to_preserve = HashSet::default();
 3115        for (seed, state) in &self.language_server_ids {
 3116            if seed.worktree_id == id_to_remove {
 3117                servers_to_remove.insert(state.id);
 3118            } else {
 3119                servers_to_preserve.insert(state.id);
 3120            }
 3121        }
 3122        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3123        self.language_server_ids
 3124            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3125        for server_id_to_remove in &servers_to_remove {
 3126            self.language_server_watched_paths
 3127                .remove(server_id_to_remove);
 3128            self.language_server_paths_watched_for_rename
 3129                .remove(server_id_to_remove);
 3130            self.last_workspace_edits_by_language_server
 3131                .remove(server_id_to_remove);
 3132            self.language_servers.remove(server_id_to_remove);
 3133            self.buffer_pull_diagnostics_result_ids
 3134                .remove(server_id_to_remove);
 3135            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3136                buffer_servers.remove(server_id_to_remove);
 3137            }
 3138            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3139        }
 3140        servers_to_remove.into_iter().collect()
 3141    }
 3142
 3143    fn rebuild_watched_paths_inner<'a>(
 3144        &'a self,
 3145        language_server_id: LanguageServerId,
 3146        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3147        cx: &mut Context<LspStore>,
 3148    ) -> LanguageServerWatchedPathsBuilder {
 3149        let worktrees = self
 3150            .worktree_store
 3151            .read(cx)
 3152            .worktrees()
 3153            .filter_map(|worktree| {
 3154                self.language_servers_for_worktree(worktree.read(cx).id())
 3155                    .find(|server| server.server_id() == language_server_id)
 3156                    .map(|_| worktree)
 3157            })
 3158            .collect::<Vec<_>>();
 3159
 3160        let mut worktree_globs = HashMap::default();
 3161        let mut abs_globs = HashMap::default();
 3162        log::trace!(
 3163            "Processing new watcher paths for language server with id {}",
 3164            language_server_id
 3165        );
 3166
 3167        for watcher in watchers {
 3168            if let Some((worktree, literal_prefix, pattern)) =
 3169                self.worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3170            {
 3171                worktree.update(cx, |worktree, _| {
 3172                    if let Some((tree, glob)) =
 3173                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3174                    {
 3175                        tree.add_path_prefix_to_scan(literal_prefix.into());
 3176                        worktree_globs
 3177                            .entry(tree.id())
 3178                            .or_insert_with(GlobSetBuilder::new)
 3179                            .add(glob);
 3180                    }
 3181                });
 3182            } else {
 3183                let (path, pattern) = match &watcher.glob_pattern {
 3184                    lsp::GlobPattern::String(s) => {
 3185                        let watcher_path = SanitizedPath::new(s);
 3186                        let path = glob_literal_prefix(watcher_path.as_path());
 3187                        let pattern = watcher_path
 3188                            .as_path()
 3189                            .strip_prefix(&path)
 3190                            .map(|p| p.to_string_lossy().to_string())
 3191                            .unwrap_or_else(|e| {
 3192                                debug_panic!(
 3193                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3194                                    s,
 3195                                    path.display(),
 3196                                    e
 3197                                );
 3198                                watcher_path.as_path().to_string_lossy().to_string()
 3199                            });
 3200                        (path, pattern)
 3201                    }
 3202                    lsp::GlobPattern::Relative(rp) => {
 3203                        let Ok(mut base_uri) = match &rp.base_uri {
 3204                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3205                            lsp::OneOf::Right(base_uri) => base_uri,
 3206                        }
 3207                        .to_file_path() else {
 3208                            continue;
 3209                        };
 3210
 3211                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3212                        let pattern = Path::new(&rp.pattern)
 3213                            .strip_prefix(&path)
 3214                            .map(|p| p.to_string_lossy().to_string())
 3215                            .unwrap_or_else(|e| {
 3216                                debug_panic!(
 3217                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3218                                    rp.pattern,
 3219                                    path.display(),
 3220                                    e
 3221                                );
 3222                                rp.pattern.clone()
 3223                            });
 3224                        base_uri.push(path);
 3225                        (base_uri, pattern)
 3226                    }
 3227                };
 3228
 3229                if let Some(glob) = Glob::new(&pattern).log_err() {
 3230                    if !path
 3231                        .components()
 3232                        .any(|c| matches!(c, path::Component::Normal(_)))
 3233                    {
 3234                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3235                        // rather than adding a new watcher for `/`.
 3236                        for worktree in &worktrees {
 3237                            worktree_globs
 3238                                .entry(worktree.read(cx).id())
 3239                                .or_insert_with(GlobSetBuilder::new)
 3240                                .add(glob.clone());
 3241                        }
 3242                    } else {
 3243                        abs_globs
 3244                            .entry(path.into())
 3245                            .or_insert_with(GlobSetBuilder::new)
 3246                            .add(glob);
 3247                    }
 3248                }
 3249            }
 3250        }
 3251
 3252        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3253        for (worktree_id, builder) in worktree_globs {
 3254            if let Ok(globset) = builder.build() {
 3255                watch_builder.watch_worktree(worktree_id, globset);
 3256            }
 3257        }
 3258        for (abs_path, builder) in abs_globs {
 3259            if let Ok(globset) = builder.build() {
 3260                watch_builder.watch_abs_path(abs_path, globset);
 3261            }
 3262        }
 3263        watch_builder
 3264    }
 3265
 3266    fn worktree_and_path_for_file_watcher(
 3267        &self,
 3268        worktrees: &[Entity<Worktree>],
 3269        watcher: &FileSystemWatcher,
 3270        cx: &App,
 3271    ) -> Option<(Entity<Worktree>, PathBuf, String)> {
 3272        worktrees.iter().find_map(|worktree| {
 3273            let tree = worktree.read(cx);
 3274            let worktree_root_path = tree.abs_path();
 3275            match &watcher.glob_pattern {
 3276                lsp::GlobPattern::String(s) => {
 3277                    let watcher_path = SanitizedPath::new(s);
 3278                    let relative = watcher_path
 3279                        .as_path()
 3280                        .strip_prefix(&worktree_root_path)
 3281                        .ok()?;
 3282                    let literal_prefix = glob_literal_prefix(relative);
 3283                    Some((
 3284                        worktree.clone(),
 3285                        literal_prefix,
 3286                        relative.to_string_lossy().to_string(),
 3287                    ))
 3288                }
 3289                lsp::GlobPattern::Relative(rp) => {
 3290                    let base_uri = match &rp.base_uri {
 3291                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3292                        lsp::OneOf::Right(base_uri) => base_uri,
 3293                    }
 3294                    .to_file_path()
 3295                    .ok()?;
 3296                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3297                    let mut literal_prefix = relative.to_owned();
 3298                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3299                    Some((worktree.clone(), literal_prefix, rp.pattern.clone()))
 3300                }
 3301            }
 3302        })
 3303    }
 3304
 3305    fn rebuild_watched_paths(
 3306        &mut self,
 3307        language_server_id: LanguageServerId,
 3308        cx: &mut Context<LspStore>,
 3309    ) {
 3310        let Some(watchers) = self
 3311            .language_server_watcher_registrations
 3312            .get(&language_server_id)
 3313        else {
 3314            return;
 3315        };
 3316
 3317        let watch_builder =
 3318            self.rebuild_watched_paths_inner(language_server_id, watchers.values().flatten(), cx);
 3319        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3320        self.language_server_watched_paths
 3321            .insert(language_server_id, watcher);
 3322
 3323        cx.notify();
 3324    }
 3325
 3326    fn on_lsp_did_change_watched_files(
 3327        &mut self,
 3328        language_server_id: LanguageServerId,
 3329        registration_id: &str,
 3330        params: DidChangeWatchedFilesRegistrationOptions,
 3331        cx: &mut Context<LspStore>,
 3332    ) {
 3333        let registrations = self
 3334            .language_server_watcher_registrations
 3335            .entry(language_server_id)
 3336            .or_default();
 3337
 3338        registrations.insert(registration_id.to_string(), params.watchers);
 3339
 3340        self.rebuild_watched_paths(language_server_id, cx);
 3341    }
 3342
 3343    fn on_lsp_unregister_did_change_watched_files(
 3344        &mut self,
 3345        language_server_id: LanguageServerId,
 3346        registration_id: &str,
 3347        cx: &mut Context<LspStore>,
 3348    ) {
 3349        let registrations = self
 3350            .language_server_watcher_registrations
 3351            .entry(language_server_id)
 3352            .or_default();
 3353
 3354        if registrations.remove(registration_id).is_some() {
 3355            log::info!(
 3356                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3357                language_server_id,
 3358                registration_id
 3359            );
 3360        } else {
 3361            log::warn!(
 3362                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3363                language_server_id,
 3364                registration_id
 3365            );
 3366        }
 3367
 3368        self.rebuild_watched_paths(language_server_id, cx);
 3369    }
 3370
 3371    async fn initialization_options_for_adapter(
 3372        adapter: Arc<dyn LspAdapter>,
 3373        fs: &dyn Fs,
 3374        delegate: &Arc<dyn LspAdapterDelegate>,
 3375    ) -> Result<Option<serde_json::Value>> {
 3376        let Some(mut initialization_config) =
 3377            adapter.clone().initialization_options(fs, delegate).await?
 3378        else {
 3379            return Ok(None);
 3380        };
 3381
 3382        for other_adapter in delegate.registered_lsp_adapters() {
 3383            if other_adapter.name() == adapter.name() {
 3384                continue;
 3385            }
 3386            if let Ok(Some(target_config)) = other_adapter
 3387                .clone()
 3388                .additional_initialization_options(adapter.name(), fs, delegate)
 3389                .await
 3390            {
 3391                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3392            }
 3393        }
 3394
 3395        Ok(Some(initialization_config))
 3396    }
 3397
 3398    fn toolchain_store(&self) -> &Entity<LocalToolchainStore> {
 3399        &self.toolchain_store
 3400    }
 3401
 3402    async fn workspace_configuration_for_adapter(
 3403        adapter: Arc<dyn LspAdapter>,
 3404        fs: &dyn Fs,
 3405        delegate: &Arc<dyn LspAdapterDelegate>,
 3406        toolchain: Option<Toolchain>,
 3407        cx: &mut AsyncApp,
 3408    ) -> Result<serde_json::Value> {
 3409        let mut workspace_config = adapter
 3410            .clone()
 3411            .workspace_configuration(fs, delegate, toolchain, cx)
 3412            .await?;
 3413
 3414        for other_adapter in delegate.registered_lsp_adapters() {
 3415            if other_adapter.name() == adapter.name() {
 3416                continue;
 3417            }
 3418            if let Ok(Some(target_config)) = other_adapter
 3419                .clone()
 3420                .additional_workspace_configuration(adapter.name(), fs, delegate, cx)
 3421                .await
 3422            {
 3423                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3424            }
 3425        }
 3426
 3427        Ok(workspace_config)
 3428    }
 3429
 3430    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3431        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3432            Some(server.clone())
 3433        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3434            Some(Arc::clone(server))
 3435        } else {
 3436            None
 3437        }
 3438    }
 3439}
 3440
 3441fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3442    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3443        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3444            language_server_id: server.server_id(),
 3445            name: Some(server.name()),
 3446            message: proto::update_language_server::Variant::MetadataUpdated(
 3447                proto::ServerMetadataUpdated {
 3448                    capabilities: Some(capabilities),
 3449                },
 3450            ),
 3451        });
 3452    }
 3453}
 3454
 3455#[derive(Debug)]
 3456pub struct FormattableBuffer {
 3457    handle: Entity<Buffer>,
 3458    abs_path: Option<PathBuf>,
 3459    env: Option<HashMap<String, String>>,
 3460    ranges: Option<Vec<Range<Anchor>>>,
 3461}
 3462
 3463pub struct RemoteLspStore {
 3464    upstream_client: Option<AnyProtoClient>,
 3465    upstream_project_id: u64,
 3466}
 3467
 3468pub(crate) enum LspStoreMode {
 3469    Local(LocalLspStore),   // ssh host and collab host
 3470    Remote(RemoteLspStore), // collab guest
 3471}
 3472
 3473impl LspStoreMode {
 3474    fn is_local(&self) -> bool {
 3475        matches!(self, LspStoreMode::Local(_))
 3476    }
 3477}
 3478
 3479pub struct LspStore {
 3480    mode: LspStoreMode,
 3481    last_formatting_failure: Option<String>,
 3482    downstream_client: Option<(AnyProtoClient, u64)>,
 3483    nonce: u128,
 3484    buffer_store: Entity<BufferStore>,
 3485    worktree_store: Entity<WorktreeStore>,
 3486    pub languages: Arc<LanguageRegistry>,
 3487    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3488    active_entry: Option<ProjectEntryId>,
 3489    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3490    _maintain_buffer_languages: Task<()>,
 3491    diagnostic_summaries:
 3492        HashMap<WorktreeId, HashMap<Arc<Path>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3493    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3494    lsp_document_colors: HashMap<BufferId, DocumentColorData>,
 3495    lsp_code_lens: HashMap<BufferId, CodeLensData>,
 3496    running_lsp_requests: HashMap<TypeId, (Global, HashMap<LspRequestId, Task<()>>)>,
 3497}
 3498
 3499#[derive(Debug, Default, Clone)]
 3500pub struct DocumentColors {
 3501    pub colors: HashSet<DocumentColor>,
 3502    pub cache_version: Option<usize>,
 3503}
 3504
 3505type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3506type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3507
 3508#[derive(Debug, Default)]
 3509struct DocumentColorData {
 3510    colors_for_version: Global,
 3511    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3512    cache_version: usize,
 3513    colors_update: Option<(Global, DocumentColorTask)>,
 3514}
 3515
 3516#[derive(Debug, Default)]
 3517struct CodeLensData {
 3518    lens_for_version: Global,
 3519    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3520    update: Option<(Global, CodeLensTask)>,
 3521}
 3522
 3523#[derive(Debug, PartialEq, Eq, Clone, Copy)]
 3524pub enum LspFetchStrategy {
 3525    IgnoreCache,
 3526    UseCache { known_cache_version: Option<usize> },
 3527}
 3528
 3529#[derive(Debug)]
 3530pub enum LspStoreEvent {
 3531    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3532    LanguageServerRemoved(LanguageServerId),
 3533    LanguageServerUpdate {
 3534        language_server_id: LanguageServerId,
 3535        name: Option<LanguageServerName>,
 3536        message: proto::update_language_server::Variant,
 3537    },
 3538    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3539    LanguageServerPrompt(LanguageServerPromptRequest),
 3540    LanguageDetected {
 3541        buffer: Entity<Buffer>,
 3542        new_language: Option<Arc<Language>>,
 3543    },
 3544    Notification(String),
 3545    RefreshInlayHints,
 3546    RefreshCodeLens,
 3547    DiagnosticsUpdated {
 3548        server_id: LanguageServerId,
 3549        paths: Vec<ProjectPath>,
 3550    },
 3551    DiskBasedDiagnosticsStarted {
 3552        language_server_id: LanguageServerId,
 3553    },
 3554    DiskBasedDiagnosticsFinished {
 3555        language_server_id: LanguageServerId,
 3556    },
 3557    SnippetEdit {
 3558        buffer_id: BufferId,
 3559        edits: Vec<(lsp::Range, Snippet)>,
 3560        most_recent_edit: clock::Lamport,
 3561    },
 3562}
 3563
 3564#[derive(Clone, Debug, Serialize)]
 3565pub struct LanguageServerStatus {
 3566    pub name: LanguageServerName,
 3567    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 3568    pub has_pending_diagnostic_updates: bool,
 3569    progress_tokens: HashSet<String>,
 3570    pub worktree: Option<WorktreeId>,
 3571}
 3572
 3573#[derive(Clone, Debug)]
 3574struct CoreSymbol {
 3575    pub language_server_name: LanguageServerName,
 3576    pub source_worktree_id: WorktreeId,
 3577    pub source_language_server_id: LanguageServerId,
 3578    pub path: ProjectPath,
 3579    pub name: String,
 3580    pub kind: lsp::SymbolKind,
 3581    pub range: Range<Unclipped<PointUtf16>>,
 3582    pub signature: [u8; 32],
 3583}
 3584
 3585impl LspStore {
 3586    pub fn init(client: &AnyProtoClient) {
 3587        client.add_entity_request_handler(Self::handle_lsp_query);
 3588        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3589        client.add_entity_request_handler(Self::handle_multi_lsp_query);
 3590        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3591        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3592        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3593        client.add_entity_message_handler(Self::handle_start_language_server);
 3594        client.add_entity_message_handler(Self::handle_update_language_server);
 3595        client.add_entity_message_handler(Self::handle_language_server_log);
 3596        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3597        client.add_entity_request_handler(Self::handle_format_buffers);
 3598        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3599        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3600        client.add_entity_request_handler(Self::handle_apply_code_action);
 3601        client.add_entity_request_handler(Self::handle_inlay_hints);
 3602        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3603        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3604        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3605        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3606        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3607        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3608        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3609        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3610        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3611        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3612        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3613        client.add_entity_request_handler(Self::handle_lsp_command::<GetCodeActions>);
 3614        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3615        client.add_entity_request_handler(Self::handle_lsp_command::<GetHover>);
 3616        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3617        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3618        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3619        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3620        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3621
 3622        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3623        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3624        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3625        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3626        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3627        client.add_entity_request_handler(
 3628            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3629        );
 3630        client.add_entity_request_handler(
 3631            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3632        );
 3633        client.add_entity_request_handler(
 3634            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3635        );
 3636        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentDiagnostics>);
 3637    }
 3638
 3639    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3640        match &self.mode {
 3641            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3642            _ => None,
 3643        }
 3644    }
 3645
 3646    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3647        match &self.mode {
 3648            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3649            _ => None,
 3650        }
 3651    }
 3652
 3653    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3654        match &mut self.mode {
 3655            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3656            _ => None,
 3657        }
 3658    }
 3659
 3660    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3661        match &self.mode {
 3662            LspStoreMode::Remote(RemoteLspStore {
 3663                upstream_client: Some(upstream_client),
 3664                upstream_project_id,
 3665                ..
 3666            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3667
 3668            LspStoreMode::Remote(RemoteLspStore {
 3669                upstream_client: None,
 3670                ..
 3671            }) => None,
 3672            LspStoreMode::Local(_) => None,
 3673        }
 3674    }
 3675
 3676    pub fn new_local(
 3677        buffer_store: Entity<BufferStore>,
 3678        worktree_store: Entity<WorktreeStore>,
 3679        prettier_store: Entity<PrettierStore>,
 3680        toolchain_store: Entity<LocalToolchainStore>,
 3681        environment: Entity<ProjectEnvironment>,
 3682        manifest_tree: Entity<ManifestTree>,
 3683        languages: Arc<LanguageRegistry>,
 3684        http_client: Arc<dyn HttpClient>,
 3685        fs: Arc<dyn Fs>,
 3686        cx: &mut Context<Self>,
 3687    ) -> Self {
 3688        let yarn = YarnPathStore::new(fs.clone(), cx);
 3689        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3690            .detach();
 3691        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3692            .detach();
 3693        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3694            .detach();
 3695        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3696            .detach();
 3697        if let Some(extension_events) = extension::ExtensionEvents::try_global(cx).as_ref() {
 3698            cx.subscribe(
 3699                extension_events,
 3700                Self::reload_zed_json_schemas_on_extensions_changed,
 3701            )
 3702            .detach();
 3703        } else {
 3704            log::debug!("No extension events global found. Skipping JSON schema auto-reload setup");
 3705        }
 3706        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3707            .detach();
 3708        subscribe_to_binary_statuses(&languages, cx).detach();
 3709
 3710        let _maintain_workspace_config = {
 3711            let (sender, receiver) = watch::channel();
 3712            (
 3713                Self::maintain_workspace_config(fs.clone(), receiver, cx),
 3714                sender,
 3715            )
 3716        };
 3717
 3718        Self {
 3719            mode: LspStoreMode::Local(LocalLspStore {
 3720                weak: cx.weak_entity(),
 3721                worktree_store: worktree_store.clone(),
 3722
 3723                supplementary_language_servers: Default::default(),
 3724                languages: languages.clone(),
 3725                language_server_ids: Default::default(),
 3726                language_servers: Default::default(),
 3727                last_workspace_edits_by_language_server: Default::default(),
 3728                language_server_watched_paths: Default::default(),
 3729                language_server_paths_watched_for_rename: Default::default(),
 3730                language_server_watcher_registrations: Default::default(),
 3731                buffers_being_formatted: Default::default(),
 3732                buffer_snapshots: Default::default(),
 3733                prettier_store,
 3734                environment,
 3735                http_client,
 3736                fs,
 3737                yarn,
 3738                next_diagnostic_group_id: Default::default(),
 3739                diagnostics: Default::default(),
 3740                _subscription: cx.on_app_quit(|this, cx| {
 3741                    this.as_local_mut()
 3742                        .unwrap()
 3743                        .shutdown_language_servers_on_quit(cx)
 3744                }),
 3745                lsp_tree: LanguageServerTree::new(
 3746                    manifest_tree,
 3747                    languages.clone(),
 3748                    toolchain_store.clone(),
 3749                ),
 3750                toolchain_store,
 3751                registered_buffers: HashMap::default(),
 3752                buffers_opened_in_servers: HashMap::default(),
 3753                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3754                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3755                    .manifest_file_names(),
 3756            }),
 3757            last_formatting_failure: None,
 3758            downstream_client: None,
 3759            buffer_store,
 3760            worktree_store,
 3761            languages: languages.clone(),
 3762            language_server_statuses: Default::default(),
 3763            nonce: StdRng::from_os_rng().random(),
 3764            diagnostic_summaries: HashMap::default(),
 3765            lsp_server_capabilities: HashMap::default(),
 3766            lsp_document_colors: HashMap::default(),
 3767            lsp_code_lens: HashMap::default(),
 3768            running_lsp_requests: HashMap::default(),
 3769            active_entry: None,
 3770            _maintain_workspace_config,
 3771            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3772        }
 3773    }
 3774
 3775    fn send_lsp_proto_request<R: LspCommand>(
 3776        &self,
 3777        buffer: Entity<Buffer>,
 3778        client: AnyProtoClient,
 3779        upstream_project_id: u64,
 3780        request: R,
 3781        cx: &mut Context<LspStore>,
 3782    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3783        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3784            return Task::ready(Ok(R::Response::default()));
 3785        }
 3786        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3787        cx.spawn(async move |this, cx| {
 3788            let response = client.request(message).await?;
 3789            let this = this.upgrade().context("project dropped")?;
 3790            request
 3791                .response_from_proto(response, this, buffer, cx.clone())
 3792                .await
 3793        })
 3794    }
 3795
 3796    pub(super) fn new_remote(
 3797        buffer_store: Entity<BufferStore>,
 3798        worktree_store: Entity<WorktreeStore>,
 3799        languages: Arc<LanguageRegistry>,
 3800        upstream_client: AnyProtoClient,
 3801        project_id: u64,
 3802        fs: Arc<dyn Fs>,
 3803        cx: &mut Context<Self>,
 3804    ) -> Self {
 3805        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3806            .detach();
 3807        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3808            .detach();
 3809        subscribe_to_binary_statuses(&languages, cx).detach();
 3810        let _maintain_workspace_config = {
 3811            let (sender, receiver) = watch::channel();
 3812            (Self::maintain_workspace_config(fs, receiver, cx), sender)
 3813        };
 3814        Self {
 3815            mode: LspStoreMode::Remote(RemoteLspStore {
 3816                upstream_client: Some(upstream_client),
 3817                upstream_project_id: project_id,
 3818            }),
 3819            downstream_client: None,
 3820            last_formatting_failure: None,
 3821            buffer_store,
 3822            worktree_store,
 3823            languages: languages.clone(),
 3824            language_server_statuses: Default::default(),
 3825            nonce: StdRng::from_os_rng().random(),
 3826            diagnostic_summaries: HashMap::default(),
 3827            lsp_server_capabilities: HashMap::default(),
 3828            lsp_document_colors: HashMap::default(),
 3829            lsp_code_lens: HashMap::default(),
 3830            running_lsp_requests: HashMap::default(),
 3831            active_entry: None,
 3832
 3833            _maintain_workspace_config,
 3834            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3835        }
 3836    }
 3837
 3838    fn on_buffer_store_event(
 3839        &mut self,
 3840        _: Entity<BufferStore>,
 3841        event: &BufferStoreEvent,
 3842        cx: &mut Context<Self>,
 3843    ) {
 3844        match event {
 3845            BufferStoreEvent::BufferAdded(buffer) => {
 3846                self.on_buffer_added(buffer, cx).log_err();
 3847            }
 3848            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3849                let buffer_id = buffer.read(cx).remote_id();
 3850                if let Some(local) = self.as_local_mut()
 3851                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3852                {
 3853                    local.reset_buffer(buffer, old_file, cx);
 3854
 3855                    if local.registered_buffers.contains_key(&buffer_id) {
 3856                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3857                    }
 3858                }
 3859
 3860                self.detect_language_for_buffer(buffer, cx);
 3861                if let Some(local) = self.as_local_mut() {
 3862                    local.initialize_buffer(buffer, cx);
 3863                    if local.registered_buffers.contains_key(&buffer_id) {
 3864                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3865                    }
 3866                }
 3867            }
 3868            _ => {}
 3869        }
 3870    }
 3871
 3872    fn on_worktree_store_event(
 3873        &mut self,
 3874        _: Entity<WorktreeStore>,
 3875        event: &WorktreeStoreEvent,
 3876        cx: &mut Context<Self>,
 3877    ) {
 3878        match event {
 3879            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3880                if !worktree.read(cx).is_local() {
 3881                    return;
 3882                }
 3883                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3884                    worktree::Event::UpdatedEntries(changes) => {
 3885                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 3886                    }
 3887                    worktree::Event::UpdatedGitRepositories(_)
 3888                    | worktree::Event::DeletedEntry(_) => {}
 3889                })
 3890                .detach()
 3891            }
 3892            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 3893            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 3894                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 3895            }
 3896            WorktreeStoreEvent::WorktreeReleased(..)
 3897            | WorktreeStoreEvent::WorktreeOrderChanged
 3898            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 3899            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 3900            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 3901        }
 3902    }
 3903
 3904    fn on_prettier_store_event(
 3905        &mut self,
 3906        _: Entity<PrettierStore>,
 3907        event: &PrettierStoreEvent,
 3908        cx: &mut Context<Self>,
 3909    ) {
 3910        match event {
 3911            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 3912                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 3913            }
 3914            PrettierStoreEvent::LanguageServerAdded {
 3915                new_server_id,
 3916                name,
 3917                prettier_server,
 3918            } => {
 3919                self.register_supplementary_language_server(
 3920                    *new_server_id,
 3921                    name.clone(),
 3922                    prettier_server.clone(),
 3923                    cx,
 3924                );
 3925            }
 3926        }
 3927    }
 3928
 3929    fn on_toolchain_store_event(
 3930        &mut self,
 3931        _: Entity<LocalToolchainStore>,
 3932        event: &ToolchainStoreEvent,
 3933        _: &mut Context<Self>,
 3934    ) {
 3935        if let ToolchainStoreEvent::ToolchainActivated = event {
 3936            self.request_workspace_config_refresh()
 3937        }
 3938    }
 3939
 3940    fn request_workspace_config_refresh(&mut self) {
 3941        *self._maintain_workspace_config.1.borrow_mut() = ();
 3942    }
 3943
 3944    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 3945        self.as_local().map(|local| local.prettier_store.clone())
 3946    }
 3947
 3948    fn on_buffer_event(
 3949        &mut self,
 3950        buffer: Entity<Buffer>,
 3951        event: &language::BufferEvent,
 3952        cx: &mut Context<Self>,
 3953    ) {
 3954        match event {
 3955            language::BufferEvent::Edited => {
 3956                self.on_buffer_edited(buffer, cx);
 3957            }
 3958
 3959            language::BufferEvent::Saved => {
 3960                self.on_buffer_saved(buffer, cx);
 3961            }
 3962
 3963            _ => {}
 3964        }
 3965    }
 3966
 3967    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 3968        buffer
 3969            .read(cx)
 3970            .set_language_registry(self.languages.clone());
 3971
 3972        cx.subscribe(buffer, |this, buffer, event, cx| {
 3973            this.on_buffer_event(buffer, event, cx);
 3974        })
 3975        .detach();
 3976
 3977        self.detect_language_for_buffer(buffer, cx);
 3978        if let Some(local) = self.as_local_mut() {
 3979            local.initialize_buffer(buffer, cx);
 3980        }
 3981
 3982        Ok(())
 3983    }
 3984
 3985    pub fn reload_zed_json_schemas_on_extensions_changed(
 3986        &mut self,
 3987        _: Entity<extension::ExtensionEvents>,
 3988        evt: &extension::Event,
 3989        cx: &mut Context<Self>,
 3990    ) {
 3991        match evt {
 3992            extension::Event::ExtensionInstalled(_)
 3993            | extension::Event::ExtensionUninstalled(_)
 3994            | extension::Event::ConfigureExtensionRequested(_) => return,
 3995            extension::Event::ExtensionsInstalledChanged => {}
 3996        }
 3997        if self.as_local().is_none() {
 3998            return;
 3999        }
 4000        cx.spawn(async move |this, cx| {
 4001            let weak_ref = this.clone();
 4002
 4003            let servers = this
 4004                .update(cx, |this, cx| {
 4005                    let local = this.as_local()?;
 4006
 4007                    let mut servers = Vec::new();
 4008                    for (seed, state) in &local.language_server_ids {
 4009
 4010                            let Some(states) = local.language_servers.get(&state.id) else {
 4011                                continue;
 4012                            };
 4013                            let (json_adapter, json_server) = match states {
 4014                                LanguageServerState::Running {
 4015                                    adapter, server, ..
 4016                                } if adapter.adapter.is_primary_zed_json_schema_adapter() => {
 4017                                    (adapter.adapter.clone(), server.clone())
 4018                                }
 4019                                _ => continue,
 4020                            };
 4021
 4022                            let Some(worktree) = this
 4023                                .worktree_store
 4024                                .read(cx)
 4025                                .worktree_for_id(seed.worktree_id, cx)
 4026                            else {
 4027                                continue;
 4028                            };
 4029                            let json_delegate: Arc<dyn LspAdapterDelegate> =
 4030                                LocalLspAdapterDelegate::new(
 4031                                    local.languages.clone(),
 4032                                    &local.environment,
 4033                                    weak_ref.clone(),
 4034                                    &worktree,
 4035                                    local.http_client.clone(),
 4036                                    local.fs.clone(),
 4037                                    cx,
 4038                                );
 4039
 4040                            servers.push((json_adapter, json_server, json_delegate));
 4041
 4042                    }
 4043                    Some(servers)
 4044                })
 4045                .ok()
 4046                .flatten();
 4047
 4048            let Some(servers) = servers else {
 4049                return;
 4050            };
 4051
 4052            let Ok(Some((fs, _))) = this.read_with(cx, |this, _| {
 4053                let local = this.as_local()?;
 4054                let toolchain_store = local.toolchain_store().clone();
 4055                Some((local.fs.clone(), toolchain_store))
 4056            }) else {
 4057                return;
 4058            };
 4059            for (adapter, server, delegate) in servers {
 4060                adapter.clear_zed_json_schema_cache().await;
 4061
 4062                let Some(json_workspace_config) = LocalLspStore::workspace_configuration_for_adapter(
 4063                        adapter,
 4064                        fs.as_ref(),
 4065                        &delegate,
 4066                        None,
 4067                        cx,
 4068                    )
 4069                    .await
 4070                    .context("generate new workspace configuration for JSON language server while trying to refresh JSON Schemas")
 4071                    .ok()
 4072                else {
 4073                    continue;
 4074                };
 4075                server
 4076                    .notify::<lsp::notification::DidChangeConfiguration>(
 4077                        &lsp::DidChangeConfigurationParams {
 4078                            settings: json_workspace_config,
 4079                        },
 4080                    )
 4081                    .ok();
 4082            }
 4083        })
 4084        .detach();
 4085    }
 4086
 4087    pub(crate) fn register_buffer_with_language_servers(
 4088        &mut self,
 4089        buffer: &Entity<Buffer>,
 4090        only_register_servers: HashSet<LanguageServerSelector>,
 4091        ignore_refcounts: bool,
 4092        cx: &mut Context<Self>,
 4093    ) -> OpenLspBufferHandle {
 4094        let buffer_id = buffer.read(cx).remote_id();
 4095        let handle = cx.new(|_| buffer.clone());
 4096        if let Some(local) = self.as_local_mut() {
 4097            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4098            if !ignore_refcounts {
 4099                *refcount += 1;
 4100            }
 4101
 4102            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4103            // 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
 4104            // 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
 4105            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4106            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4107                return handle;
 4108            };
 4109            if !file.is_local() {
 4110                return handle;
 4111            }
 4112
 4113            if ignore_refcounts || *refcount == 1 {
 4114                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4115            }
 4116            if !ignore_refcounts {
 4117                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4118                    let refcount = {
 4119                        let local = lsp_store.as_local_mut().unwrap();
 4120                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4121                            debug_panic!("bad refcounting");
 4122                            return;
 4123                        };
 4124
 4125                        *refcount -= 1;
 4126                        *refcount
 4127                    };
 4128                    if refcount == 0 {
 4129                        lsp_store.lsp_document_colors.remove(&buffer_id);
 4130                        lsp_store.lsp_code_lens.remove(&buffer_id);
 4131                        let local = lsp_store.as_local_mut().unwrap();
 4132                        local.registered_buffers.remove(&buffer_id);
 4133                        local.buffers_opened_in_servers.remove(&buffer_id);
 4134                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4135                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4136                        }
 4137                    }
 4138                })
 4139                .detach();
 4140            }
 4141        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4142            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4143            cx.background_spawn(async move {
 4144                upstream_client
 4145                    .request(proto::RegisterBufferWithLanguageServers {
 4146                        project_id: upstream_project_id,
 4147                        buffer_id,
 4148                        only_servers: only_register_servers
 4149                            .into_iter()
 4150                            .map(|selector| {
 4151                                let selector = match selector {
 4152                                    LanguageServerSelector::Id(language_server_id) => {
 4153                                        proto::language_server_selector::Selector::ServerId(
 4154                                            language_server_id.to_proto(),
 4155                                        )
 4156                                    }
 4157                                    LanguageServerSelector::Name(language_server_name) => {
 4158                                        proto::language_server_selector::Selector::Name(
 4159                                            language_server_name.to_string(),
 4160                                        )
 4161                                    }
 4162                                };
 4163                                proto::LanguageServerSelector {
 4164                                    selector: Some(selector),
 4165                                }
 4166                            })
 4167                            .collect(),
 4168                    })
 4169                    .await
 4170            })
 4171            .detach();
 4172        } else {
 4173            panic!("oops!");
 4174        }
 4175        handle
 4176    }
 4177
 4178    fn maintain_buffer_languages(
 4179        languages: Arc<LanguageRegistry>,
 4180        cx: &mut Context<Self>,
 4181    ) -> Task<()> {
 4182        let mut subscription = languages.subscribe();
 4183        let mut prev_reload_count = languages.reload_count();
 4184        cx.spawn(async move |this, cx| {
 4185            while let Some(()) = subscription.next().await {
 4186                if let Some(this) = this.upgrade() {
 4187                    // If the language registry has been reloaded, then remove and
 4188                    // re-assign the languages on all open buffers.
 4189                    let reload_count = languages.reload_count();
 4190                    if reload_count > prev_reload_count {
 4191                        prev_reload_count = reload_count;
 4192                        this.update(cx, |this, cx| {
 4193                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4194                                for buffer in buffer_store.buffers() {
 4195                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4196                                    {
 4197                                        buffer
 4198                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4199                                        if let Some(local) = this.as_local_mut() {
 4200                                            local.reset_buffer(&buffer, &f, cx);
 4201
 4202                                            if local
 4203                                                .registered_buffers
 4204                                                .contains_key(&buffer.read(cx).remote_id())
 4205                                                && let Some(file_url) =
 4206                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4207                                            {
 4208                                                local.unregister_buffer_from_language_servers(
 4209                                                    &buffer, &file_url, cx,
 4210                                                );
 4211                                            }
 4212                                        }
 4213                                    }
 4214                                }
 4215                            });
 4216                        })
 4217                        .ok();
 4218                    }
 4219
 4220                    this.update(cx, |this, cx| {
 4221                        let mut plain_text_buffers = Vec::new();
 4222                        let mut buffers_with_unknown_injections = Vec::new();
 4223                        for handle in this.buffer_store.read(cx).buffers() {
 4224                            let buffer = handle.read(cx);
 4225                            if buffer.language().is_none()
 4226                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4227                            {
 4228                                plain_text_buffers.push(handle);
 4229                            } else if buffer.contains_unknown_injections() {
 4230                                buffers_with_unknown_injections.push(handle);
 4231                            }
 4232                        }
 4233
 4234                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4235                        // and reused later in the invisible worktrees.
 4236                        plain_text_buffers.sort_by_key(|buffer| {
 4237                            Reverse(
 4238                                File::from_dyn(buffer.read(cx).file())
 4239                                    .map(|file| file.worktree.read(cx).is_visible()),
 4240                            )
 4241                        });
 4242
 4243                        for buffer in plain_text_buffers {
 4244                            this.detect_language_for_buffer(&buffer, cx);
 4245                            if let Some(local) = this.as_local_mut() {
 4246                                local.initialize_buffer(&buffer, cx);
 4247                                if local
 4248                                    .registered_buffers
 4249                                    .contains_key(&buffer.read(cx).remote_id())
 4250                                {
 4251                                    local.register_buffer_with_language_servers(
 4252                                        &buffer,
 4253                                        HashSet::default(),
 4254                                        cx,
 4255                                    );
 4256                                }
 4257                            }
 4258                        }
 4259
 4260                        for buffer in buffers_with_unknown_injections {
 4261                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4262                        }
 4263                    })
 4264                    .ok();
 4265                }
 4266            }
 4267        })
 4268    }
 4269
 4270    fn detect_language_for_buffer(
 4271        &mut self,
 4272        buffer_handle: &Entity<Buffer>,
 4273        cx: &mut Context<Self>,
 4274    ) -> Option<language::AvailableLanguage> {
 4275        // If the buffer has a language, set it and start the language server if we haven't already.
 4276        let buffer = buffer_handle.read(cx);
 4277        let file = buffer.file()?;
 4278
 4279        let content = buffer.as_rope();
 4280        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4281        if let Some(available_language) = &available_language {
 4282            if let Some(Ok(Ok(new_language))) = self
 4283                .languages
 4284                .load_language(available_language)
 4285                .now_or_never()
 4286            {
 4287                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4288            }
 4289        } else {
 4290            cx.emit(LspStoreEvent::LanguageDetected {
 4291                buffer: buffer_handle.clone(),
 4292                new_language: None,
 4293            });
 4294        }
 4295
 4296        available_language
 4297    }
 4298
 4299    pub(crate) fn set_language_for_buffer(
 4300        &mut self,
 4301        buffer_entity: &Entity<Buffer>,
 4302        new_language: Arc<Language>,
 4303        cx: &mut Context<Self>,
 4304    ) {
 4305        let buffer = buffer_entity.read(cx);
 4306        let buffer_file = buffer.file().cloned();
 4307        let buffer_id = buffer.remote_id();
 4308        if let Some(local_store) = self.as_local_mut()
 4309            && local_store.registered_buffers.contains_key(&buffer_id)
 4310            && let Some(abs_path) =
 4311                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4312            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4313        {
 4314            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4315        }
 4316        buffer_entity.update(cx, |buffer, cx| {
 4317            if buffer
 4318                .language()
 4319                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4320            {
 4321                buffer.set_language(Some(new_language.clone()), cx);
 4322            }
 4323        });
 4324
 4325        let settings =
 4326            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4327        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4328
 4329        let worktree_id = if let Some(file) = buffer_file {
 4330            let worktree = file.worktree.clone();
 4331
 4332            if let Some(local) = self.as_local_mut()
 4333                && local.registered_buffers.contains_key(&buffer_id)
 4334            {
 4335                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4336            }
 4337            Some(worktree.read(cx).id())
 4338        } else {
 4339            None
 4340        };
 4341
 4342        if settings.prettier.allowed
 4343            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4344        {
 4345            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4346            if let Some(prettier_store) = prettier_store {
 4347                prettier_store.update(cx, |prettier_store, cx| {
 4348                    prettier_store.install_default_prettier(
 4349                        worktree_id,
 4350                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4351                        cx,
 4352                    )
 4353                })
 4354            }
 4355        }
 4356
 4357        cx.emit(LspStoreEvent::LanguageDetected {
 4358            buffer: buffer_entity.clone(),
 4359            new_language: Some(new_language),
 4360        })
 4361    }
 4362
 4363    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4364        self.buffer_store.clone()
 4365    }
 4366
 4367    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4368        self.active_entry = active_entry;
 4369    }
 4370
 4371    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4372        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4373            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4374        {
 4375            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4376                summaries
 4377                    .iter()
 4378                    .map(|(server_id, summary)| summary.to_proto(*server_id, path))
 4379            });
 4380            if let Some(summary) = summaries.next() {
 4381                client
 4382                    .send(proto::UpdateDiagnosticSummary {
 4383                        project_id: downstream_project_id,
 4384                        worktree_id: worktree.id().to_proto(),
 4385                        summary: Some(summary),
 4386                        more_summaries: summaries.collect(),
 4387                    })
 4388                    .log_err();
 4389            }
 4390        }
 4391    }
 4392
 4393    fn is_capable_for_proto_request<R>(
 4394        &self,
 4395        buffer: &Entity<Buffer>,
 4396        request: &R,
 4397        cx: &Context<Self>,
 4398    ) -> bool
 4399    where
 4400        R: LspCommand,
 4401    {
 4402        self.check_if_capable_for_proto_request(
 4403            buffer,
 4404            |capabilities| {
 4405                request.check_capabilities(AdapterServerCapabilities {
 4406                    server_capabilities: capabilities.clone(),
 4407                    code_action_kinds: None,
 4408                })
 4409            },
 4410            cx,
 4411        )
 4412    }
 4413
 4414    fn check_if_capable_for_proto_request<F>(
 4415        &self,
 4416        buffer: &Entity<Buffer>,
 4417        check: F,
 4418        cx: &Context<Self>,
 4419    ) -> bool
 4420    where
 4421        F: Fn(&lsp::ServerCapabilities) -> bool,
 4422    {
 4423        let Some(language) = buffer.read(cx).language().cloned() else {
 4424            return false;
 4425        };
 4426        let relevant_language_servers = self
 4427            .languages
 4428            .lsp_adapters(&language.name())
 4429            .into_iter()
 4430            .map(|lsp_adapter| lsp_adapter.name())
 4431            .collect::<HashSet<_>>();
 4432        self.language_server_statuses
 4433            .iter()
 4434            .filter_map(|(server_id, server_status)| {
 4435                relevant_language_servers
 4436                    .contains(&server_status.name)
 4437                    .then_some(server_id)
 4438            })
 4439            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4440            .any(check)
 4441    }
 4442
 4443    pub fn request_lsp<R>(
 4444        &mut self,
 4445        buffer: Entity<Buffer>,
 4446        server: LanguageServerToQuery,
 4447        request: R,
 4448        cx: &mut Context<Self>,
 4449    ) -> Task<Result<R::Response>>
 4450    where
 4451        R: LspCommand,
 4452        <R::LspRequest as lsp::request::Request>::Result: Send,
 4453        <R::LspRequest as lsp::request::Request>::Params: Send,
 4454    {
 4455        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4456            return self.send_lsp_proto_request(
 4457                buffer,
 4458                upstream_client,
 4459                upstream_project_id,
 4460                request,
 4461                cx,
 4462            );
 4463        }
 4464
 4465        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4466            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4467                local
 4468                    .language_servers_for_buffer(buffer, cx)
 4469                    .find(|(_, server)| {
 4470                        request.check_capabilities(server.adapter_server_capabilities())
 4471                    })
 4472                    .map(|(_, server)| server.clone())
 4473            }),
 4474            LanguageServerToQuery::Other(id) => self
 4475                .language_server_for_local_buffer(buffer, id, cx)
 4476                .and_then(|(_, server)| {
 4477                    request
 4478                        .check_capabilities(server.adapter_server_capabilities())
 4479                        .then(|| Arc::clone(server))
 4480                }),
 4481        }) else {
 4482            return Task::ready(Ok(Default::default()));
 4483        };
 4484
 4485        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4486
 4487        let Some(file) = file else {
 4488            return Task::ready(Ok(Default::default()));
 4489        };
 4490
 4491        let lsp_params = match request.to_lsp_params_or_response(
 4492            &file.abs_path(cx),
 4493            buffer.read(cx),
 4494            &language_server,
 4495            cx,
 4496        ) {
 4497            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4498            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4499
 4500            Err(err) => {
 4501                let message = format!(
 4502                    "{} via {} failed: {}",
 4503                    request.display_name(),
 4504                    language_server.name(),
 4505                    err
 4506                );
 4507                log::warn!("{message}");
 4508                return Task::ready(Err(anyhow!(message)));
 4509            }
 4510        };
 4511
 4512        let status = request.status();
 4513        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4514            return Task::ready(Ok(Default::default()));
 4515        }
 4516        cx.spawn(async move |this, cx| {
 4517            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4518
 4519            let id = lsp_request.id();
 4520            let _cleanup = if status.is_some() {
 4521                cx.update(|cx| {
 4522                    this.update(cx, |this, cx| {
 4523                        this.on_lsp_work_start(
 4524                            language_server.server_id(),
 4525                            id.to_string(),
 4526                            LanguageServerProgress {
 4527                                is_disk_based_diagnostics_progress: false,
 4528                                is_cancellable: false,
 4529                                title: None,
 4530                                message: status.clone(),
 4531                                percentage: None,
 4532                                last_update_at: cx.background_executor().now(),
 4533                            },
 4534                            cx,
 4535                        );
 4536                    })
 4537                })
 4538                .log_err();
 4539
 4540                Some(defer(|| {
 4541                    cx.update(|cx| {
 4542                        this.update(cx, |this, cx| {
 4543                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
 4544                        })
 4545                    })
 4546                    .log_err();
 4547                }))
 4548            } else {
 4549                None
 4550            };
 4551
 4552            let result = lsp_request.await.into_response();
 4553
 4554            let response = result.map_err(|err| {
 4555                let message = format!(
 4556                    "{} via {} failed: {}",
 4557                    request.display_name(),
 4558                    language_server.name(),
 4559                    err
 4560                );
 4561                log::warn!("{message}");
 4562                anyhow::anyhow!(message)
 4563            })?;
 4564
 4565            request
 4566                .response_from_lsp(
 4567                    response,
 4568                    this.upgrade().context("no app context")?,
 4569                    buffer,
 4570                    language_server.server_id(),
 4571                    cx.clone(),
 4572                )
 4573                .await
 4574        })
 4575    }
 4576
 4577    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4578        let mut language_formatters_to_check = Vec::new();
 4579        for buffer in self.buffer_store.read(cx).buffers() {
 4580            let buffer = buffer.read(cx);
 4581            let buffer_file = File::from_dyn(buffer.file());
 4582            let buffer_language = buffer.language();
 4583            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4584            if buffer_language.is_some() {
 4585                language_formatters_to_check.push((
 4586                    buffer_file.map(|f| f.worktree_id(cx)),
 4587                    settings.into_owned(),
 4588                ));
 4589            }
 4590        }
 4591
 4592        self.request_workspace_config_refresh();
 4593
 4594        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4595            prettier_store.update(cx, |prettier_store, cx| {
 4596                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4597            })
 4598        }
 4599
 4600        cx.notify();
 4601    }
 4602
 4603    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4604        let buffer_store = self.buffer_store.clone();
 4605        let Some(local) = self.as_local_mut() else {
 4606            return;
 4607        };
 4608        let mut adapters = BTreeMap::default();
 4609        let get_adapter = {
 4610            let languages = local.languages.clone();
 4611            let environment = local.environment.clone();
 4612            let weak = local.weak.clone();
 4613            let worktree_store = local.worktree_store.clone();
 4614            let http_client = local.http_client.clone();
 4615            let fs = local.fs.clone();
 4616            move |worktree_id, cx: &mut App| {
 4617                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4618                Some(LocalLspAdapterDelegate::new(
 4619                    languages.clone(),
 4620                    &environment,
 4621                    weak.clone(),
 4622                    &worktree,
 4623                    http_client.clone(),
 4624                    fs.clone(),
 4625                    cx,
 4626                ))
 4627            }
 4628        };
 4629
 4630        let mut messages_to_report = Vec::new();
 4631        let (new_tree, to_stop) = {
 4632            let mut rebase = local.lsp_tree.rebase();
 4633            let buffers = buffer_store
 4634                .read(cx)
 4635                .buffers()
 4636                .filter_map(|buffer| {
 4637                    let raw_buffer = buffer.read(cx);
 4638                    if !local
 4639                        .registered_buffers
 4640                        .contains_key(&raw_buffer.remote_id())
 4641                    {
 4642                        return None;
 4643                    }
 4644                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4645                    let language = raw_buffer.language().cloned()?;
 4646                    Some((file, language, raw_buffer.remote_id()))
 4647                })
 4648                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4649            for (file, language, buffer_id) in buffers {
 4650                let worktree_id = file.worktree_id(cx);
 4651                let Some(worktree) = local
 4652                    .worktree_store
 4653                    .read(cx)
 4654                    .worktree_for_id(worktree_id, cx)
 4655                else {
 4656                    continue;
 4657                };
 4658
 4659                if let Some((_, apply)) = local.reuse_existing_language_server(
 4660                    rebase.server_tree(),
 4661                    &worktree,
 4662                    &language.name(),
 4663                    cx,
 4664                ) {
 4665                    (apply)(rebase.server_tree());
 4666                } else if let Some(lsp_delegate) = adapters
 4667                    .entry(worktree_id)
 4668                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4669                    .clone()
 4670                {
 4671                    let delegate =
 4672                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4673                    let path = file
 4674                        .path()
 4675                        .parent()
 4676                        .map(Arc::from)
 4677                        .unwrap_or_else(|| file.path().clone());
 4678                    let worktree_path = ProjectPath { worktree_id, path };
 4679                    let abs_path = file.abs_path(cx);
 4680                    let worktree_root = worktree.read(cx).abs_path();
 4681                    let nodes = rebase
 4682                        .walk(
 4683                            worktree_path,
 4684                            language.name(),
 4685                            language.manifest(),
 4686                            delegate.clone(),
 4687                            cx,
 4688                        )
 4689                        .collect::<Vec<_>>();
 4690                    for node in nodes {
 4691                        let server_id = node.server_id_or_init(|disposition| {
 4692                            let path = &disposition.path;
 4693                            let uri = Uri::from_file_path(worktree_root.join(&path.path));
 4694                            let key = LanguageServerSeed {
 4695                                worktree_id,
 4696                                name: disposition.server_name.clone(),
 4697                                settings: disposition.settings.clone(),
 4698                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4699                                    path.worktree_id,
 4700                                    &path.path,
 4701                                    language.name(),
 4702                                ),
 4703                            };
 4704                            local.language_server_ids.remove(&key);
 4705
 4706                            let server_id = local.get_or_insert_language_server(
 4707                                &worktree,
 4708                                lsp_delegate.clone(),
 4709                                disposition,
 4710                                &language.name(),
 4711                                cx,
 4712                            );
 4713                            if let Some(state) = local.language_servers.get(&server_id)
 4714                                && let Ok(uri) = uri
 4715                            {
 4716                                state.add_workspace_folder(uri);
 4717                            };
 4718                            server_id
 4719                        });
 4720
 4721                        if let Some(language_server_id) = server_id {
 4722                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4723                                language_server_id,
 4724                                name: node.name(),
 4725                                message:
 4726                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4727                                        proto::RegisteredForBuffer {
 4728                                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 4729                                            buffer_id: buffer_id.to_proto(),
 4730                                        },
 4731                                    ),
 4732                            });
 4733                        }
 4734                    }
 4735                } else {
 4736                    continue;
 4737                }
 4738            }
 4739            rebase.finish()
 4740        };
 4741        for message in messages_to_report {
 4742            cx.emit(message);
 4743        }
 4744        local.lsp_tree = new_tree;
 4745        for (id, _) in to_stop {
 4746            self.stop_local_language_server(id, cx).detach();
 4747        }
 4748    }
 4749
 4750    pub fn apply_code_action(
 4751        &self,
 4752        buffer_handle: Entity<Buffer>,
 4753        mut action: CodeAction,
 4754        push_to_history: bool,
 4755        cx: &mut Context<Self>,
 4756    ) -> Task<Result<ProjectTransaction>> {
 4757        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4758            let request = proto::ApplyCodeAction {
 4759                project_id,
 4760                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4761                action: Some(Self::serialize_code_action(&action)),
 4762            };
 4763            let buffer_store = self.buffer_store();
 4764            cx.spawn(async move |_, cx| {
 4765                let response = upstream_client
 4766                    .request(request)
 4767                    .await?
 4768                    .transaction
 4769                    .context("missing transaction")?;
 4770
 4771                buffer_store
 4772                    .update(cx, |buffer_store, cx| {
 4773                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4774                    })?
 4775                    .await
 4776            })
 4777        } else if self.mode.is_local() {
 4778            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4779                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4780                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4781            }) else {
 4782                return Task::ready(Ok(ProjectTransaction::default()));
 4783            };
 4784            cx.spawn(async move |this,  cx| {
 4785                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4786                    .await
 4787                    .context("resolving a code action")?;
 4788                if let Some(edit) = action.lsp_action.edit()
 4789                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4790                        return LocalLspStore::deserialize_workspace_edit(
 4791                            this.upgrade().context("no app present")?,
 4792                            edit.clone(),
 4793                            push_to_history,
 4794
 4795                            lang_server.clone(),
 4796                            cx,
 4797                        )
 4798                        .await;
 4799                    }
 4800
 4801                if let Some(command) = action.lsp_action.command() {
 4802                    let server_capabilities = lang_server.capabilities();
 4803                    let available_commands = server_capabilities
 4804                        .execute_command_provider
 4805                        .as_ref()
 4806                        .map(|options| options.commands.as_slice())
 4807                        .unwrap_or_default();
 4808                    if available_commands.contains(&command.command) {
 4809                        this.update(cx, |this, _| {
 4810                            this.as_local_mut()
 4811                                .unwrap()
 4812                                .last_workspace_edits_by_language_server
 4813                                .remove(&lang_server.server_id());
 4814                        })?;
 4815
 4816                        let _result = lang_server
 4817                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4818                                command: command.command.clone(),
 4819                                arguments: command.arguments.clone().unwrap_or_default(),
 4820                                ..lsp::ExecuteCommandParams::default()
 4821                            })
 4822                            .await.into_response()
 4823                            .context("execute command")?;
 4824
 4825                        return this.update(cx, |this, _| {
 4826                            this.as_local_mut()
 4827                                .unwrap()
 4828                                .last_workspace_edits_by_language_server
 4829                                .remove(&lang_server.server_id())
 4830                                .unwrap_or_default()
 4831                        });
 4832                    } else {
 4833                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4834                    }
 4835                }
 4836
 4837                Ok(ProjectTransaction::default())
 4838            })
 4839        } else {
 4840            Task::ready(Err(anyhow!("no upstream client and not local")))
 4841        }
 4842    }
 4843
 4844    pub fn apply_code_action_kind(
 4845        &mut self,
 4846        buffers: HashSet<Entity<Buffer>>,
 4847        kind: CodeActionKind,
 4848        push_to_history: bool,
 4849        cx: &mut Context<Self>,
 4850    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4851        if self.as_local().is_some() {
 4852            cx.spawn(async move |lsp_store, cx| {
 4853                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4854                let result = LocalLspStore::execute_code_action_kind_locally(
 4855                    lsp_store.clone(),
 4856                    buffers,
 4857                    kind,
 4858                    push_to_history,
 4859                    cx,
 4860                )
 4861                .await;
 4862                lsp_store.update(cx, |lsp_store, _| {
 4863                    lsp_store.update_last_formatting_failure(&result);
 4864                })?;
 4865                result
 4866            })
 4867        } else if let Some((client, project_id)) = self.upstream_client() {
 4868            let buffer_store = self.buffer_store();
 4869            cx.spawn(async move |lsp_store, cx| {
 4870                let result = client
 4871                    .request(proto::ApplyCodeActionKind {
 4872                        project_id,
 4873                        kind: kind.as_str().to_owned(),
 4874                        buffer_ids: buffers
 4875                            .iter()
 4876                            .map(|buffer| {
 4877                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4878                            })
 4879                            .collect::<Result<_>>()?,
 4880                    })
 4881                    .await
 4882                    .and_then(|result| result.transaction.context("missing transaction"));
 4883                lsp_store.update(cx, |lsp_store, _| {
 4884                    lsp_store.update_last_formatting_failure(&result);
 4885                })?;
 4886
 4887                let transaction_response = result?;
 4888                buffer_store
 4889                    .update(cx, |buffer_store, cx| {
 4890                        buffer_store.deserialize_project_transaction(
 4891                            transaction_response,
 4892                            push_to_history,
 4893                            cx,
 4894                        )
 4895                    })?
 4896                    .await
 4897            })
 4898        } else {
 4899            Task::ready(Ok(ProjectTransaction::default()))
 4900        }
 4901    }
 4902
 4903    pub fn resolve_inlay_hint(
 4904        &self,
 4905        mut hint: InlayHint,
 4906        buffer: Entity<Buffer>,
 4907        server_id: LanguageServerId,
 4908        cx: &mut Context<Self>,
 4909    ) -> Task<anyhow::Result<InlayHint>> {
 4910        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4911            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4912            {
 4913                hint.resolve_state = ResolveState::Resolved;
 4914                return Task::ready(Ok(hint));
 4915            }
 4916            let request = proto::ResolveInlayHint {
 4917                project_id,
 4918                buffer_id: buffer.read(cx).remote_id().into(),
 4919                language_server_id: server_id.0 as u64,
 4920                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 4921            };
 4922            cx.background_spawn(async move {
 4923                let response = upstream_client
 4924                    .request(request)
 4925                    .await
 4926                    .context("inlay hints proto request")?;
 4927                match response.hint {
 4928                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 4929                        .context("inlay hints proto resolve response conversion"),
 4930                    None => Ok(hint),
 4931                }
 4932            })
 4933        } else {
 4934            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 4935                self.language_server_for_local_buffer(buffer, server_id, cx)
 4936                    .map(|(_, server)| server.clone())
 4937            }) else {
 4938                return Task::ready(Ok(hint));
 4939            };
 4940            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 4941                return Task::ready(Ok(hint));
 4942            }
 4943            let buffer_snapshot = buffer.read(cx).snapshot();
 4944            cx.spawn(async move |_, cx| {
 4945                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 4946                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 4947                );
 4948                let resolved_hint = resolve_task
 4949                    .await
 4950                    .into_response()
 4951                    .context("inlay hint resolve LSP request")?;
 4952                let resolved_hint = InlayHints::lsp_to_project_hint(
 4953                    resolved_hint,
 4954                    &buffer,
 4955                    server_id,
 4956                    ResolveState::Resolved,
 4957                    false,
 4958                    cx,
 4959                )
 4960                .await?;
 4961                Ok(resolved_hint)
 4962            })
 4963        }
 4964    }
 4965
 4966    pub fn resolve_color_presentation(
 4967        &mut self,
 4968        mut color: DocumentColor,
 4969        buffer: Entity<Buffer>,
 4970        server_id: LanguageServerId,
 4971        cx: &mut Context<Self>,
 4972    ) -> Task<Result<DocumentColor>> {
 4973        if color.resolved {
 4974            return Task::ready(Ok(color));
 4975        }
 4976
 4977        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4978            let start = color.lsp_range.start;
 4979            let end = color.lsp_range.end;
 4980            let request = proto::GetColorPresentation {
 4981                project_id,
 4982                server_id: server_id.to_proto(),
 4983                buffer_id: buffer.read(cx).remote_id().into(),
 4984                color: Some(proto::ColorInformation {
 4985                    red: color.color.red,
 4986                    green: color.color.green,
 4987                    blue: color.color.blue,
 4988                    alpha: color.color.alpha,
 4989                    lsp_range_start: Some(proto::PointUtf16 {
 4990                        row: start.line,
 4991                        column: start.character,
 4992                    }),
 4993                    lsp_range_end: Some(proto::PointUtf16 {
 4994                        row: end.line,
 4995                        column: end.character,
 4996                    }),
 4997                }),
 4998            };
 4999            cx.background_spawn(async move {
 5000                let response = upstream_client
 5001                    .request(request)
 5002                    .await
 5003                    .context("color presentation proto request")?;
 5004                color.resolved = true;
 5005                color.color_presentations = response
 5006                    .presentations
 5007                    .into_iter()
 5008                    .map(|presentation| ColorPresentation {
 5009                        label: SharedString::from(presentation.label),
 5010                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5011                        additional_text_edits: presentation
 5012                            .additional_text_edits
 5013                            .into_iter()
 5014                            .filter_map(deserialize_lsp_edit)
 5015                            .collect(),
 5016                    })
 5017                    .collect();
 5018                Ok(color)
 5019            })
 5020        } else {
 5021            let path = match buffer
 5022                .update(cx, |buffer, cx| {
 5023                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5024                })
 5025                .context("buffer with the missing path")
 5026            {
 5027                Ok(path) => path,
 5028                Err(e) => return Task::ready(Err(e)),
 5029            };
 5030            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5031                self.language_server_for_local_buffer(buffer, server_id, cx)
 5032                    .map(|(_, server)| server.clone())
 5033            }) else {
 5034                return Task::ready(Ok(color));
 5035            };
 5036            cx.background_spawn(async move {
 5037                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5038                    lsp::ColorPresentationParams {
 5039                        text_document: make_text_document_identifier(&path)?,
 5040                        color: color.color,
 5041                        range: color.lsp_range,
 5042                        work_done_progress_params: Default::default(),
 5043                        partial_result_params: Default::default(),
 5044                    },
 5045                );
 5046                color.color_presentations = resolve_task
 5047                    .await
 5048                    .into_response()
 5049                    .context("color presentation resolve LSP request")?
 5050                    .into_iter()
 5051                    .map(|presentation| ColorPresentation {
 5052                        label: SharedString::from(presentation.label),
 5053                        text_edit: presentation.text_edit,
 5054                        additional_text_edits: presentation
 5055                            .additional_text_edits
 5056                            .unwrap_or_default(),
 5057                    })
 5058                    .collect();
 5059                color.resolved = true;
 5060                Ok(color)
 5061            })
 5062        }
 5063    }
 5064
 5065    pub(crate) fn linked_edits(
 5066        &mut self,
 5067        buffer: &Entity<Buffer>,
 5068        position: Anchor,
 5069        cx: &mut Context<Self>,
 5070    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5071        let snapshot = buffer.read(cx).snapshot();
 5072        let scope = snapshot.language_scope_at(position);
 5073        let Some(server_id) = self
 5074            .as_local()
 5075            .and_then(|local| {
 5076                buffer.update(cx, |buffer, cx| {
 5077                    local
 5078                        .language_servers_for_buffer(buffer, cx)
 5079                        .filter(|(_, server)| {
 5080                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5081                        })
 5082                        .filter(|(adapter, _)| {
 5083                            scope
 5084                                .as_ref()
 5085                                .map(|scope| scope.language_allowed(&adapter.name))
 5086                                .unwrap_or(true)
 5087                        })
 5088                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5089                        .next()
 5090                })
 5091            })
 5092            .or_else(|| {
 5093                self.upstream_client()
 5094                    .is_some()
 5095                    .then_some(LanguageServerToQuery::FirstCapable)
 5096            })
 5097            .filter(|_| {
 5098                maybe!({
 5099                    let language = buffer.read(cx).language_at(position)?;
 5100                    Some(
 5101                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5102                            .linked_edits,
 5103                    )
 5104                }) == Some(true)
 5105            })
 5106        else {
 5107            return Task::ready(Ok(Vec::new()));
 5108        };
 5109
 5110        self.request_lsp(
 5111            buffer.clone(),
 5112            server_id,
 5113            LinkedEditingRange { position },
 5114            cx,
 5115        )
 5116    }
 5117
 5118    fn apply_on_type_formatting(
 5119        &mut self,
 5120        buffer: Entity<Buffer>,
 5121        position: Anchor,
 5122        trigger: String,
 5123        cx: &mut Context<Self>,
 5124    ) -> Task<Result<Option<Transaction>>> {
 5125        if let Some((client, project_id)) = self.upstream_client() {
 5126            if !self.check_if_capable_for_proto_request(
 5127                &buffer,
 5128                |capabilities| {
 5129                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5130                },
 5131                cx,
 5132            ) {
 5133                return Task::ready(Ok(None));
 5134            }
 5135            let request = proto::OnTypeFormatting {
 5136                project_id,
 5137                buffer_id: buffer.read(cx).remote_id().into(),
 5138                position: Some(serialize_anchor(&position)),
 5139                trigger,
 5140                version: serialize_version(&buffer.read(cx).version()),
 5141            };
 5142            cx.background_spawn(async move {
 5143                client
 5144                    .request(request)
 5145                    .await?
 5146                    .transaction
 5147                    .map(language::proto::deserialize_transaction)
 5148                    .transpose()
 5149            })
 5150        } else if let Some(local) = self.as_local_mut() {
 5151            let buffer_id = buffer.read(cx).remote_id();
 5152            local.buffers_being_formatted.insert(buffer_id);
 5153            cx.spawn(async move |this, cx| {
 5154                let _cleanup = defer({
 5155                    let this = this.clone();
 5156                    let mut cx = cx.clone();
 5157                    move || {
 5158                        this.update(&mut cx, |this, _| {
 5159                            if let Some(local) = this.as_local_mut() {
 5160                                local.buffers_being_formatted.remove(&buffer_id);
 5161                            }
 5162                        })
 5163                        .ok();
 5164                    }
 5165                });
 5166
 5167                buffer
 5168                    .update(cx, |buffer, _| {
 5169                        buffer.wait_for_edits(Some(position.timestamp))
 5170                    })?
 5171                    .await?;
 5172                this.update(cx, |this, cx| {
 5173                    let position = position.to_point_utf16(buffer.read(cx));
 5174                    this.on_type_format(buffer, position, trigger, false, cx)
 5175                })?
 5176                .await
 5177            })
 5178        } else {
 5179            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5180        }
 5181    }
 5182
 5183    pub fn on_type_format<T: ToPointUtf16>(
 5184        &mut self,
 5185        buffer: Entity<Buffer>,
 5186        position: T,
 5187        trigger: String,
 5188        push_to_history: bool,
 5189        cx: &mut Context<Self>,
 5190    ) -> Task<Result<Option<Transaction>>> {
 5191        let position = position.to_point_utf16(buffer.read(cx));
 5192        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5193    }
 5194
 5195    fn on_type_format_impl(
 5196        &mut self,
 5197        buffer: Entity<Buffer>,
 5198        position: PointUtf16,
 5199        trigger: String,
 5200        push_to_history: bool,
 5201        cx: &mut Context<Self>,
 5202    ) -> Task<Result<Option<Transaction>>> {
 5203        let options = buffer.update(cx, |buffer, cx| {
 5204            lsp_command::lsp_formatting_options(
 5205                language_settings(
 5206                    buffer.language_at(position).map(|l| l.name()),
 5207                    buffer.file(),
 5208                    cx,
 5209                )
 5210                .as_ref(),
 5211            )
 5212        });
 5213
 5214        cx.spawn(async move |this, cx| {
 5215            if let Some(waiter) =
 5216                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5217            {
 5218                waiter.await?;
 5219            }
 5220            cx.update(|cx| {
 5221                this.update(cx, |this, cx| {
 5222                    this.request_lsp(
 5223                        buffer.clone(),
 5224                        LanguageServerToQuery::FirstCapable,
 5225                        OnTypeFormatting {
 5226                            position,
 5227                            trigger,
 5228                            options,
 5229                            push_to_history,
 5230                        },
 5231                        cx,
 5232                    )
 5233                })
 5234            })??
 5235            .await
 5236        })
 5237    }
 5238
 5239    pub fn definitions(
 5240        &mut self,
 5241        buffer: &Entity<Buffer>,
 5242        position: PointUtf16,
 5243        cx: &mut Context<Self>,
 5244    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5245        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5246            let request = GetDefinitions { position };
 5247            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5248                return Task::ready(Ok(None));
 5249            }
 5250            let request_task = upstream_client.request_lsp(
 5251                project_id,
 5252                LSP_REQUEST_TIMEOUT,
 5253                cx.background_executor().clone(),
 5254                request.to_proto(project_id, buffer.read(cx)),
 5255            );
 5256            let buffer = buffer.clone();
 5257            cx.spawn(async move |weak_project, cx| {
 5258                let Some(project) = weak_project.upgrade() else {
 5259                    return Ok(None);
 5260                };
 5261                let Some(responses) = request_task.await? else {
 5262                    return Ok(None);
 5263                };
 5264                let actions = join_all(responses.payload.into_iter().map(|response| {
 5265                    GetDefinitions { position }.response_from_proto(
 5266                        response.response,
 5267                        project.clone(),
 5268                        buffer.clone(),
 5269                        cx.clone(),
 5270                    )
 5271                }))
 5272                .await;
 5273
 5274                Ok(Some(
 5275                    actions
 5276                        .into_iter()
 5277                        .collect::<Result<Vec<Vec<_>>>>()?
 5278                        .into_iter()
 5279                        .flatten()
 5280                        .dedup()
 5281                        .collect(),
 5282                ))
 5283            })
 5284        } else {
 5285            let definitions_task = self.request_multiple_lsp_locally(
 5286                buffer,
 5287                Some(position),
 5288                GetDefinitions { position },
 5289                cx,
 5290            );
 5291            cx.background_spawn(async move {
 5292                Ok(Some(
 5293                    definitions_task
 5294                        .await
 5295                        .into_iter()
 5296                        .flat_map(|(_, definitions)| definitions)
 5297                        .dedup()
 5298                        .collect(),
 5299                ))
 5300            })
 5301        }
 5302    }
 5303
 5304    pub fn declarations(
 5305        &mut self,
 5306        buffer: &Entity<Buffer>,
 5307        position: PointUtf16,
 5308        cx: &mut Context<Self>,
 5309    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5310        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5311            let request = GetDeclarations { position };
 5312            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5313                return Task::ready(Ok(None));
 5314            }
 5315            let request_task = upstream_client.request_lsp(
 5316                project_id,
 5317                LSP_REQUEST_TIMEOUT,
 5318                cx.background_executor().clone(),
 5319                request.to_proto(project_id, buffer.read(cx)),
 5320            );
 5321            let buffer = buffer.clone();
 5322            cx.spawn(async move |weak_project, cx| {
 5323                let Some(project) = weak_project.upgrade() else {
 5324                    return Ok(None);
 5325                };
 5326                let Some(responses) = request_task.await? else {
 5327                    return Ok(None);
 5328                };
 5329                let actions = join_all(responses.payload.into_iter().map(|response| {
 5330                    GetDeclarations { position }.response_from_proto(
 5331                        response.response,
 5332                        project.clone(),
 5333                        buffer.clone(),
 5334                        cx.clone(),
 5335                    )
 5336                }))
 5337                .await;
 5338
 5339                Ok(Some(
 5340                    actions
 5341                        .into_iter()
 5342                        .collect::<Result<Vec<Vec<_>>>>()?
 5343                        .into_iter()
 5344                        .flatten()
 5345                        .dedup()
 5346                        .collect(),
 5347                ))
 5348            })
 5349        } else {
 5350            let declarations_task = self.request_multiple_lsp_locally(
 5351                buffer,
 5352                Some(position),
 5353                GetDeclarations { position },
 5354                cx,
 5355            );
 5356            cx.background_spawn(async move {
 5357                Ok(Some(
 5358                    declarations_task
 5359                        .await
 5360                        .into_iter()
 5361                        .flat_map(|(_, declarations)| declarations)
 5362                        .dedup()
 5363                        .collect(),
 5364                ))
 5365            })
 5366        }
 5367    }
 5368
 5369    pub fn type_definitions(
 5370        &mut self,
 5371        buffer: &Entity<Buffer>,
 5372        position: PointUtf16,
 5373        cx: &mut Context<Self>,
 5374    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5375        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5376            let request = GetTypeDefinitions { position };
 5377            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5378                return Task::ready(Ok(None));
 5379            }
 5380            let request_task = upstream_client.request_lsp(
 5381                project_id,
 5382                LSP_REQUEST_TIMEOUT,
 5383                cx.background_executor().clone(),
 5384                request.to_proto(project_id, buffer.read(cx)),
 5385            );
 5386            let buffer = buffer.clone();
 5387            cx.spawn(async move |weak_project, cx| {
 5388                let Some(project) = weak_project.upgrade() else {
 5389                    return Ok(None);
 5390                };
 5391                let Some(responses) = request_task.await? else {
 5392                    return Ok(None);
 5393                };
 5394                let actions = join_all(responses.payload.into_iter().map(|response| {
 5395                    GetTypeDefinitions { position }.response_from_proto(
 5396                        response.response,
 5397                        project.clone(),
 5398                        buffer.clone(),
 5399                        cx.clone(),
 5400                    )
 5401                }))
 5402                .await;
 5403
 5404                Ok(Some(
 5405                    actions
 5406                        .into_iter()
 5407                        .collect::<Result<Vec<Vec<_>>>>()?
 5408                        .into_iter()
 5409                        .flatten()
 5410                        .dedup()
 5411                        .collect(),
 5412                ))
 5413            })
 5414        } else {
 5415            let type_definitions_task = self.request_multiple_lsp_locally(
 5416                buffer,
 5417                Some(position),
 5418                GetTypeDefinitions { position },
 5419                cx,
 5420            );
 5421            cx.background_spawn(async move {
 5422                Ok(Some(
 5423                    type_definitions_task
 5424                        .await
 5425                        .into_iter()
 5426                        .flat_map(|(_, type_definitions)| type_definitions)
 5427                        .dedup()
 5428                        .collect(),
 5429                ))
 5430            })
 5431        }
 5432    }
 5433
 5434    pub fn implementations(
 5435        &mut self,
 5436        buffer: &Entity<Buffer>,
 5437        position: PointUtf16,
 5438        cx: &mut Context<Self>,
 5439    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5440        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5441            let request = GetImplementations { position };
 5442            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5443                return Task::ready(Ok(None));
 5444            }
 5445            let request_task = upstream_client.request_lsp(
 5446                project_id,
 5447                LSP_REQUEST_TIMEOUT,
 5448                cx.background_executor().clone(),
 5449                request.to_proto(project_id, buffer.read(cx)),
 5450            );
 5451            let buffer = buffer.clone();
 5452            cx.spawn(async move |weak_project, cx| {
 5453                let Some(project) = weak_project.upgrade() else {
 5454                    return Ok(None);
 5455                };
 5456                let Some(responses) = request_task.await? else {
 5457                    return Ok(None);
 5458                };
 5459                let actions = join_all(responses.payload.into_iter().map(|response| {
 5460                    GetImplementations { position }.response_from_proto(
 5461                        response.response,
 5462                        project.clone(),
 5463                        buffer.clone(),
 5464                        cx.clone(),
 5465                    )
 5466                }))
 5467                .await;
 5468
 5469                Ok(Some(
 5470                    actions
 5471                        .into_iter()
 5472                        .collect::<Result<Vec<Vec<_>>>>()?
 5473                        .into_iter()
 5474                        .flatten()
 5475                        .dedup()
 5476                        .collect(),
 5477                ))
 5478            })
 5479        } else {
 5480            let implementations_task = self.request_multiple_lsp_locally(
 5481                buffer,
 5482                Some(position),
 5483                GetImplementations { position },
 5484                cx,
 5485            );
 5486            cx.background_spawn(async move {
 5487                Ok(Some(
 5488                    implementations_task
 5489                        .await
 5490                        .into_iter()
 5491                        .flat_map(|(_, implementations)| implementations)
 5492                        .dedup()
 5493                        .collect(),
 5494                ))
 5495            })
 5496        }
 5497    }
 5498
 5499    pub fn references(
 5500        &mut self,
 5501        buffer: &Entity<Buffer>,
 5502        position: PointUtf16,
 5503        cx: &mut Context<Self>,
 5504    ) -> Task<Result<Option<Vec<Location>>>> {
 5505        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5506            let request = GetReferences { position };
 5507            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5508                return Task::ready(Ok(None));
 5509            }
 5510
 5511            let request_task = upstream_client.request_lsp(
 5512                project_id,
 5513                LSP_REQUEST_TIMEOUT,
 5514                cx.background_executor().clone(),
 5515                request.to_proto(project_id, buffer.read(cx)),
 5516            );
 5517            let buffer = buffer.clone();
 5518            cx.spawn(async move |weak_project, cx| {
 5519                let Some(project) = weak_project.upgrade() else {
 5520                    return Ok(None);
 5521                };
 5522                let Some(responses) = request_task.await? else {
 5523                    return Ok(None);
 5524                };
 5525
 5526                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5527                    GetReferences { position }.response_from_proto(
 5528                        lsp_response.response,
 5529                        project.clone(),
 5530                        buffer.clone(),
 5531                        cx.clone(),
 5532                    )
 5533                }))
 5534                .await
 5535                .into_iter()
 5536                .collect::<Result<Vec<Vec<_>>>>()?
 5537                .into_iter()
 5538                .flatten()
 5539                .dedup()
 5540                .collect();
 5541                Ok(Some(locations))
 5542            })
 5543        } else {
 5544            let references_task = self.request_multiple_lsp_locally(
 5545                buffer,
 5546                Some(position),
 5547                GetReferences { position },
 5548                cx,
 5549            );
 5550            cx.background_spawn(async move {
 5551                Ok(Some(
 5552                    references_task
 5553                        .await
 5554                        .into_iter()
 5555                        .flat_map(|(_, references)| references)
 5556                        .dedup()
 5557                        .collect(),
 5558                ))
 5559            })
 5560        }
 5561    }
 5562
 5563    pub fn code_actions(
 5564        &mut self,
 5565        buffer: &Entity<Buffer>,
 5566        range: Range<Anchor>,
 5567        kinds: Option<Vec<CodeActionKind>>,
 5568        cx: &mut Context<Self>,
 5569    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5570        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5571            let request = GetCodeActions {
 5572                range: range.clone(),
 5573                kinds: kinds.clone(),
 5574            };
 5575            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5576                return Task::ready(Ok(None));
 5577            }
 5578            let request_task = upstream_client.request_lsp(
 5579                project_id,
 5580                LSP_REQUEST_TIMEOUT,
 5581                cx.background_executor().clone(),
 5582                request.to_proto(project_id, buffer.read(cx)),
 5583            );
 5584            let buffer = buffer.clone();
 5585            cx.spawn(async move |weak_project, cx| {
 5586                let Some(project) = weak_project.upgrade() else {
 5587                    return Ok(None);
 5588                };
 5589                let Some(responses) = request_task.await? else {
 5590                    return Ok(None);
 5591                };
 5592                let actions = join_all(responses.payload.into_iter().map(|response| {
 5593                    GetCodeActions {
 5594                        range: range.clone(),
 5595                        kinds: kinds.clone(),
 5596                    }
 5597                    .response_from_proto(
 5598                        response.response,
 5599                        project.clone(),
 5600                        buffer.clone(),
 5601                        cx.clone(),
 5602                    )
 5603                }))
 5604                .await;
 5605
 5606                Ok(Some(
 5607                    actions
 5608                        .into_iter()
 5609                        .collect::<Result<Vec<Vec<_>>>>()?
 5610                        .into_iter()
 5611                        .flatten()
 5612                        .collect(),
 5613                ))
 5614            })
 5615        } else {
 5616            let all_actions_task = self.request_multiple_lsp_locally(
 5617                buffer,
 5618                Some(range.start),
 5619                GetCodeActions { range, kinds },
 5620                cx,
 5621            );
 5622            cx.background_spawn(async move {
 5623                Ok(Some(
 5624                    all_actions_task
 5625                        .await
 5626                        .into_iter()
 5627                        .flat_map(|(_, actions)| actions)
 5628                        .collect(),
 5629                ))
 5630            })
 5631        }
 5632    }
 5633
 5634    pub fn code_lens_actions(
 5635        &mut self,
 5636        buffer: &Entity<Buffer>,
 5637        cx: &mut Context<Self>,
 5638    ) -> CodeLensTask {
 5639        let version_queried_for = buffer.read(cx).version();
 5640        let buffer_id = buffer.read(cx).remote_id();
 5641
 5642        if let Some(cached_data) = self.lsp_code_lens.get(&buffer_id)
 5643            && !version_queried_for.changed_since(&cached_data.lens_for_version)
 5644        {
 5645            let has_different_servers = self.as_local().is_some_and(|local| {
 5646                local
 5647                    .buffers_opened_in_servers
 5648                    .get(&buffer_id)
 5649                    .cloned()
 5650                    .unwrap_or_default()
 5651                    != cached_data.lens.keys().copied().collect()
 5652            });
 5653            if !has_different_servers {
 5654                return Task::ready(Ok(Some(
 5655                    cached_data.lens.values().flatten().cloned().collect(),
 5656                )))
 5657                .shared();
 5658            }
 5659        }
 5660
 5661        let lsp_data = self.lsp_code_lens.entry(buffer_id).or_default();
 5662        if let Some((updating_for, running_update)) = &lsp_data.update
 5663            && !version_queried_for.changed_since(updating_for)
 5664        {
 5665            return running_update.clone();
 5666        }
 5667        let buffer = buffer.clone();
 5668        let query_version_queried_for = version_queried_for.clone();
 5669        let new_task = cx
 5670            .spawn(async move |lsp_store, cx| {
 5671                cx.background_executor()
 5672                    .timer(Duration::from_millis(30))
 5673                    .await;
 5674                let fetched_lens = lsp_store
 5675                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5676                    .map_err(Arc::new)?
 5677                    .await
 5678                    .context("fetching code lens")
 5679                    .map_err(Arc::new);
 5680                let fetched_lens = match fetched_lens {
 5681                    Ok(fetched_lens) => fetched_lens,
 5682                    Err(e) => {
 5683                        lsp_store
 5684                            .update(cx, |lsp_store, _| {
 5685                                lsp_store.lsp_code_lens.entry(buffer_id).or_default().update = None;
 5686                            })
 5687                            .ok();
 5688                        return Err(e);
 5689                    }
 5690                };
 5691
 5692                lsp_store
 5693                    .update(cx, |lsp_store, _| {
 5694                        let lsp_data = lsp_store.lsp_code_lens.entry(buffer_id).or_default();
 5695                        if let Some(fetched_lens) = fetched_lens {
 5696                            if lsp_data.lens_for_version == query_version_queried_for {
 5697                                lsp_data.lens.extend(fetched_lens);
 5698                            } else if !lsp_data
 5699                                .lens_for_version
 5700                                .changed_since(&query_version_queried_for)
 5701                            {
 5702                                lsp_data.lens_for_version = query_version_queried_for;
 5703                                lsp_data.lens = fetched_lens;
 5704                            }
 5705                        }
 5706                        lsp_data.update = None;
 5707                        Some(lsp_data.lens.values().flatten().cloned().collect())
 5708                    })
 5709                    .map_err(Arc::new)
 5710            })
 5711            .shared();
 5712        lsp_data.update = Some((version_queried_for, new_task.clone()));
 5713        new_task
 5714    }
 5715
 5716    fn fetch_code_lens(
 5717        &mut self,
 5718        buffer: &Entity<Buffer>,
 5719        cx: &mut Context<Self>,
 5720    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5721        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5722            let request = GetCodeLens;
 5723            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5724                return Task::ready(Ok(None));
 5725            }
 5726            let request_task = upstream_client.request_lsp(
 5727                project_id,
 5728                LSP_REQUEST_TIMEOUT,
 5729                cx.background_executor().clone(),
 5730                request.to_proto(project_id, buffer.read(cx)),
 5731            );
 5732            let buffer = buffer.clone();
 5733            cx.spawn(async move |weak_lsp_store, cx| {
 5734                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5735                    return Ok(None);
 5736                };
 5737                let Some(responses) = request_task.await? else {
 5738                    return Ok(None);
 5739                };
 5740
 5741                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5742                    let lsp_store = lsp_store.clone();
 5743                    let buffer = buffer.clone();
 5744                    let cx = cx.clone();
 5745                    async move {
 5746                        (
 5747                            LanguageServerId::from_proto(response.server_id),
 5748                            GetCodeLens
 5749                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5750                                .await,
 5751                        )
 5752                    }
 5753                }))
 5754                .await;
 5755
 5756                let mut has_errors = false;
 5757                let code_lens_actions = code_lens_actions
 5758                    .into_iter()
 5759                    .filter_map(|(server_id, code_lens)| match code_lens {
 5760                        Ok(code_lens) => Some((server_id, code_lens)),
 5761                        Err(e) => {
 5762                            has_errors = true;
 5763                            log::error!("{e:#}");
 5764                            None
 5765                        }
 5766                    })
 5767                    .collect::<HashMap<_, _>>();
 5768                anyhow::ensure!(
 5769                    !has_errors || !code_lens_actions.is_empty(),
 5770                    "Failed to fetch code lens"
 5771                );
 5772                Ok(Some(code_lens_actions))
 5773            })
 5774        } else {
 5775            let code_lens_actions_task =
 5776                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5777            cx.background_spawn(async move {
 5778                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5779            })
 5780        }
 5781    }
 5782
 5783    #[inline(never)]
 5784    pub fn completions(
 5785        &self,
 5786        buffer: &Entity<Buffer>,
 5787        position: PointUtf16,
 5788        context: CompletionContext,
 5789        cx: &mut Context<Self>,
 5790    ) -> Task<Result<Vec<CompletionResponse>>> {
 5791        let language_registry = self.languages.clone();
 5792
 5793        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5794            let request = GetCompletions { position, context };
 5795            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5796                return Task::ready(Ok(Vec::new()));
 5797            }
 5798            let task = self.send_lsp_proto_request(
 5799                buffer.clone(),
 5800                upstream_client,
 5801                project_id,
 5802                request,
 5803                cx,
 5804            );
 5805            let language = buffer.read(cx).language().cloned();
 5806
 5807            // In the future, we should provide project guests with the names of LSP adapters,
 5808            // so that they can use the correct LSP adapter when computing labels. For now,
 5809            // guests just use the first LSP adapter associated with the buffer's language.
 5810            let lsp_adapter = language.as_ref().and_then(|language| {
 5811                language_registry
 5812                    .lsp_adapters(&language.name())
 5813                    .first()
 5814                    .cloned()
 5815            });
 5816
 5817            cx.foreground_executor().spawn(async move {
 5818                let completion_response = task.await?;
 5819                let completions = populate_labels_for_completions(
 5820                    completion_response.completions,
 5821                    language,
 5822                    lsp_adapter,
 5823                )
 5824                .await;
 5825                Ok(vec![CompletionResponse {
 5826                    completions,
 5827                    display_options: CompletionDisplayOptions::default(),
 5828                    is_incomplete: completion_response.is_incomplete,
 5829                }])
 5830            })
 5831        } else if let Some(local) = self.as_local() {
 5832            let snapshot = buffer.read(cx).snapshot();
 5833            let offset = position.to_offset(&snapshot);
 5834            let scope = snapshot.language_scope_at(offset);
 5835            let language = snapshot.language().cloned();
 5836            let completion_settings = language_settings(
 5837                language.as_ref().map(|language| language.name()),
 5838                buffer.read(cx).file(),
 5839                cx,
 5840            )
 5841            .completions;
 5842            if !completion_settings.lsp {
 5843                return Task::ready(Ok(Vec::new()));
 5844            }
 5845
 5846            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5847                local
 5848                    .language_servers_for_buffer(buffer, cx)
 5849                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5850                    .filter(|(adapter, _)| {
 5851                        scope
 5852                            .as_ref()
 5853                            .map(|scope| scope.language_allowed(&adapter.name))
 5854                            .unwrap_or(true)
 5855                    })
 5856                    .map(|(_, server)| server.server_id())
 5857                    .collect()
 5858            });
 5859
 5860            let buffer = buffer.clone();
 5861            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5862            let lsp_timeout = if lsp_timeout > 0 {
 5863                Some(Duration::from_millis(lsp_timeout))
 5864            } else {
 5865                None
 5866            };
 5867            cx.spawn(async move |this,  cx| {
 5868                let mut tasks = Vec::with_capacity(server_ids.len());
 5869                this.update(cx, |lsp_store, cx| {
 5870                    for server_id in server_ids {
 5871                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5872                        let lsp_timeout = lsp_timeout
 5873                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5874                        let mut timeout = cx.background_spawn(async move {
 5875                            match lsp_timeout {
 5876                                Some(lsp_timeout) => {
 5877                                    lsp_timeout.await;
 5878                                    true
 5879                                },
 5880                                None => false,
 5881                            }
 5882                        }).fuse();
 5883                        let mut lsp_request = lsp_store.request_lsp(
 5884                            buffer.clone(),
 5885                            LanguageServerToQuery::Other(server_id),
 5886                            GetCompletions {
 5887                                position,
 5888                                context: context.clone(),
 5889                            },
 5890                            cx,
 5891                        ).fuse();
 5892                        let new_task = cx.background_spawn(async move {
 5893                            select_biased! {
 5894                                response = lsp_request => anyhow::Ok(Some(response?)),
 5895                                timeout_happened = timeout => {
 5896                                    if timeout_happened {
 5897                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5898                                        Ok(None)
 5899                                    } else {
 5900                                        let completions = lsp_request.await?;
 5901                                        Ok(Some(completions))
 5902                                    }
 5903                                },
 5904                            }
 5905                        });
 5906                        tasks.push((lsp_adapter, new_task));
 5907                    }
 5908                })?;
 5909
 5910                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5911                    let completion_response = task.await.ok()??;
 5912                    let completions = populate_labels_for_completions(
 5913                            completion_response.completions,
 5914                            language.clone(),
 5915                            lsp_adapter,
 5916                        )
 5917                        .await;
 5918                    Some(CompletionResponse {
 5919                        completions,
 5920                        display_options: CompletionDisplayOptions::default(),
 5921                        is_incomplete: completion_response.is_incomplete,
 5922                    })
 5923                });
 5924
 5925                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 5926
 5927                Ok(responses.into_iter().flatten().collect())
 5928            })
 5929        } else {
 5930            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5931        }
 5932    }
 5933
 5934    pub fn resolve_completions(
 5935        &self,
 5936        buffer: Entity<Buffer>,
 5937        completion_indices: Vec<usize>,
 5938        completions: Rc<RefCell<Box<[Completion]>>>,
 5939        cx: &mut Context<Self>,
 5940    ) -> Task<Result<bool>> {
 5941        let client = self.upstream_client();
 5942        let buffer_id = buffer.read(cx).remote_id();
 5943        let buffer_snapshot = buffer.read(cx).snapshot();
 5944
 5945        if !self.check_if_capable_for_proto_request(
 5946            &buffer,
 5947            GetCompletions::can_resolve_completions,
 5948            cx,
 5949        ) {
 5950            return Task::ready(Ok(false));
 5951        }
 5952        cx.spawn(async move |lsp_store, cx| {
 5953            let mut did_resolve = false;
 5954            if let Some((client, project_id)) = client {
 5955                for completion_index in completion_indices {
 5956                    let server_id = {
 5957                        let completion = &completions.borrow()[completion_index];
 5958                        completion.source.server_id()
 5959                    };
 5960                    if let Some(server_id) = server_id {
 5961                        if Self::resolve_completion_remote(
 5962                            project_id,
 5963                            server_id,
 5964                            buffer_id,
 5965                            completions.clone(),
 5966                            completion_index,
 5967                            client.clone(),
 5968                        )
 5969                        .await
 5970                        .log_err()
 5971                        .is_some()
 5972                        {
 5973                            did_resolve = true;
 5974                        }
 5975                    } else {
 5976                        resolve_word_completion(
 5977                            &buffer_snapshot,
 5978                            &mut completions.borrow_mut()[completion_index],
 5979                        );
 5980                    }
 5981                }
 5982            } else {
 5983                for completion_index in completion_indices {
 5984                    let server_id = {
 5985                        let completion = &completions.borrow()[completion_index];
 5986                        completion.source.server_id()
 5987                    };
 5988                    if let Some(server_id) = server_id {
 5989                        let server_and_adapter = lsp_store
 5990                            .read_with(cx, |lsp_store, _| {
 5991                                let server = lsp_store.language_server_for_id(server_id)?;
 5992                                let adapter =
 5993                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 5994                                Some((server, adapter))
 5995                            })
 5996                            .ok()
 5997                            .flatten();
 5998                        let Some((server, adapter)) = server_and_adapter else {
 5999                            continue;
 6000                        };
 6001
 6002                        let resolved = Self::resolve_completion_local(
 6003                            server,
 6004                            completions.clone(),
 6005                            completion_index,
 6006                        )
 6007                        .await
 6008                        .log_err()
 6009                        .is_some();
 6010                        if resolved {
 6011                            Self::regenerate_completion_labels(
 6012                                adapter,
 6013                                &buffer_snapshot,
 6014                                completions.clone(),
 6015                                completion_index,
 6016                            )
 6017                            .await
 6018                            .log_err();
 6019                            did_resolve = true;
 6020                        }
 6021                    } else {
 6022                        resolve_word_completion(
 6023                            &buffer_snapshot,
 6024                            &mut completions.borrow_mut()[completion_index],
 6025                        );
 6026                    }
 6027                }
 6028            }
 6029
 6030            Ok(did_resolve)
 6031        })
 6032    }
 6033
 6034    async fn resolve_completion_local(
 6035        server: Arc<lsp::LanguageServer>,
 6036        completions: Rc<RefCell<Box<[Completion]>>>,
 6037        completion_index: usize,
 6038    ) -> Result<()> {
 6039        let server_id = server.server_id();
 6040        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6041            return Ok(());
 6042        }
 6043
 6044        let request = {
 6045            let completion = &completions.borrow()[completion_index];
 6046            match &completion.source {
 6047                CompletionSource::Lsp {
 6048                    lsp_completion,
 6049                    resolved,
 6050                    server_id: completion_server_id,
 6051                    ..
 6052                } => {
 6053                    if *resolved {
 6054                        return Ok(());
 6055                    }
 6056                    anyhow::ensure!(
 6057                        server_id == *completion_server_id,
 6058                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6059                    );
 6060                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6061                }
 6062                CompletionSource::BufferWord { .. }
 6063                | CompletionSource::Dap { .. }
 6064                | CompletionSource::Custom => {
 6065                    return Ok(());
 6066                }
 6067            }
 6068        };
 6069        let resolved_completion = request
 6070            .await
 6071            .into_response()
 6072            .context("resolve completion")?;
 6073
 6074        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6075        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6076
 6077        let mut completions = completions.borrow_mut();
 6078        let completion = &mut completions[completion_index];
 6079        if let CompletionSource::Lsp {
 6080            lsp_completion,
 6081            resolved,
 6082            server_id: completion_server_id,
 6083            ..
 6084        } = &mut completion.source
 6085        {
 6086            if *resolved {
 6087                return Ok(());
 6088            }
 6089            anyhow::ensure!(
 6090                server_id == *completion_server_id,
 6091                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6092            );
 6093            *lsp_completion = Box::new(resolved_completion);
 6094            *resolved = true;
 6095        }
 6096        Ok(())
 6097    }
 6098
 6099    async fn regenerate_completion_labels(
 6100        adapter: Arc<CachedLspAdapter>,
 6101        snapshot: &BufferSnapshot,
 6102        completions: Rc<RefCell<Box<[Completion]>>>,
 6103        completion_index: usize,
 6104    ) -> Result<()> {
 6105        let completion_item = completions.borrow()[completion_index]
 6106            .source
 6107            .lsp_completion(true)
 6108            .map(Cow::into_owned);
 6109        if let Some(lsp_documentation) = completion_item
 6110            .as_ref()
 6111            .and_then(|completion_item| completion_item.documentation.clone())
 6112        {
 6113            let mut completions = completions.borrow_mut();
 6114            let completion = &mut completions[completion_index];
 6115            completion.documentation = Some(lsp_documentation.into());
 6116        } else {
 6117            let mut completions = completions.borrow_mut();
 6118            let completion = &mut completions[completion_index];
 6119            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6120        }
 6121
 6122        let mut new_label = match completion_item {
 6123            Some(completion_item) => {
 6124                // 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
 6125                // So we have to update the label here anyway...
 6126                let language = snapshot.language();
 6127                match language {
 6128                    Some(language) => {
 6129                        adapter
 6130                            .labels_for_completions(
 6131                                std::slice::from_ref(&completion_item),
 6132                                language,
 6133                            )
 6134                            .await?
 6135                    }
 6136                    None => Vec::new(),
 6137                }
 6138                .pop()
 6139                .flatten()
 6140                .unwrap_or_else(|| {
 6141                    CodeLabel::fallback_for_completion(
 6142                        &completion_item,
 6143                        language.map(|language| language.as_ref()),
 6144                    )
 6145                })
 6146            }
 6147            None => CodeLabel::plain(
 6148                completions.borrow()[completion_index].new_text.clone(),
 6149                None,
 6150            ),
 6151        };
 6152        ensure_uniform_list_compatible_label(&mut new_label);
 6153
 6154        let mut completions = completions.borrow_mut();
 6155        let completion = &mut completions[completion_index];
 6156        if completion.label.filter_text() == new_label.filter_text() {
 6157            completion.label = new_label;
 6158        } else {
 6159            log::error!(
 6160                "Resolved completion changed display label from {} to {}. \
 6161                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6162                completion.label.text(),
 6163                new_label.text(),
 6164                completion.label.filter_text(),
 6165                new_label.filter_text()
 6166            );
 6167        }
 6168
 6169        Ok(())
 6170    }
 6171
 6172    async fn resolve_completion_remote(
 6173        project_id: u64,
 6174        server_id: LanguageServerId,
 6175        buffer_id: BufferId,
 6176        completions: Rc<RefCell<Box<[Completion]>>>,
 6177        completion_index: usize,
 6178        client: AnyProtoClient,
 6179    ) -> Result<()> {
 6180        let lsp_completion = {
 6181            let completion = &completions.borrow()[completion_index];
 6182            match &completion.source {
 6183                CompletionSource::Lsp {
 6184                    lsp_completion,
 6185                    resolved,
 6186                    server_id: completion_server_id,
 6187                    ..
 6188                } => {
 6189                    anyhow::ensure!(
 6190                        server_id == *completion_server_id,
 6191                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6192                    );
 6193                    if *resolved {
 6194                        return Ok(());
 6195                    }
 6196                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6197                }
 6198                CompletionSource::Custom
 6199                | CompletionSource::Dap { .. }
 6200                | CompletionSource::BufferWord { .. } => {
 6201                    return Ok(());
 6202                }
 6203            }
 6204        };
 6205        let request = proto::ResolveCompletionDocumentation {
 6206            project_id,
 6207            language_server_id: server_id.0 as u64,
 6208            lsp_completion,
 6209            buffer_id: buffer_id.into(),
 6210        };
 6211
 6212        let response = client
 6213            .request(request)
 6214            .await
 6215            .context("completion documentation resolve proto request")?;
 6216        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6217
 6218        let documentation = if response.documentation.is_empty() {
 6219            CompletionDocumentation::Undocumented
 6220        } else if response.documentation_is_markdown {
 6221            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6222        } else if response.documentation.lines().count() <= 1 {
 6223            CompletionDocumentation::SingleLine(response.documentation.into())
 6224        } else {
 6225            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6226        };
 6227
 6228        let mut completions = completions.borrow_mut();
 6229        let completion = &mut completions[completion_index];
 6230        completion.documentation = Some(documentation);
 6231        if let CompletionSource::Lsp {
 6232            insert_range,
 6233            lsp_completion,
 6234            resolved,
 6235            server_id: completion_server_id,
 6236            lsp_defaults: _,
 6237        } = &mut completion.source
 6238        {
 6239            let completion_insert_range = response
 6240                .old_insert_start
 6241                .and_then(deserialize_anchor)
 6242                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6243            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6244
 6245            if *resolved {
 6246                return Ok(());
 6247            }
 6248            anyhow::ensure!(
 6249                server_id == *completion_server_id,
 6250                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6251            );
 6252            *lsp_completion = Box::new(resolved_lsp_completion);
 6253            *resolved = true;
 6254        }
 6255
 6256        let replace_range = response
 6257            .old_replace_start
 6258            .and_then(deserialize_anchor)
 6259            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6260        if let Some((old_replace_start, old_replace_end)) = replace_range
 6261            && !response.new_text.is_empty()
 6262        {
 6263            completion.new_text = response.new_text;
 6264            completion.replace_range = old_replace_start..old_replace_end;
 6265        }
 6266
 6267        Ok(())
 6268    }
 6269
 6270    pub fn apply_additional_edits_for_completion(
 6271        &self,
 6272        buffer_handle: Entity<Buffer>,
 6273        completions: Rc<RefCell<Box<[Completion]>>>,
 6274        completion_index: usize,
 6275        push_to_history: bool,
 6276        cx: &mut Context<Self>,
 6277    ) -> Task<Result<Option<Transaction>>> {
 6278        if let Some((client, project_id)) = self.upstream_client() {
 6279            let buffer = buffer_handle.read(cx);
 6280            let buffer_id = buffer.remote_id();
 6281            cx.spawn(async move |_, cx| {
 6282                let request = {
 6283                    let completion = completions.borrow()[completion_index].clone();
 6284                    proto::ApplyCompletionAdditionalEdits {
 6285                        project_id,
 6286                        buffer_id: buffer_id.into(),
 6287                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6288                            replace_range: completion.replace_range,
 6289                            new_text: completion.new_text,
 6290                            source: completion.source,
 6291                        })),
 6292                    }
 6293                };
 6294
 6295                if let Some(transaction) = client.request(request).await?.transaction {
 6296                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6297                    buffer_handle
 6298                        .update(cx, |buffer, _| {
 6299                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6300                        })?
 6301                        .await?;
 6302                    if push_to_history {
 6303                        buffer_handle.update(cx, |buffer, _| {
 6304                            buffer.push_transaction(transaction.clone(), Instant::now());
 6305                            buffer.finalize_last_transaction();
 6306                        })?;
 6307                    }
 6308                    Ok(Some(transaction))
 6309                } else {
 6310                    Ok(None)
 6311                }
 6312            })
 6313        } else {
 6314            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6315                let completion = &completions.borrow()[completion_index];
 6316                let server_id = completion.source.server_id()?;
 6317                Some(
 6318                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6319                        .1
 6320                        .clone(),
 6321                )
 6322            }) else {
 6323                return Task::ready(Ok(None));
 6324            };
 6325
 6326            cx.spawn(async move |this, cx| {
 6327                Self::resolve_completion_local(
 6328                    server.clone(),
 6329                    completions.clone(),
 6330                    completion_index,
 6331                )
 6332                .await
 6333                .context("resolving completion")?;
 6334                let completion = completions.borrow()[completion_index].clone();
 6335                let additional_text_edits = completion
 6336                    .source
 6337                    .lsp_completion(true)
 6338                    .as_ref()
 6339                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6340                if let Some(edits) = additional_text_edits {
 6341                    let edits = this
 6342                        .update(cx, |this, cx| {
 6343                            this.as_local_mut().unwrap().edits_from_lsp(
 6344                                &buffer_handle,
 6345                                edits,
 6346                                server.server_id(),
 6347                                None,
 6348                                cx,
 6349                            )
 6350                        })?
 6351                        .await?;
 6352
 6353                    buffer_handle.update(cx, |buffer, cx| {
 6354                        buffer.finalize_last_transaction();
 6355                        buffer.start_transaction();
 6356
 6357                        for (range, text) in edits {
 6358                            let primary = &completion.replace_range;
 6359
 6360                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6361                            // and the primary completion is just an insertion (empty range), then this is likely
 6362                            // an auto-import scenario and should not be considered overlapping
 6363                            // https://github.com/zed-industries/zed/issues/26136
 6364                            let is_file_start_auto_import = {
 6365                                let snapshot = buffer.snapshot();
 6366                                let primary_start_point = primary.start.to_point(&snapshot);
 6367                                let range_start_point = range.start.to_point(&snapshot);
 6368
 6369                                let result = primary_start_point.row == 0
 6370                                    && primary_start_point.column == 0
 6371                                    && range_start_point.row == 0
 6372                                    && range_start_point.column == 0;
 6373
 6374                                result
 6375                            };
 6376
 6377                            let has_overlap = if is_file_start_auto_import {
 6378                                false
 6379                            } else {
 6380                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6381                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6382                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6383                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6384                                let result = start_within || end_within;
 6385                                result
 6386                            };
 6387
 6388                            //Skip additional edits which overlap with the primary completion edit
 6389                            //https://github.com/zed-industries/zed/pull/1871
 6390                            if !has_overlap {
 6391                                buffer.edit([(range, text)], None, cx);
 6392                            }
 6393                        }
 6394
 6395                        let transaction = if buffer.end_transaction(cx).is_some() {
 6396                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6397                            if !push_to_history {
 6398                                buffer.forget_transaction(transaction.id);
 6399                            }
 6400                            Some(transaction)
 6401                        } else {
 6402                            None
 6403                        };
 6404                        Ok(transaction)
 6405                    })?
 6406                } else {
 6407                    Ok(None)
 6408                }
 6409            })
 6410        }
 6411    }
 6412
 6413    pub fn pull_diagnostics(
 6414        &mut self,
 6415        buffer: Entity<Buffer>,
 6416        cx: &mut Context<Self>,
 6417    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6418        let buffer_id = buffer.read(cx).remote_id();
 6419
 6420        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6421            let request = GetDocumentDiagnostics {
 6422                previous_result_id: None,
 6423            };
 6424            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6425                return Task::ready(Ok(None));
 6426            }
 6427            let request_task = client.request_lsp(
 6428                upstream_project_id,
 6429                LSP_REQUEST_TIMEOUT,
 6430                cx.background_executor().clone(),
 6431                request.to_proto(upstream_project_id, buffer.read(cx)),
 6432            );
 6433            cx.background_spawn(async move {
 6434                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6435                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6436                // Do not attempt to further process the dummy responses here.
 6437                let _response = request_task.await?;
 6438                Ok(None)
 6439            })
 6440        } else {
 6441            let server_ids = buffer.update(cx, |buffer, cx| {
 6442                self.language_servers_for_local_buffer(buffer, cx)
 6443                    .map(|(_, server)| server.server_id())
 6444                    .collect::<Vec<_>>()
 6445            });
 6446            let pull_diagnostics = server_ids
 6447                .into_iter()
 6448                .map(|server_id| {
 6449                    let result_id = self.result_id(server_id, buffer_id, cx);
 6450                    self.request_lsp(
 6451                        buffer.clone(),
 6452                        LanguageServerToQuery::Other(server_id),
 6453                        GetDocumentDiagnostics {
 6454                            previous_result_id: result_id,
 6455                        },
 6456                        cx,
 6457                    )
 6458                })
 6459                .collect::<Vec<_>>();
 6460
 6461            cx.background_spawn(async move {
 6462                let mut responses = Vec::new();
 6463                for diagnostics in join_all(pull_diagnostics).await {
 6464                    responses.extend(diagnostics?);
 6465                }
 6466                Ok(Some(responses))
 6467            })
 6468        }
 6469    }
 6470
 6471    pub fn inlay_hints(
 6472        &mut self,
 6473        buffer: Entity<Buffer>,
 6474        range: Range<Anchor>,
 6475        cx: &mut Context<Self>,
 6476    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
 6477        let range_start = range.start;
 6478        let range_end = range.end;
 6479        let buffer_id = buffer.read(cx).remote_id().into();
 6480        let request = InlayHints { range };
 6481
 6482        if let Some((client, project_id)) = self.upstream_client() {
 6483            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6484                return Task::ready(Ok(Vec::new()));
 6485            }
 6486            let proto_request = proto::InlayHints {
 6487                project_id,
 6488                buffer_id,
 6489                start: Some(serialize_anchor(&range_start)),
 6490                end: Some(serialize_anchor(&range_end)),
 6491                version: serialize_version(&buffer.read(cx).version()),
 6492            };
 6493            cx.spawn(async move |project, cx| {
 6494                let response = client
 6495                    .request(proto_request)
 6496                    .await
 6497                    .context("inlay hints proto request")?;
 6498                LspCommand::response_from_proto(
 6499                    request,
 6500                    response,
 6501                    project.upgrade().context("No project")?,
 6502                    buffer.clone(),
 6503                    cx.clone(),
 6504                )
 6505                .await
 6506                .context("inlay hints proto response conversion")
 6507            })
 6508        } else {
 6509            let lsp_request_task = self.request_lsp(
 6510                buffer.clone(),
 6511                LanguageServerToQuery::FirstCapable,
 6512                request,
 6513                cx,
 6514            );
 6515            cx.spawn(async move |_, cx| {
 6516                buffer
 6517                    .update(cx, |buffer, _| {
 6518                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
 6519                    })?
 6520                    .await
 6521                    .context("waiting for inlay hint request range edits")?;
 6522                lsp_request_task.await.context("inlay hints LSP request")
 6523            })
 6524        }
 6525    }
 6526
 6527    pub fn pull_diagnostics_for_buffer(
 6528        &mut self,
 6529        buffer: Entity<Buffer>,
 6530        cx: &mut Context<Self>,
 6531    ) -> Task<anyhow::Result<()>> {
 6532        let diagnostics = self.pull_diagnostics(buffer, cx);
 6533        cx.spawn(async move |lsp_store, cx| {
 6534            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6535                return Ok(());
 6536            };
 6537            lsp_store.update(cx, |lsp_store, cx| {
 6538                if lsp_store.as_local().is_none() {
 6539                    return;
 6540                }
 6541
 6542                let mut unchanged_buffers = HashSet::default();
 6543                let mut changed_buffers = HashSet::default();
 6544                let server_diagnostics_updates = diagnostics
 6545                    .into_iter()
 6546                    .filter_map(|diagnostics_set| match diagnostics_set {
 6547                        LspPullDiagnostics::Response {
 6548                            server_id,
 6549                            uri,
 6550                            diagnostics,
 6551                        } => Some((server_id, uri, diagnostics)),
 6552                        LspPullDiagnostics::Default => None,
 6553                    })
 6554                    .fold(
 6555                        HashMap::default(),
 6556                        |mut acc, (server_id, uri, diagnostics)| {
 6557                            let (result_id, diagnostics) = match diagnostics {
 6558                                PulledDiagnostics::Unchanged { result_id } => {
 6559                                    unchanged_buffers.insert(uri.clone());
 6560                                    (Some(result_id), Vec::new())
 6561                                }
 6562                                PulledDiagnostics::Changed {
 6563                                    result_id,
 6564                                    diagnostics,
 6565                                } => {
 6566                                    changed_buffers.insert(uri.clone());
 6567                                    (result_id, diagnostics)
 6568                                }
 6569                            };
 6570                            let disk_based_sources = Cow::Owned(
 6571                                lsp_store
 6572                                    .language_server_adapter_for_id(server_id)
 6573                                    .as_ref()
 6574                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6575                                    .unwrap_or(&[])
 6576                                    .to_vec(),
 6577                            );
 6578                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6579                                DocumentDiagnosticsUpdate {
 6580                                    server_id,
 6581                                    diagnostics: lsp::PublishDiagnosticsParams {
 6582                                        uri,
 6583                                        diagnostics,
 6584                                        version: None,
 6585                                    },
 6586                                    result_id,
 6587                                    disk_based_sources,
 6588                                },
 6589                            );
 6590                            acc
 6591                        },
 6592                    );
 6593
 6594                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6595                    lsp_store
 6596                        .merge_lsp_diagnostics(
 6597                            DiagnosticSourceKind::Pulled,
 6598                            diagnostic_updates,
 6599                            |buffer, old_diagnostic, cx| {
 6600                                File::from_dyn(buffer.file())
 6601                                    .and_then(|file| {
 6602                                        let abs_path = file.as_local()?.abs_path(cx);
 6603                                        lsp::Uri::from_file_path(abs_path).ok()
 6604                                    })
 6605                                    .is_none_or(|buffer_uri| {
 6606                                        unchanged_buffers.contains(&buffer_uri)
 6607                                            || match old_diagnostic.source_kind {
 6608                                                DiagnosticSourceKind::Pulled => {
 6609                                                    !changed_buffers.contains(&buffer_uri)
 6610                                                }
 6611                                                DiagnosticSourceKind::Other
 6612                                                | DiagnosticSourceKind::Pushed => true,
 6613                                            }
 6614                                    })
 6615                            },
 6616                            cx,
 6617                        )
 6618                        .log_err();
 6619                }
 6620            })
 6621        })
 6622    }
 6623
 6624    pub fn document_colors(
 6625        &mut self,
 6626        fetch_strategy: LspFetchStrategy,
 6627        buffer: Entity<Buffer>,
 6628        cx: &mut Context<Self>,
 6629    ) -> Option<DocumentColorTask> {
 6630        let version_queried_for = buffer.read(cx).version();
 6631        let buffer_id = buffer.read(cx).remote_id();
 6632
 6633        match fetch_strategy {
 6634            LspFetchStrategy::IgnoreCache => {}
 6635            LspFetchStrategy::UseCache {
 6636                known_cache_version,
 6637            } => {
 6638                if let Some(cached_data) = self.lsp_document_colors.get(&buffer_id)
 6639                    && !version_queried_for.changed_since(&cached_data.colors_for_version)
 6640                {
 6641                    let has_different_servers = self.as_local().is_some_and(|local| {
 6642                        local
 6643                            .buffers_opened_in_servers
 6644                            .get(&buffer_id)
 6645                            .cloned()
 6646                            .unwrap_or_default()
 6647                            != cached_data.colors.keys().copied().collect()
 6648                    });
 6649                    if !has_different_servers {
 6650                        if Some(cached_data.cache_version) == known_cache_version {
 6651                            return None;
 6652                        } else {
 6653                            return Some(
 6654                                Task::ready(Ok(DocumentColors {
 6655                                    colors: cached_data
 6656                                        .colors
 6657                                        .values()
 6658                                        .flatten()
 6659                                        .cloned()
 6660                                        .collect(),
 6661                                    cache_version: Some(cached_data.cache_version),
 6662                                }))
 6663                                .shared(),
 6664                            );
 6665                        }
 6666                    }
 6667                }
 6668            }
 6669        }
 6670
 6671        let lsp_data = self.lsp_document_colors.entry(buffer_id).or_default();
 6672        if let Some((updating_for, running_update)) = &lsp_data.colors_update
 6673            && !version_queried_for.changed_since(updating_for)
 6674        {
 6675            return Some(running_update.clone());
 6676        }
 6677        let query_version_queried_for = version_queried_for.clone();
 6678        let new_task = cx
 6679            .spawn(async move |lsp_store, cx| {
 6680                cx.background_executor()
 6681                    .timer(Duration::from_millis(30))
 6682                    .await;
 6683                let fetched_colors = lsp_store
 6684                    .update(cx, |lsp_store, cx| {
 6685                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 6686                    })?
 6687                    .await
 6688                    .context("fetching document colors")
 6689                    .map_err(Arc::new);
 6690                let fetched_colors = match fetched_colors {
 6691                    Ok(fetched_colors) => {
 6692                        if fetch_strategy != LspFetchStrategy::IgnoreCache
 6693                            && Some(true)
 6694                                == buffer
 6695                                    .update(cx, |buffer, _| {
 6696                                        buffer.version() != query_version_queried_for
 6697                                    })
 6698                                    .ok()
 6699                        {
 6700                            return Ok(DocumentColors::default());
 6701                        }
 6702                        fetched_colors
 6703                    }
 6704                    Err(e) => {
 6705                        lsp_store
 6706                            .update(cx, |lsp_store, _| {
 6707                                lsp_store
 6708                                    .lsp_document_colors
 6709                                    .entry(buffer_id)
 6710                                    .or_default()
 6711                                    .colors_update = None;
 6712                            })
 6713                            .ok();
 6714                        return Err(e);
 6715                    }
 6716                };
 6717
 6718                lsp_store
 6719                    .update(cx, |lsp_store, _| {
 6720                        let lsp_data = lsp_store.lsp_document_colors.entry(buffer_id).or_default();
 6721
 6722                        if let Some(fetched_colors) = fetched_colors {
 6723                            if lsp_data.colors_for_version == query_version_queried_for {
 6724                                lsp_data.colors.extend(fetched_colors);
 6725                                lsp_data.cache_version += 1;
 6726                            } else if !lsp_data
 6727                                .colors_for_version
 6728                                .changed_since(&query_version_queried_for)
 6729                            {
 6730                                lsp_data.colors_for_version = query_version_queried_for;
 6731                                lsp_data.colors = fetched_colors;
 6732                                lsp_data.cache_version += 1;
 6733                            }
 6734                        }
 6735                        lsp_data.colors_update = None;
 6736                        let colors = lsp_data
 6737                            .colors
 6738                            .values()
 6739                            .flatten()
 6740                            .cloned()
 6741                            .collect::<HashSet<_>>();
 6742                        DocumentColors {
 6743                            colors,
 6744                            cache_version: Some(lsp_data.cache_version),
 6745                        }
 6746                    })
 6747                    .map_err(Arc::new)
 6748            })
 6749            .shared();
 6750        lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 6751        Some(new_task)
 6752    }
 6753
 6754    fn fetch_document_colors_for_buffer(
 6755        &mut self,
 6756        buffer: &Entity<Buffer>,
 6757        cx: &mut Context<Self>,
 6758    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 6759        if let Some((client, project_id)) = self.upstream_client() {
 6760            let request = GetDocumentColor {};
 6761            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6762                return Task::ready(Ok(None));
 6763            }
 6764
 6765            let request_task = client.request_lsp(
 6766                project_id,
 6767                LSP_REQUEST_TIMEOUT,
 6768                cx.background_executor().clone(),
 6769                request.to_proto(project_id, buffer.read(cx)),
 6770            );
 6771            let buffer = buffer.clone();
 6772            cx.spawn(async move |lsp_store, cx| {
 6773                let Some(project) = lsp_store.upgrade() else {
 6774                    return Ok(None);
 6775                };
 6776                let colors = join_all(
 6777                    request_task
 6778                        .await
 6779                        .log_err()
 6780                        .flatten()
 6781                        .map(|response| response.payload)
 6782                        .unwrap_or_default()
 6783                        .into_iter()
 6784                        .map(|color_response| {
 6785                            let response = request.response_from_proto(
 6786                                color_response.response,
 6787                                project.clone(),
 6788                                buffer.clone(),
 6789                                cx.clone(),
 6790                            );
 6791                            async move {
 6792                                (
 6793                                    LanguageServerId::from_proto(color_response.server_id),
 6794                                    response.await.log_err().unwrap_or_default(),
 6795                                )
 6796                            }
 6797                        }),
 6798                )
 6799                .await
 6800                .into_iter()
 6801                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6802                    acc.entry(server_id)
 6803                        .or_insert_with(HashSet::default)
 6804                        .extend(colors);
 6805                    acc
 6806                });
 6807                Ok(Some(colors))
 6808            })
 6809        } else {
 6810            let document_colors_task =
 6811                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 6812            cx.background_spawn(async move {
 6813                Ok(Some(
 6814                    document_colors_task
 6815                        .await
 6816                        .into_iter()
 6817                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6818                            acc.entry(server_id)
 6819                                .or_insert_with(HashSet::default)
 6820                                .extend(colors);
 6821                            acc
 6822                        })
 6823                        .into_iter()
 6824                        .collect(),
 6825                ))
 6826            })
 6827        }
 6828    }
 6829
 6830    pub fn signature_help<T: ToPointUtf16>(
 6831        &mut self,
 6832        buffer: &Entity<Buffer>,
 6833        position: T,
 6834        cx: &mut Context<Self>,
 6835    ) -> Task<Option<Vec<SignatureHelp>>> {
 6836        let position = position.to_point_utf16(buffer.read(cx));
 6837
 6838        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6839            let request = GetSignatureHelp { position };
 6840            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6841                return Task::ready(None);
 6842            }
 6843            let request_task = client.request_lsp(
 6844                upstream_project_id,
 6845                LSP_REQUEST_TIMEOUT,
 6846                cx.background_executor().clone(),
 6847                request.to_proto(upstream_project_id, buffer.read(cx)),
 6848            );
 6849            let buffer = buffer.clone();
 6850            cx.spawn(async move |weak_project, cx| {
 6851                let project = weak_project.upgrade()?;
 6852                let signatures = join_all(
 6853                    request_task
 6854                        .await
 6855                        .log_err()
 6856                        .flatten()
 6857                        .map(|response| response.payload)
 6858                        .unwrap_or_default()
 6859                        .into_iter()
 6860                        .map(|response| {
 6861                            let response = GetSignatureHelp { position }.response_from_proto(
 6862                                response.response,
 6863                                project.clone(),
 6864                                buffer.clone(),
 6865                                cx.clone(),
 6866                            );
 6867                            async move { response.await.log_err().flatten() }
 6868                        }),
 6869                )
 6870                .await
 6871                .into_iter()
 6872                .flatten()
 6873                .collect();
 6874                Some(signatures)
 6875            })
 6876        } else {
 6877            let all_actions_task = self.request_multiple_lsp_locally(
 6878                buffer,
 6879                Some(position),
 6880                GetSignatureHelp { position },
 6881                cx,
 6882            );
 6883            cx.background_spawn(async move {
 6884                Some(
 6885                    all_actions_task
 6886                        .await
 6887                        .into_iter()
 6888                        .flat_map(|(_, actions)| actions)
 6889                        .collect::<Vec<_>>(),
 6890                )
 6891            })
 6892        }
 6893    }
 6894
 6895    pub fn hover(
 6896        &mut self,
 6897        buffer: &Entity<Buffer>,
 6898        position: PointUtf16,
 6899        cx: &mut Context<Self>,
 6900    ) -> Task<Option<Vec<Hover>>> {
 6901        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6902            let request = GetHover { position };
 6903            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6904                return Task::ready(None);
 6905            }
 6906            let request_task = client.request_lsp(
 6907                upstream_project_id,
 6908                LSP_REQUEST_TIMEOUT,
 6909                cx.background_executor().clone(),
 6910                request.to_proto(upstream_project_id, buffer.read(cx)),
 6911            );
 6912            let buffer = buffer.clone();
 6913            cx.spawn(async move |weak_project, cx| {
 6914                let project = weak_project.upgrade()?;
 6915                let hovers = join_all(
 6916                    request_task
 6917                        .await
 6918                        .log_err()
 6919                        .flatten()
 6920                        .map(|response| response.payload)
 6921                        .unwrap_or_default()
 6922                        .into_iter()
 6923                        .map(|response| {
 6924                            let response = GetHover { position }.response_from_proto(
 6925                                response.response,
 6926                                project.clone(),
 6927                                buffer.clone(),
 6928                                cx.clone(),
 6929                            );
 6930                            async move {
 6931                                response
 6932                                    .await
 6933                                    .log_err()
 6934                                    .flatten()
 6935                                    .and_then(remove_empty_hover_blocks)
 6936                            }
 6937                        }),
 6938                )
 6939                .await
 6940                .into_iter()
 6941                .flatten()
 6942                .collect();
 6943                Some(hovers)
 6944            })
 6945        } else {
 6946            let all_actions_task = self.request_multiple_lsp_locally(
 6947                buffer,
 6948                Some(position),
 6949                GetHover { position },
 6950                cx,
 6951            );
 6952            cx.background_spawn(async move {
 6953                Some(
 6954                    all_actions_task
 6955                        .await
 6956                        .into_iter()
 6957                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 6958                        .collect::<Vec<Hover>>(),
 6959                )
 6960            })
 6961        }
 6962    }
 6963
 6964    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 6965        let language_registry = self.languages.clone();
 6966
 6967        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 6968            let request = upstream_client.request(proto::GetProjectSymbols {
 6969                project_id: *project_id,
 6970                query: query.to_string(),
 6971            });
 6972            cx.foreground_executor().spawn(async move {
 6973                let response = request.await?;
 6974                let mut symbols = Vec::new();
 6975                let core_symbols = response
 6976                    .symbols
 6977                    .into_iter()
 6978                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 6979                    .collect::<Vec<_>>();
 6980                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 6981                    .await;
 6982                Ok(symbols)
 6983            })
 6984        } else if let Some(local) = self.as_local() {
 6985            struct WorkspaceSymbolsResult {
 6986                server_id: LanguageServerId,
 6987                lsp_adapter: Arc<CachedLspAdapter>,
 6988                worktree: WeakEntity<Worktree>,
 6989                worktree_abs_path: Arc<Path>,
 6990                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 6991            }
 6992
 6993            let mut requests = Vec::new();
 6994            let mut requested_servers = BTreeSet::new();
 6995            for (seed, state) in local.language_server_ids.iter() {
 6996                let Some(worktree_handle) = self
 6997                    .worktree_store
 6998                    .read(cx)
 6999                    .worktree_for_id(seed.worktree_id, cx)
 7000                else {
 7001                    continue;
 7002                };
 7003                let worktree = worktree_handle.read(cx);
 7004                if !worktree.is_visible() {
 7005                    continue;
 7006                }
 7007
 7008                if !requested_servers.insert(state.id) {
 7009                    continue;
 7010                }
 7011
 7012                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7013                    Some(LanguageServerState::Running {
 7014                        adapter, server, ..
 7015                    }) => (adapter.clone(), server),
 7016
 7017                    _ => continue,
 7018                };
 7019                let supports_workspace_symbol_request =
 7020                    match server.capabilities().workspace_symbol_provider {
 7021                        Some(OneOf::Left(supported)) => supported,
 7022                        Some(OneOf::Right(_)) => true,
 7023                        None => false,
 7024                    };
 7025                if !supports_workspace_symbol_request {
 7026                    continue;
 7027                }
 7028                let worktree_abs_path = worktree.abs_path().clone();
 7029                let worktree_handle = worktree_handle.clone();
 7030                let server_id = server.server_id();
 7031                requests.push(
 7032                        server
 7033                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7034                                lsp::WorkspaceSymbolParams {
 7035                                    query: query.to_string(),
 7036                                    ..Default::default()
 7037                                },
 7038                            )
 7039                            .map(move |response| {
 7040                                let lsp_symbols = response.into_response()
 7041                                    .context("workspace symbols request")
 7042                                    .log_err()
 7043                                    .flatten()
 7044                                    .map(|symbol_response| match symbol_response {
 7045                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7046                                            flat_responses.into_iter().map(|lsp_symbol| {
 7047                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7048                                            }).collect::<Vec<_>>()
 7049                                        }
 7050                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7051                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7052                                                let location = match lsp_symbol.location {
 7053                                                    OneOf::Left(location) => location,
 7054                                                    OneOf::Right(_) => {
 7055                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7056                                                        return None
 7057                                                    }
 7058                                                };
 7059                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7060                                            }).collect::<Vec<_>>()
 7061                                        }
 7062                                    }).unwrap_or_default();
 7063
 7064                                WorkspaceSymbolsResult {
 7065                                    server_id,
 7066                                    lsp_adapter,
 7067                                    worktree: worktree_handle.downgrade(),
 7068                                    worktree_abs_path,
 7069                                    lsp_symbols,
 7070                                }
 7071                            }),
 7072                    );
 7073            }
 7074
 7075            cx.spawn(async move |this, cx| {
 7076                let responses = futures::future::join_all(requests).await;
 7077                let this = match this.upgrade() {
 7078                    Some(this) => this,
 7079                    None => return Ok(Vec::new()),
 7080                };
 7081
 7082                let mut symbols = Vec::new();
 7083                for result in responses {
 7084                    let core_symbols = this.update(cx, |this, cx| {
 7085                        result
 7086                            .lsp_symbols
 7087                            .into_iter()
 7088                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7089                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7090                                let source_worktree = result.worktree.upgrade()?;
 7091                                let source_worktree_id = source_worktree.read(cx).id();
 7092
 7093                                let path;
 7094                                let worktree;
 7095                                if let Some((tree, rel_path)) =
 7096                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7097                                {
 7098                                    worktree = tree;
 7099                                    path = rel_path;
 7100                                } else {
 7101                                    worktree = source_worktree;
 7102                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
 7103                                }
 7104
 7105                                let worktree_id = worktree.read(cx).id();
 7106                                let project_path = ProjectPath {
 7107                                    worktree_id,
 7108                                    path: path.into(),
 7109                                };
 7110                                let signature = this.symbol_signature(&project_path);
 7111                                Some(CoreSymbol {
 7112                                    source_language_server_id: result.server_id,
 7113                                    language_server_name: result.lsp_adapter.name.clone(),
 7114                                    source_worktree_id,
 7115                                    path: project_path,
 7116                                    kind: symbol_kind,
 7117                                    name: symbol_name,
 7118                                    range: range_from_lsp(symbol_location.range),
 7119                                    signature,
 7120                                })
 7121                            })
 7122                            .collect()
 7123                    })?;
 7124
 7125                    populate_labels_for_symbols(
 7126                        core_symbols,
 7127                        &language_registry,
 7128                        Some(result.lsp_adapter),
 7129                        &mut symbols,
 7130                    )
 7131                    .await;
 7132                }
 7133
 7134                Ok(symbols)
 7135            })
 7136        } else {
 7137            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7138        }
 7139    }
 7140
 7141    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7142        let mut summary = DiagnosticSummary::default();
 7143        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7144            summary.error_count += path_summary.error_count;
 7145            summary.warning_count += path_summary.warning_count;
 7146        }
 7147        summary
 7148    }
 7149
 7150    /// Returns the diagnostic summary for a specific project path.
 7151    pub fn diagnostic_summary_for_path(
 7152        &self,
 7153        project_path: &ProjectPath,
 7154        _: &App,
 7155    ) -> DiagnosticSummary {
 7156        if let Some(summaries) = self
 7157            .diagnostic_summaries
 7158            .get(&project_path.worktree_id)
 7159            .and_then(|map| map.get(&project_path.path))
 7160        {
 7161            let (error_count, warning_count) = summaries.iter().fold(
 7162                (0, 0),
 7163                |(error_count, warning_count), (_language_server_id, summary)| {
 7164                    (
 7165                        error_count + summary.error_count,
 7166                        warning_count + summary.warning_count,
 7167                    )
 7168                },
 7169            );
 7170
 7171            DiagnosticSummary {
 7172                error_count,
 7173                warning_count,
 7174            }
 7175        } else {
 7176            DiagnosticSummary::default()
 7177        }
 7178    }
 7179
 7180    pub fn diagnostic_summaries<'a>(
 7181        &'a self,
 7182        include_ignored: bool,
 7183        cx: &'a App,
 7184    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7185        self.worktree_store
 7186            .read(cx)
 7187            .visible_worktrees(cx)
 7188            .filter_map(|worktree| {
 7189                let worktree = worktree.read(cx);
 7190                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7191            })
 7192            .flat_map(move |(worktree, summaries)| {
 7193                let worktree_id = worktree.id();
 7194                summaries
 7195                    .iter()
 7196                    .filter(move |(path, _)| {
 7197                        include_ignored
 7198                            || worktree
 7199                                .entry_for_path(path.as_ref())
 7200                                .is_some_and(|entry| !entry.is_ignored)
 7201                    })
 7202                    .flat_map(move |(path, summaries)| {
 7203                        summaries.iter().map(move |(server_id, summary)| {
 7204                            (
 7205                                ProjectPath {
 7206                                    worktree_id,
 7207                                    path: path.clone(),
 7208                                },
 7209                                *server_id,
 7210                                *summary,
 7211                            )
 7212                        })
 7213                    })
 7214            })
 7215    }
 7216
 7217    pub fn on_buffer_edited(
 7218        &mut self,
 7219        buffer: Entity<Buffer>,
 7220        cx: &mut Context<Self>,
 7221    ) -> Option<()> {
 7222        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7223            Some(
 7224                self.as_local()?
 7225                    .language_servers_for_buffer(buffer, cx)
 7226                    .map(|i| i.1.clone())
 7227                    .collect(),
 7228            )
 7229        })?;
 7230
 7231        let buffer = buffer.read(cx);
 7232        let file = File::from_dyn(buffer.file())?;
 7233        let abs_path = file.as_local()?.abs_path(cx);
 7234        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7235        let next_snapshot = buffer.text_snapshot();
 7236        for language_server in language_servers {
 7237            let language_server = language_server.clone();
 7238
 7239            let buffer_snapshots = self
 7240                .as_local_mut()
 7241                .unwrap()
 7242                .buffer_snapshots
 7243                .get_mut(&buffer.remote_id())
 7244                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7245            let previous_snapshot = buffer_snapshots.last()?;
 7246
 7247            let build_incremental_change = || {
 7248                buffer
 7249                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7250                        previous_snapshot.snapshot.version(),
 7251                    )
 7252                    .map(|edit| {
 7253                        let edit_start = edit.new.start.0;
 7254                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7255                        let new_text = next_snapshot
 7256                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7257                            .collect();
 7258                        lsp::TextDocumentContentChangeEvent {
 7259                            range: Some(lsp::Range::new(
 7260                                point_to_lsp(edit_start),
 7261                                point_to_lsp(edit_end),
 7262                            )),
 7263                            range_length: None,
 7264                            text: new_text,
 7265                        }
 7266                    })
 7267                    .collect()
 7268            };
 7269
 7270            let document_sync_kind = language_server
 7271                .capabilities()
 7272                .text_document_sync
 7273                .as_ref()
 7274                .and_then(|sync| match sync {
 7275                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7276                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7277                });
 7278
 7279            let content_changes: Vec<_> = match document_sync_kind {
 7280                Some(lsp::TextDocumentSyncKind::FULL) => {
 7281                    vec![lsp::TextDocumentContentChangeEvent {
 7282                        range: None,
 7283                        range_length: None,
 7284                        text: next_snapshot.text(),
 7285                    }]
 7286                }
 7287                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7288                _ => {
 7289                    #[cfg(any(test, feature = "test-support"))]
 7290                    {
 7291                        build_incremental_change()
 7292                    }
 7293
 7294                    #[cfg(not(any(test, feature = "test-support")))]
 7295                    {
 7296                        continue;
 7297                    }
 7298                }
 7299            };
 7300
 7301            let next_version = previous_snapshot.version + 1;
 7302            buffer_snapshots.push(LspBufferSnapshot {
 7303                version: next_version,
 7304                snapshot: next_snapshot.clone(),
 7305            });
 7306
 7307            language_server
 7308                .notify::<lsp::notification::DidChangeTextDocument>(
 7309                    &lsp::DidChangeTextDocumentParams {
 7310                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7311                            uri.clone(),
 7312                            next_version,
 7313                        ),
 7314                        content_changes,
 7315                    },
 7316                )
 7317                .ok();
 7318            self.pull_workspace_diagnostics(language_server.server_id());
 7319        }
 7320
 7321        None
 7322    }
 7323
 7324    pub fn on_buffer_saved(
 7325        &mut self,
 7326        buffer: Entity<Buffer>,
 7327        cx: &mut Context<Self>,
 7328    ) -> Option<()> {
 7329        let file = File::from_dyn(buffer.read(cx).file())?;
 7330        let worktree_id = file.worktree_id(cx);
 7331        let abs_path = file.as_local()?.abs_path(cx);
 7332        let text_document = lsp::TextDocumentIdentifier {
 7333            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7334        };
 7335        let local = self.as_local()?;
 7336
 7337        for server in local.language_servers_for_worktree(worktree_id) {
 7338            if let Some(include_text) = include_text(server.as_ref()) {
 7339                let text = if include_text {
 7340                    Some(buffer.read(cx).text())
 7341                } else {
 7342                    None
 7343                };
 7344                server
 7345                    .notify::<lsp::notification::DidSaveTextDocument>(
 7346                        &lsp::DidSaveTextDocumentParams {
 7347                            text_document: text_document.clone(),
 7348                            text,
 7349                        },
 7350                    )
 7351                    .ok();
 7352            }
 7353        }
 7354
 7355        let language_servers = buffer.update(cx, |buffer, cx| {
 7356            local.language_server_ids_for_buffer(buffer, cx)
 7357        });
 7358        for language_server_id in language_servers {
 7359            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7360        }
 7361
 7362        None
 7363    }
 7364
 7365    async fn refresh_workspace_configurations(
 7366        lsp_store: &WeakEntity<Self>,
 7367        fs: Arc<dyn Fs>,
 7368        cx: &mut AsyncApp,
 7369    ) {
 7370        maybe!(async move {
 7371            let mut refreshed_servers = HashSet::default();
 7372            let servers = lsp_store
 7373                .update(cx, |lsp_store, cx| {
 7374                    let local = lsp_store.as_local()?;
 7375
 7376                    let servers = local
 7377                        .language_server_ids
 7378                        .iter()
 7379                        .filter_map(|(seed, state)| {
 7380                            let worktree = lsp_store
 7381                                .worktree_store
 7382                                .read(cx)
 7383                                .worktree_for_id(seed.worktree_id, cx);
 7384                            let delegate: Arc<dyn LspAdapterDelegate> =
 7385                                worktree.map(|worktree| {
 7386                                    LocalLspAdapterDelegate::new(
 7387                                        local.languages.clone(),
 7388                                        &local.environment,
 7389                                        cx.weak_entity(),
 7390                                        &worktree,
 7391                                        local.http_client.clone(),
 7392                                        local.fs.clone(),
 7393                                        cx,
 7394                                    )
 7395                                })?;
 7396                            let server_id = state.id;
 7397
 7398                            let states = local.language_servers.get(&server_id)?;
 7399
 7400                            match states {
 7401                                LanguageServerState::Starting { .. } => None,
 7402                                LanguageServerState::Running {
 7403                                    adapter, server, ..
 7404                                } => {
 7405                                    let fs = fs.clone();
 7406
 7407                                    let adapter = adapter.clone();
 7408                                    let server = server.clone();
 7409                                    refreshed_servers.insert(server.name());
 7410                                    let toolchain = seed.toolchain.clone();
 7411                                    Some(cx.spawn(async move |_, cx| {
 7412                                        let settings =
 7413                                            LocalLspStore::workspace_configuration_for_adapter(
 7414                                                adapter.adapter.clone(),
 7415                                                fs.as_ref(),
 7416                                                &delegate,
 7417                                                toolchain,
 7418                                                cx,
 7419                                            )
 7420                                            .await
 7421                                            .ok()?;
 7422                                        server
 7423                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7424                                                &lsp::DidChangeConfigurationParams { settings },
 7425                                            )
 7426                                            .ok()?;
 7427                                        Some(())
 7428                                    }))
 7429                                }
 7430                            }
 7431                        })
 7432                        .collect::<Vec<_>>();
 7433
 7434                    Some(servers)
 7435                })
 7436                .ok()
 7437                .flatten()?;
 7438
 7439            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7440            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7441            // to stop and unregister its language server wrapper.
 7442            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7443            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7444            let _: Vec<Option<()>> = join_all(servers).await;
 7445
 7446            Some(())
 7447        })
 7448        .await;
 7449    }
 7450
 7451    fn maintain_workspace_config(
 7452        fs: Arc<dyn Fs>,
 7453        external_refresh_requests: watch::Receiver<()>,
 7454        cx: &mut Context<Self>,
 7455    ) -> Task<Result<()>> {
 7456        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7457        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7458
 7459        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7460            *settings_changed_tx.borrow_mut() = ();
 7461        });
 7462
 7463        let mut joint_future =
 7464            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7465        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7466        // - 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).
 7467        // - 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.
 7468        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7469        // - 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,
 7470        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7471        cx.spawn(async move |this, cx| {
 7472            while let Some(()) = joint_future.next().await {
 7473                this.update(cx, |this, cx| {
 7474                    this.refresh_server_tree(cx);
 7475                })
 7476                .ok();
 7477
 7478                Self::refresh_workspace_configurations(&this, fs.clone(), cx).await;
 7479            }
 7480
 7481            drop(settings_observation);
 7482            anyhow::Ok(())
 7483        })
 7484    }
 7485
 7486    pub fn language_servers_for_local_buffer<'a>(
 7487        &'a self,
 7488        buffer: &Buffer,
 7489        cx: &mut App,
 7490    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7491        let local = self.as_local();
 7492        let language_server_ids = local
 7493            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7494            .unwrap_or_default();
 7495
 7496        language_server_ids
 7497            .into_iter()
 7498            .filter_map(
 7499                move |server_id| match local?.language_servers.get(&server_id)? {
 7500                    LanguageServerState::Running {
 7501                        adapter, server, ..
 7502                    } => Some((adapter, server)),
 7503                    _ => None,
 7504                },
 7505            )
 7506    }
 7507
 7508    pub fn language_server_for_local_buffer<'a>(
 7509        &'a self,
 7510        buffer: &'a Buffer,
 7511        server_id: LanguageServerId,
 7512        cx: &'a mut App,
 7513    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7514        self.as_local()?
 7515            .language_servers_for_buffer(buffer, cx)
 7516            .find(|(_, s)| s.server_id() == server_id)
 7517    }
 7518
 7519    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7520        self.diagnostic_summaries.remove(&id_to_remove);
 7521        if let Some(local) = self.as_local_mut() {
 7522            let to_remove = local.remove_worktree(id_to_remove, cx);
 7523            for server in to_remove {
 7524                self.language_server_statuses.remove(&server);
 7525            }
 7526        }
 7527    }
 7528
 7529    pub fn shared(
 7530        &mut self,
 7531        project_id: u64,
 7532        downstream_client: AnyProtoClient,
 7533        _: &mut Context<Self>,
 7534    ) {
 7535        self.downstream_client = Some((downstream_client.clone(), project_id));
 7536
 7537        for (server_id, status) in &self.language_server_statuses {
 7538            if let Some(server) = self.language_server_for_id(*server_id) {
 7539                downstream_client
 7540                    .send(proto::StartLanguageServer {
 7541                        project_id,
 7542                        server: Some(proto::LanguageServer {
 7543                            id: server_id.to_proto(),
 7544                            name: status.name.to_string(),
 7545                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7546                        }),
 7547                        capabilities: serde_json::to_string(&server.capabilities())
 7548                            .expect("serializing server LSP capabilities"),
 7549                    })
 7550                    .log_err();
 7551            }
 7552        }
 7553    }
 7554
 7555    pub fn disconnected_from_host(&mut self) {
 7556        self.downstream_client.take();
 7557    }
 7558
 7559    pub fn disconnected_from_ssh_remote(&mut self) {
 7560        if let LspStoreMode::Remote(RemoteLspStore {
 7561            upstream_client, ..
 7562        }) = &mut self.mode
 7563        {
 7564            upstream_client.take();
 7565        }
 7566    }
 7567
 7568    pub(crate) fn set_language_server_statuses_from_proto(
 7569        &mut self,
 7570        project: WeakEntity<Project>,
 7571        language_servers: Vec<proto::LanguageServer>,
 7572        server_capabilities: Vec<String>,
 7573        cx: &mut Context<Self>,
 7574    ) {
 7575        let lsp_logs = cx
 7576            .try_global::<GlobalLogStore>()
 7577            .map(|lsp_store| lsp_store.0.clone());
 7578
 7579        self.language_server_statuses = language_servers
 7580            .into_iter()
 7581            .zip(server_capabilities)
 7582            .map(|(server, server_capabilities)| {
 7583                let server_id = LanguageServerId(server.id as usize);
 7584                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7585                    self.lsp_server_capabilities
 7586                        .insert(server_id, server_capabilities);
 7587                }
 7588
 7589                let name = LanguageServerName::from_proto(server.name);
 7590                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7591
 7592                if let Some(lsp_logs) = &lsp_logs {
 7593                    lsp_logs.update(cx, |lsp_logs, cx| {
 7594                        lsp_logs.add_language_server(
 7595                            // Only remote clients get their language servers set from proto
 7596                            LanguageServerKind::Remote {
 7597                                project: project.clone(),
 7598                            },
 7599                            server_id,
 7600                            Some(name.clone()),
 7601                            worktree,
 7602                            None,
 7603                            cx,
 7604                        );
 7605                    });
 7606                }
 7607
 7608                (
 7609                    server_id,
 7610                    LanguageServerStatus {
 7611                        name,
 7612                        pending_work: Default::default(),
 7613                        has_pending_diagnostic_updates: false,
 7614                        progress_tokens: Default::default(),
 7615                        worktree,
 7616                    },
 7617                )
 7618            })
 7619            .collect();
 7620    }
 7621
 7622    #[cfg(test)]
 7623    pub fn update_diagnostic_entries(
 7624        &mut self,
 7625        server_id: LanguageServerId,
 7626        abs_path: PathBuf,
 7627        result_id: Option<String>,
 7628        version: Option<i32>,
 7629        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7630        cx: &mut Context<Self>,
 7631    ) -> anyhow::Result<()> {
 7632        self.merge_diagnostic_entries(
 7633            vec![DocumentDiagnosticsUpdate {
 7634                diagnostics: DocumentDiagnostics {
 7635                    diagnostics,
 7636                    document_abs_path: abs_path,
 7637                    version,
 7638                },
 7639                result_id,
 7640                server_id,
 7641                disk_based_sources: Cow::Borrowed(&[]),
 7642            }],
 7643            |_, _, _| false,
 7644            cx,
 7645        )?;
 7646        Ok(())
 7647    }
 7648
 7649    pub fn merge_diagnostic_entries<'a>(
 7650        &mut self,
 7651        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7652        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7653        cx: &mut Context<Self>,
 7654    ) -> anyhow::Result<()> {
 7655        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7656        let mut updated_diagnostics_paths = HashMap::default();
 7657        for mut update in diagnostic_updates {
 7658            let abs_path = &update.diagnostics.document_abs_path;
 7659            let server_id = update.server_id;
 7660            let Some((worktree, relative_path)) =
 7661                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7662            else {
 7663                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7664                return Ok(());
 7665            };
 7666
 7667            let worktree_id = worktree.read(cx).id();
 7668            let project_path = ProjectPath {
 7669                worktree_id,
 7670                path: relative_path.into(),
 7671            };
 7672
 7673            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7674                let snapshot = buffer_handle.read(cx).snapshot();
 7675                let buffer = buffer_handle.read(cx);
 7676                let reused_diagnostics = buffer
 7677                    .buffer_diagnostics(Some(server_id))
 7678                    .iter()
 7679                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 7680                    .map(|v| {
 7681                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 7682                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 7683                        DiagnosticEntry {
 7684                            range: start..end,
 7685                            diagnostic: v.diagnostic.clone(),
 7686                        }
 7687                    })
 7688                    .collect::<Vec<_>>();
 7689
 7690                self.as_local_mut()
 7691                    .context("cannot merge diagnostics on a remote LspStore")?
 7692                    .update_buffer_diagnostics(
 7693                        &buffer_handle,
 7694                        server_id,
 7695                        update.result_id,
 7696                        update.diagnostics.version,
 7697                        update.diagnostics.diagnostics.clone(),
 7698                        reused_diagnostics.clone(),
 7699                        cx,
 7700                    )?;
 7701
 7702                update.diagnostics.diagnostics.extend(reused_diagnostics);
 7703            }
 7704
 7705            let updated = worktree.update(cx, |worktree, cx| {
 7706                self.update_worktree_diagnostics(
 7707                    worktree.id(),
 7708                    server_id,
 7709                    project_path.path.clone(),
 7710                    update.diagnostics.diagnostics,
 7711                    cx,
 7712                )
 7713            })?;
 7714            match updated {
 7715                ControlFlow::Continue(new_summary) => {
 7716                    if let Some((project_id, new_summary)) = new_summary {
 7717                        match &mut diagnostics_summary {
 7718                            Some(diagnostics_summary) => {
 7719                                diagnostics_summary
 7720                                    .more_summaries
 7721                                    .push(proto::DiagnosticSummary {
 7722                                        path: project_path.path.as_ref().to_proto(),
 7723                                        language_server_id: server_id.0 as u64,
 7724                                        error_count: new_summary.error_count,
 7725                                        warning_count: new_summary.warning_count,
 7726                                    })
 7727                            }
 7728                            None => {
 7729                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 7730                                    project_id,
 7731                                    worktree_id: worktree_id.to_proto(),
 7732                                    summary: Some(proto::DiagnosticSummary {
 7733                                        path: project_path.path.as_ref().to_proto(),
 7734                                        language_server_id: server_id.0 as u64,
 7735                                        error_count: new_summary.error_count,
 7736                                        warning_count: new_summary.warning_count,
 7737                                    }),
 7738                                    more_summaries: Vec::new(),
 7739                                })
 7740                            }
 7741                        }
 7742                    }
 7743                    updated_diagnostics_paths
 7744                        .entry(server_id)
 7745                        .or_insert_with(Vec::new)
 7746                        .push(project_path);
 7747                }
 7748                ControlFlow::Break(()) => {}
 7749            }
 7750        }
 7751
 7752        if let Some((diagnostics_summary, (downstream_client, _))) =
 7753            diagnostics_summary.zip(self.downstream_client.as_ref())
 7754        {
 7755            downstream_client.send(diagnostics_summary).log_err();
 7756        }
 7757        for (server_id, paths) in updated_diagnostics_paths {
 7758            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 7759        }
 7760        Ok(())
 7761    }
 7762
 7763    fn update_worktree_diagnostics(
 7764        &mut self,
 7765        worktree_id: WorktreeId,
 7766        server_id: LanguageServerId,
 7767        path_in_worktree: Arc<Path>,
 7768        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7769        _: &mut Context<Worktree>,
 7770    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 7771        let local = match &mut self.mode {
 7772            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 7773            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 7774        };
 7775
 7776        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 7777        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 7778        let summaries_by_server_id = summaries_for_tree
 7779            .entry(path_in_worktree.clone())
 7780            .or_default();
 7781
 7782        let old_summary = summaries_by_server_id
 7783            .remove(&server_id)
 7784            .unwrap_or_default();
 7785
 7786        let new_summary = DiagnosticSummary::new(&diagnostics);
 7787        if new_summary.is_empty() {
 7788            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 7789            {
 7790                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7791                    diagnostics_by_server_id.remove(ix);
 7792                }
 7793                if diagnostics_by_server_id.is_empty() {
 7794                    diagnostics_for_tree.remove(&path_in_worktree);
 7795                }
 7796            }
 7797        } else {
 7798            summaries_by_server_id.insert(server_id, new_summary);
 7799            let diagnostics_by_server_id = diagnostics_for_tree
 7800                .entry(path_in_worktree.clone())
 7801                .or_default();
 7802            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7803                Ok(ix) => {
 7804                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 7805                }
 7806                Err(ix) => {
 7807                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 7808                }
 7809            }
 7810        }
 7811
 7812        if !old_summary.is_empty() || !new_summary.is_empty() {
 7813            if let Some((_, project_id)) = &self.downstream_client {
 7814                Ok(ControlFlow::Continue(Some((
 7815                    *project_id,
 7816                    proto::DiagnosticSummary {
 7817                        path: path_in_worktree.to_proto(),
 7818                        language_server_id: server_id.0 as u64,
 7819                        error_count: new_summary.error_count as u32,
 7820                        warning_count: new_summary.warning_count as u32,
 7821                    },
 7822                ))))
 7823            } else {
 7824                Ok(ControlFlow::Continue(None))
 7825            }
 7826        } else {
 7827            Ok(ControlFlow::Break(()))
 7828        }
 7829    }
 7830
 7831    pub fn open_buffer_for_symbol(
 7832        &mut self,
 7833        symbol: &Symbol,
 7834        cx: &mut Context<Self>,
 7835    ) -> Task<Result<Entity<Buffer>>> {
 7836        if let Some((client, project_id)) = self.upstream_client() {
 7837            let request = client.request(proto::OpenBufferForSymbol {
 7838                project_id,
 7839                symbol: Some(Self::serialize_symbol(symbol)),
 7840            });
 7841            cx.spawn(async move |this, cx| {
 7842                let response = request.await?;
 7843                let buffer_id = BufferId::new(response.buffer_id)?;
 7844                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 7845                    .await
 7846            })
 7847        } else if let Some(local) = self.as_local() {
 7848            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 7849                seed.worktree_id == symbol.source_worktree_id
 7850                    && state.id == symbol.source_language_server_id
 7851                    && symbol.language_server_name == seed.name
 7852            });
 7853            if !is_valid {
 7854                return Task::ready(Err(anyhow!(
 7855                    "language server for worktree and language not found"
 7856                )));
 7857            };
 7858
 7859            let worktree_abs_path = if let Some(worktree_abs_path) = self
 7860                .worktree_store
 7861                .read(cx)
 7862                .worktree_for_id(symbol.path.worktree_id, cx)
 7863                .map(|worktree| worktree.read(cx).abs_path())
 7864            {
 7865                worktree_abs_path
 7866            } else {
 7867                return Task::ready(Err(anyhow!("worktree not found for symbol")));
 7868            };
 7869
 7870            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
 7871            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 7872                uri
 7873            } else {
 7874                return Task::ready(Err(anyhow!("invalid symbol path")));
 7875            };
 7876
 7877            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 7878        } else {
 7879            Task::ready(Err(anyhow!("no upstream client or local store")))
 7880        }
 7881    }
 7882
 7883    pub(crate) fn open_local_buffer_via_lsp(
 7884        &mut self,
 7885        abs_path: lsp::Uri,
 7886        language_server_id: LanguageServerId,
 7887        cx: &mut Context<Self>,
 7888    ) -> Task<Result<Entity<Buffer>>> {
 7889        cx.spawn(async move |lsp_store, cx| {
 7890            // Escape percent-encoded string.
 7891            let current_scheme = abs_path.scheme().to_owned();
 7892            // Uri is immutable, so we can't modify the scheme
 7893
 7894            let abs_path = abs_path
 7895                .to_file_path()
 7896                .map_err(|()| anyhow!("can't convert URI to path"))?;
 7897            let p = abs_path.clone();
 7898            let yarn_worktree = lsp_store
 7899                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 7900                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 7901                        cx.spawn(async move |this, cx| {
 7902                            let t = this
 7903                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 7904                                .ok()?;
 7905                            t.await
 7906                        })
 7907                    }),
 7908                    None => Task::ready(None),
 7909                })?
 7910                .await;
 7911            let (worktree_root_target, known_relative_path) =
 7912                if let Some((zip_root, relative_path)) = yarn_worktree {
 7913                    (zip_root, Some(relative_path))
 7914                } else {
 7915                    (Arc::<Path>::from(abs_path.as_path()), None)
 7916                };
 7917            let (worktree, relative_path) = if let Some(result) =
 7918                lsp_store.update(cx, |lsp_store, cx| {
 7919                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7920                        worktree_store.find_worktree(&worktree_root_target, cx)
 7921                    })
 7922                })? {
 7923                let relative_path =
 7924                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
 7925                (result.0, relative_path)
 7926            } else {
 7927                let worktree = lsp_store
 7928                    .update(cx, |lsp_store, cx| {
 7929                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7930                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 7931                        })
 7932                    })?
 7933                    .await?;
 7934                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 7935                    lsp_store
 7936                        .update(cx, |lsp_store, cx| {
 7937                            if let Some(local) = lsp_store.as_local_mut() {
 7938                                local.register_language_server_for_invisible_worktree(
 7939                                    &worktree,
 7940                                    language_server_id,
 7941                                    cx,
 7942                                )
 7943                            }
 7944                        })
 7945                        .ok();
 7946                }
 7947                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 7948                let relative_path = if let Some(known_path) = known_relative_path {
 7949                    known_path
 7950                } else {
 7951                    abs_path.strip_prefix(worktree_root)?.into()
 7952                };
 7953                (worktree, relative_path)
 7954            };
 7955            let project_path = ProjectPath {
 7956                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 7957                path: relative_path,
 7958            };
 7959            lsp_store
 7960                .update(cx, |lsp_store, cx| {
 7961                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 7962                        buffer_store.open_buffer(project_path, cx)
 7963                    })
 7964                })?
 7965                .await
 7966        })
 7967    }
 7968
 7969    fn request_multiple_lsp_locally<P, R>(
 7970        &mut self,
 7971        buffer: &Entity<Buffer>,
 7972        position: Option<P>,
 7973        request: R,
 7974        cx: &mut Context<Self>,
 7975    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 7976    where
 7977        P: ToOffset,
 7978        R: LspCommand + Clone,
 7979        <R::LspRequest as lsp::request::Request>::Result: Send,
 7980        <R::LspRequest as lsp::request::Request>::Params: Send,
 7981    {
 7982        let Some(local) = self.as_local() else {
 7983            return Task::ready(Vec::new());
 7984        };
 7985
 7986        let snapshot = buffer.read(cx).snapshot();
 7987        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 7988
 7989        let server_ids = buffer.update(cx, |buffer, cx| {
 7990            local
 7991                .language_servers_for_buffer(buffer, cx)
 7992                .filter(|(adapter, _)| {
 7993                    scope
 7994                        .as_ref()
 7995                        .map(|scope| scope.language_allowed(&adapter.name))
 7996                        .unwrap_or(true)
 7997                })
 7998                .map(|(_, server)| server.server_id())
 7999                .filter(|server_id| {
 8000                    self.as_local().is_none_or(|local| {
 8001                        local
 8002                            .buffers_opened_in_servers
 8003                            .get(&snapshot.remote_id())
 8004                            .is_some_and(|servers| servers.contains(server_id))
 8005                    })
 8006                })
 8007                .collect::<Vec<_>>()
 8008        });
 8009
 8010        let mut response_results = server_ids
 8011            .into_iter()
 8012            .map(|server_id| {
 8013                let task = self.request_lsp(
 8014                    buffer.clone(),
 8015                    LanguageServerToQuery::Other(server_id),
 8016                    request.clone(),
 8017                    cx,
 8018                );
 8019                async move { (server_id, task.await) }
 8020            })
 8021            .collect::<FuturesUnordered<_>>();
 8022
 8023        cx.background_spawn(async move {
 8024            let mut responses = Vec::with_capacity(response_results.len());
 8025            while let Some((server_id, response_result)) = response_results.next().await {
 8026                if let Some(response) = response_result.log_err() {
 8027                    responses.push((server_id, response));
 8028                }
 8029            }
 8030            responses
 8031        })
 8032    }
 8033
 8034    async fn handle_lsp_command<T: LspCommand>(
 8035        this: Entity<Self>,
 8036        envelope: TypedEnvelope<T::ProtoRequest>,
 8037        mut cx: AsyncApp,
 8038    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8039    where
 8040        <T::LspRequest as lsp::request::Request>::Params: Send,
 8041        <T::LspRequest as lsp::request::Request>::Result: Send,
 8042    {
 8043        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8044        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8045        let buffer_handle = this.update(&mut cx, |this, cx| {
 8046            this.buffer_store.read(cx).get_existing(buffer_id)
 8047        })??;
 8048        let request = T::from_proto(
 8049            envelope.payload,
 8050            this.clone(),
 8051            buffer_handle.clone(),
 8052            cx.clone(),
 8053        )
 8054        .await?;
 8055        let response = this
 8056            .update(&mut cx, |this, cx| {
 8057                this.request_lsp(
 8058                    buffer_handle.clone(),
 8059                    LanguageServerToQuery::FirstCapable,
 8060                    request,
 8061                    cx,
 8062                )
 8063            })?
 8064            .await?;
 8065        this.update(&mut cx, |this, cx| {
 8066            Ok(T::response_to_proto(
 8067                response,
 8068                this,
 8069                sender_id,
 8070                &buffer_handle.read(cx).version(),
 8071                cx,
 8072            ))
 8073        })?
 8074    }
 8075
 8076    async fn handle_lsp_query(
 8077        lsp_store: Entity<Self>,
 8078        envelope: TypedEnvelope<proto::LspQuery>,
 8079        mut cx: AsyncApp,
 8080    ) -> Result<proto::Ack> {
 8081        use proto::lsp_query::Request;
 8082        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8083        let lsp_query = envelope.payload;
 8084        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8085        match lsp_query.request.context("invalid LSP query request")? {
 8086            Request::GetReferences(get_references) => {
 8087                let position = get_references.position.clone().and_then(deserialize_anchor);
 8088                Self::query_lsp_locally::<GetReferences>(
 8089                    lsp_store,
 8090                    sender_id,
 8091                    lsp_request_id,
 8092                    get_references,
 8093                    position,
 8094                    cx.clone(),
 8095                )
 8096                .await?;
 8097            }
 8098            Request::GetDocumentColor(get_document_color) => {
 8099                Self::query_lsp_locally::<GetDocumentColor>(
 8100                    lsp_store,
 8101                    sender_id,
 8102                    lsp_request_id,
 8103                    get_document_color,
 8104                    None,
 8105                    cx.clone(),
 8106                )
 8107                .await?;
 8108            }
 8109            Request::GetHover(get_hover) => {
 8110                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8111                Self::query_lsp_locally::<GetHover>(
 8112                    lsp_store,
 8113                    sender_id,
 8114                    lsp_request_id,
 8115                    get_hover,
 8116                    position,
 8117                    cx.clone(),
 8118                )
 8119                .await?;
 8120            }
 8121            Request::GetCodeActions(get_code_actions) => {
 8122                Self::query_lsp_locally::<GetCodeActions>(
 8123                    lsp_store,
 8124                    sender_id,
 8125                    lsp_request_id,
 8126                    get_code_actions,
 8127                    None,
 8128                    cx.clone(),
 8129                )
 8130                .await?;
 8131            }
 8132            Request::GetSignatureHelp(get_signature_help) => {
 8133                let position = get_signature_help
 8134                    .position
 8135                    .clone()
 8136                    .and_then(deserialize_anchor);
 8137                Self::query_lsp_locally::<GetSignatureHelp>(
 8138                    lsp_store,
 8139                    sender_id,
 8140                    lsp_request_id,
 8141                    get_signature_help,
 8142                    position,
 8143                    cx.clone(),
 8144                )
 8145                .await?;
 8146            }
 8147            Request::GetCodeLens(get_code_lens) => {
 8148                Self::query_lsp_locally::<GetCodeLens>(
 8149                    lsp_store,
 8150                    sender_id,
 8151                    lsp_request_id,
 8152                    get_code_lens,
 8153                    None,
 8154                    cx.clone(),
 8155                )
 8156                .await?;
 8157            }
 8158            Request::GetDefinition(get_definition) => {
 8159                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8160                Self::query_lsp_locally::<GetDefinitions>(
 8161                    lsp_store,
 8162                    sender_id,
 8163                    lsp_request_id,
 8164                    get_definition,
 8165                    position,
 8166                    cx.clone(),
 8167                )
 8168                .await?;
 8169            }
 8170            Request::GetDeclaration(get_declaration) => {
 8171                let position = get_declaration
 8172                    .position
 8173                    .clone()
 8174                    .and_then(deserialize_anchor);
 8175                Self::query_lsp_locally::<GetDeclarations>(
 8176                    lsp_store,
 8177                    sender_id,
 8178                    lsp_request_id,
 8179                    get_declaration,
 8180                    position,
 8181                    cx.clone(),
 8182                )
 8183                .await?;
 8184            }
 8185            Request::GetTypeDefinition(get_type_definition) => {
 8186                let position = get_type_definition
 8187                    .position
 8188                    .clone()
 8189                    .and_then(deserialize_anchor);
 8190                Self::query_lsp_locally::<GetTypeDefinitions>(
 8191                    lsp_store,
 8192                    sender_id,
 8193                    lsp_request_id,
 8194                    get_type_definition,
 8195                    position,
 8196                    cx.clone(),
 8197                )
 8198                .await?;
 8199            }
 8200            Request::GetImplementation(get_implementation) => {
 8201                let position = get_implementation
 8202                    .position
 8203                    .clone()
 8204                    .and_then(deserialize_anchor);
 8205                Self::query_lsp_locally::<GetImplementations>(
 8206                    lsp_store,
 8207                    sender_id,
 8208                    lsp_request_id,
 8209                    get_implementation,
 8210                    position,
 8211                    cx.clone(),
 8212                )
 8213                .await?;
 8214            }
 8215            // Diagnostics pull synchronizes internally via the buffer state, and cannot be handled generically as the other requests.
 8216            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8217                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8218                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8219                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8220                    this.buffer_store.read(cx).get_existing(buffer_id)
 8221                })??;
 8222                buffer
 8223                    .update(&mut cx, |buffer, _| {
 8224                        buffer.wait_for_version(version.clone())
 8225                    })?
 8226                    .await?;
 8227                lsp_store.update(&mut cx, |lsp_store, cx| {
 8228                    let existing_queries = lsp_store
 8229                        .running_lsp_requests
 8230                        .entry(TypeId::of::<GetDocumentDiagnostics>())
 8231                        .or_default();
 8232                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8233                    ) || buffer.read(cx).version.changed_since(&existing_queries.0)
 8234                    {
 8235                        existing_queries.1.clear();
 8236                    }
 8237                    existing_queries.1.insert(
 8238                        lsp_request_id,
 8239                        cx.spawn(async move |lsp_store, cx| {
 8240                            let diagnostics_pull = lsp_store
 8241                                .update(cx, |lsp_store, cx| {
 8242                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8243                                })
 8244                                .ok();
 8245                            if let Some(diagnostics_pull) = diagnostics_pull {
 8246                                match diagnostics_pull.await {
 8247                                    Ok(()) => {}
 8248                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8249                                };
 8250                            }
 8251                        }),
 8252                    );
 8253                })?;
 8254            }
 8255        }
 8256        Ok(proto::Ack {})
 8257    }
 8258
 8259    async fn handle_lsp_query_response(
 8260        lsp_store: Entity<Self>,
 8261        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8262        cx: AsyncApp,
 8263    ) -> Result<()> {
 8264        lsp_store.read_with(&cx, |lsp_store, _| {
 8265            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8266                upstream_client.handle_lsp_response(envelope.clone());
 8267            }
 8268        })?;
 8269        Ok(())
 8270    }
 8271
 8272    // todo(lsp) remove after Zed Stable hits v0.204.x
 8273    async fn handle_multi_lsp_query(
 8274        lsp_store: Entity<Self>,
 8275        envelope: TypedEnvelope<proto::MultiLspQuery>,
 8276        mut cx: AsyncApp,
 8277    ) -> Result<proto::MultiLspQueryResponse> {
 8278        let response_from_ssh = lsp_store.read_with(&cx, |this, _| {
 8279            let (upstream_client, project_id) = this.upstream_client()?;
 8280            let mut payload = envelope.payload.clone();
 8281            payload.project_id = project_id;
 8282
 8283            Some(upstream_client.request(payload))
 8284        })?;
 8285        if let Some(response_from_ssh) = response_from_ssh {
 8286            return response_from_ssh.await;
 8287        }
 8288
 8289        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8290        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8291        let version = deserialize_version(&envelope.payload.version);
 8292        let buffer = lsp_store.update(&mut cx, |this, cx| {
 8293            this.buffer_store.read(cx).get_existing(buffer_id)
 8294        })??;
 8295        buffer
 8296            .update(&mut cx, |buffer, _| {
 8297                buffer.wait_for_version(version.clone())
 8298            })?
 8299            .await?;
 8300        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
 8301        match envelope
 8302            .payload
 8303            .strategy
 8304            .context("invalid request without the strategy")?
 8305        {
 8306            proto::multi_lsp_query::Strategy::All(_) => {
 8307                // currently, there's only one multiple language servers query strategy,
 8308                // so just ensure it's specified correctly
 8309            }
 8310        }
 8311        match envelope.payload.request {
 8312            Some(proto::multi_lsp_query::Request::GetHover(message)) => {
 8313                buffer
 8314                    .update(&mut cx, |buffer, _| {
 8315                        buffer.wait_for_version(deserialize_version(&message.version))
 8316                    })?
 8317                    .await?;
 8318                let get_hover =
 8319                    GetHover::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8320                        .await?;
 8321                let all_hovers = lsp_store
 8322                    .update(&mut cx, |this, cx| {
 8323                        this.request_multiple_lsp_locally(
 8324                            &buffer,
 8325                            Some(get_hover.position),
 8326                            get_hover,
 8327                            cx,
 8328                        )
 8329                    })?
 8330                    .await
 8331                    .into_iter()
 8332                    .filter_map(|(server_id, hover)| {
 8333                        Some((server_id, remove_empty_hover_blocks(hover?)?))
 8334                    });
 8335                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8336                    responses: all_hovers
 8337                        .map(|(server_id, hover)| proto::LspResponse {
 8338                            server_id: server_id.to_proto(),
 8339                            response: Some(proto::lsp_response::Response::GetHoverResponse(
 8340                                GetHover::response_to_proto(
 8341                                    Some(hover),
 8342                                    project,
 8343                                    sender_id,
 8344                                    &buffer_version,
 8345                                    cx,
 8346                                ),
 8347                            )),
 8348                        })
 8349                        .collect(),
 8350                })
 8351            }
 8352            Some(proto::multi_lsp_query::Request::GetCodeActions(message)) => {
 8353                buffer
 8354                    .update(&mut cx, |buffer, _| {
 8355                        buffer.wait_for_version(deserialize_version(&message.version))
 8356                    })?
 8357                    .await?;
 8358                let get_code_actions = GetCodeActions::from_proto(
 8359                    message,
 8360                    lsp_store.clone(),
 8361                    buffer.clone(),
 8362                    cx.clone(),
 8363                )
 8364                .await?;
 8365
 8366                let all_actions = lsp_store
 8367                    .update(&mut cx, |project, cx| {
 8368                        project.request_multiple_lsp_locally(
 8369                            &buffer,
 8370                            Some(get_code_actions.range.start),
 8371                            get_code_actions,
 8372                            cx,
 8373                        )
 8374                    })?
 8375                    .await
 8376                    .into_iter();
 8377
 8378                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8379                    responses: all_actions
 8380                        .map(|(server_id, code_actions)| proto::LspResponse {
 8381                            server_id: server_id.to_proto(),
 8382                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
 8383                                GetCodeActions::response_to_proto(
 8384                                    code_actions,
 8385                                    project,
 8386                                    sender_id,
 8387                                    &buffer_version,
 8388                                    cx,
 8389                                ),
 8390                            )),
 8391                        })
 8392                        .collect(),
 8393                })
 8394            }
 8395            Some(proto::multi_lsp_query::Request::GetSignatureHelp(message)) => {
 8396                buffer
 8397                    .update(&mut cx, |buffer, _| {
 8398                        buffer.wait_for_version(deserialize_version(&message.version))
 8399                    })?
 8400                    .await?;
 8401                let get_signature_help = GetSignatureHelp::from_proto(
 8402                    message,
 8403                    lsp_store.clone(),
 8404                    buffer.clone(),
 8405                    cx.clone(),
 8406                )
 8407                .await?;
 8408
 8409                let all_signatures = lsp_store
 8410                    .update(&mut cx, |project, cx| {
 8411                        project.request_multiple_lsp_locally(
 8412                            &buffer,
 8413                            Some(get_signature_help.position),
 8414                            get_signature_help,
 8415                            cx,
 8416                        )
 8417                    })?
 8418                    .await
 8419                    .into_iter();
 8420
 8421                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8422                    responses: all_signatures
 8423                        .map(|(server_id, signature_help)| proto::LspResponse {
 8424                            server_id: server_id.to_proto(),
 8425                            response: Some(
 8426                                proto::lsp_response::Response::GetSignatureHelpResponse(
 8427                                    GetSignatureHelp::response_to_proto(
 8428                                        signature_help,
 8429                                        project,
 8430                                        sender_id,
 8431                                        &buffer_version,
 8432                                        cx,
 8433                                    ),
 8434                                ),
 8435                            ),
 8436                        })
 8437                        .collect(),
 8438                })
 8439            }
 8440            Some(proto::multi_lsp_query::Request::GetCodeLens(message)) => {
 8441                buffer
 8442                    .update(&mut cx, |buffer, _| {
 8443                        buffer.wait_for_version(deserialize_version(&message.version))
 8444                    })?
 8445                    .await?;
 8446                let get_code_lens =
 8447                    GetCodeLens::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8448                        .await?;
 8449
 8450                let code_lens_actions = lsp_store
 8451                    .update(&mut cx, |project, cx| {
 8452                        project.request_multiple_lsp_locally(
 8453                            &buffer,
 8454                            None::<usize>,
 8455                            get_code_lens,
 8456                            cx,
 8457                        )
 8458                    })?
 8459                    .await
 8460                    .into_iter();
 8461
 8462                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8463                    responses: code_lens_actions
 8464                        .map(|(server_id, actions)| proto::LspResponse {
 8465                            server_id: server_id.to_proto(),
 8466                            response: Some(proto::lsp_response::Response::GetCodeLensResponse(
 8467                                GetCodeLens::response_to_proto(
 8468                                    actions,
 8469                                    project,
 8470                                    sender_id,
 8471                                    &buffer_version,
 8472                                    cx,
 8473                                ),
 8474                            )),
 8475                        })
 8476                        .collect(),
 8477                })
 8478            }
 8479            Some(proto::multi_lsp_query::Request::GetDocumentDiagnostics(message)) => {
 8480                buffer
 8481                    .update(&mut cx, |buffer, _| {
 8482                        buffer.wait_for_version(deserialize_version(&message.version))
 8483                    })?
 8484                    .await?;
 8485                lsp_store
 8486                    .update(&mut cx, |lsp_store, cx| {
 8487                        lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8488                    })?
 8489                    .await?;
 8490                // `pull_diagnostics_for_buffer` will merge in the new diagnostics and send them to the client.
 8491                // The client cannot merge anything into its non-local LspStore, so we do not need to return anything.
 8492                Ok(proto::MultiLspQueryResponse {
 8493                    responses: Vec::new(),
 8494                })
 8495            }
 8496            Some(proto::multi_lsp_query::Request::GetDocumentColor(message)) => {
 8497                buffer
 8498                    .update(&mut cx, |buffer, _| {
 8499                        buffer.wait_for_version(deserialize_version(&message.version))
 8500                    })?
 8501                    .await?;
 8502                let get_document_color = GetDocumentColor::from_proto(
 8503                    message,
 8504                    lsp_store.clone(),
 8505                    buffer.clone(),
 8506                    cx.clone(),
 8507                )
 8508                .await?;
 8509
 8510                let all_colors = lsp_store
 8511                    .update(&mut cx, |project, cx| {
 8512                        project.request_multiple_lsp_locally(
 8513                            &buffer,
 8514                            None::<usize>,
 8515                            get_document_color,
 8516                            cx,
 8517                        )
 8518                    })?
 8519                    .await
 8520                    .into_iter();
 8521
 8522                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8523                    responses: all_colors
 8524                        .map(|(server_id, colors)| proto::LspResponse {
 8525                            server_id: server_id.to_proto(),
 8526                            response: Some(
 8527                                proto::lsp_response::Response::GetDocumentColorResponse(
 8528                                    GetDocumentColor::response_to_proto(
 8529                                        colors,
 8530                                        project,
 8531                                        sender_id,
 8532                                        &buffer_version,
 8533                                        cx,
 8534                                    ),
 8535                                ),
 8536                            ),
 8537                        })
 8538                        .collect(),
 8539                })
 8540            }
 8541            Some(proto::multi_lsp_query::Request::GetDefinition(message)) => {
 8542                let get_definitions = GetDefinitions::from_proto(
 8543                    message,
 8544                    lsp_store.clone(),
 8545                    buffer.clone(),
 8546                    cx.clone(),
 8547                )
 8548                .await?;
 8549
 8550                let definitions = lsp_store
 8551                    .update(&mut cx, |project, cx| {
 8552                        project.request_multiple_lsp_locally(
 8553                            &buffer,
 8554                            Some(get_definitions.position),
 8555                            get_definitions,
 8556                            cx,
 8557                        )
 8558                    })?
 8559                    .await
 8560                    .into_iter();
 8561
 8562                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8563                    responses: definitions
 8564                        .map(|(server_id, definitions)| proto::LspResponse {
 8565                            server_id: server_id.to_proto(),
 8566                            response: Some(proto::lsp_response::Response::GetDefinitionResponse(
 8567                                GetDefinitions::response_to_proto(
 8568                                    definitions,
 8569                                    project,
 8570                                    sender_id,
 8571                                    &buffer_version,
 8572                                    cx,
 8573                                ),
 8574                            )),
 8575                        })
 8576                        .collect(),
 8577                })
 8578            }
 8579            Some(proto::multi_lsp_query::Request::GetDeclaration(message)) => {
 8580                let get_declarations = GetDeclarations::from_proto(
 8581                    message,
 8582                    lsp_store.clone(),
 8583                    buffer.clone(),
 8584                    cx.clone(),
 8585                )
 8586                .await?;
 8587
 8588                let declarations = lsp_store
 8589                    .update(&mut cx, |project, cx| {
 8590                        project.request_multiple_lsp_locally(
 8591                            &buffer,
 8592                            Some(get_declarations.position),
 8593                            get_declarations,
 8594                            cx,
 8595                        )
 8596                    })?
 8597                    .await
 8598                    .into_iter();
 8599
 8600                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8601                    responses: declarations
 8602                        .map(|(server_id, declarations)| proto::LspResponse {
 8603                            server_id: server_id.to_proto(),
 8604                            response: Some(proto::lsp_response::Response::GetDeclarationResponse(
 8605                                GetDeclarations::response_to_proto(
 8606                                    declarations,
 8607                                    project,
 8608                                    sender_id,
 8609                                    &buffer_version,
 8610                                    cx,
 8611                                ),
 8612                            )),
 8613                        })
 8614                        .collect(),
 8615                })
 8616            }
 8617            Some(proto::multi_lsp_query::Request::GetTypeDefinition(message)) => {
 8618                let get_type_definitions = GetTypeDefinitions::from_proto(
 8619                    message,
 8620                    lsp_store.clone(),
 8621                    buffer.clone(),
 8622                    cx.clone(),
 8623                )
 8624                .await?;
 8625
 8626                let type_definitions = lsp_store
 8627                    .update(&mut cx, |project, cx| {
 8628                        project.request_multiple_lsp_locally(
 8629                            &buffer,
 8630                            Some(get_type_definitions.position),
 8631                            get_type_definitions,
 8632                            cx,
 8633                        )
 8634                    })?
 8635                    .await
 8636                    .into_iter();
 8637
 8638                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8639                    responses: type_definitions
 8640                        .map(|(server_id, type_definitions)| proto::LspResponse {
 8641                            server_id: server_id.to_proto(),
 8642                            response: Some(
 8643                                proto::lsp_response::Response::GetTypeDefinitionResponse(
 8644                                    GetTypeDefinitions::response_to_proto(
 8645                                        type_definitions,
 8646                                        project,
 8647                                        sender_id,
 8648                                        &buffer_version,
 8649                                        cx,
 8650                                    ),
 8651                                ),
 8652                            ),
 8653                        })
 8654                        .collect(),
 8655                })
 8656            }
 8657            Some(proto::multi_lsp_query::Request::GetImplementation(message)) => {
 8658                let get_implementations = GetImplementations::from_proto(
 8659                    message,
 8660                    lsp_store.clone(),
 8661                    buffer.clone(),
 8662                    cx.clone(),
 8663                )
 8664                .await?;
 8665
 8666                let implementations = lsp_store
 8667                    .update(&mut cx, |project, cx| {
 8668                        project.request_multiple_lsp_locally(
 8669                            &buffer,
 8670                            Some(get_implementations.position),
 8671                            get_implementations,
 8672                            cx,
 8673                        )
 8674                    })?
 8675                    .await
 8676                    .into_iter();
 8677
 8678                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8679                    responses: implementations
 8680                        .map(|(server_id, implementations)| proto::LspResponse {
 8681                            server_id: server_id.to_proto(),
 8682                            response: Some(
 8683                                proto::lsp_response::Response::GetImplementationResponse(
 8684                                    GetImplementations::response_to_proto(
 8685                                        implementations,
 8686                                        project,
 8687                                        sender_id,
 8688                                        &buffer_version,
 8689                                        cx,
 8690                                    ),
 8691                                ),
 8692                            ),
 8693                        })
 8694                        .collect(),
 8695                })
 8696            }
 8697            Some(proto::multi_lsp_query::Request::GetReferences(message)) => {
 8698                let get_references = GetReferences::from_proto(
 8699                    message,
 8700                    lsp_store.clone(),
 8701                    buffer.clone(),
 8702                    cx.clone(),
 8703                )
 8704                .await?;
 8705
 8706                let references = lsp_store
 8707                    .update(&mut cx, |project, cx| {
 8708                        project.request_multiple_lsp_locally(
 8709                            &buffer,
 8710                            Some(get_references.position),
 8711                            get_references,
 8712                            cx,
 8713                        )
 8714                    })?
 8715                    .await
 8716                    .into_iter();
 8717
 8718                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8719                    responses: references
 8720                        .map(|(server_id, references)| proto::LspResponse {
 8721                            server_id: server_id.to_proto(),
 8722                            response: Some(proto::lsp_response::Response::GetReferencesResponse(
 8723                                GetReferences::response_to_proto(
 8724                                    references,
 8725                                    project,
 8726                                    sender_id,
 8727                                    &buffer_version,
 8728                                    cx,
 8729                                ),
 8730                            )),
 8731                        })
 8732                        .collect(),
 8733                })
 8734            }
 8735            None => anyhow::bail!("empty multi lsp query request"),
 8736        }
 8737    }
 8738
 8739    async fn handle_apply_code_action(
 8740        this: Entity<Self>,
 8741        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8742        mut cx: AsyncApp,
 8743    ) -> Result<proto::ApplyCodeActionResponse> {
 8744        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8745        let action =
 8746            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8747        let apply_code_action = this.update(&mut cx, |this, cx| {
 8748            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8749            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8750            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8751        })??;
 8752
 8753        let project_transaction = apply_code_action.await?;
 8754        let project_transaction = this.update(&mut cx, |this, cx| {
 8755            this.buffer_store.update(cx, |buffer_store, cx| {
 8756                buffer_store.serialize_project_transaction_for_peer(
 8757                    project_transaction,
 8758                    sender_id,
 8759                    cx,
 8760                )
 8761            })
 8762        })?;
 8763        Ok(proto::ApplyCodeActionResponse {
 8764            transaction: Some(project_transaction),
 8765        })
 8766    }
 8767
 8768    async fn handle_register_buffer_with_language_servers(
 8769        this: Entity<Self>,
 8770        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8771        mut cx: AsyncApp,
 8772    ) -> Result<proto::Ack> {
 8773        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8774        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8775        this.update(&mut cx, |this, cx| {
 8776            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8777                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8778                    project_id: upstream_project_id,
 8779                    buffer_id: buffer_id.to_proto(),
 8780                    only_servers: envelope.payload.only_servers,
 8781                });
 8782            }
 8783
 8784            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8785                anyhow::bail!("buffer is not open");
 8786            };
 8787
 8788            let handle = this.register_buffer_with_language_servers(
 8789                &buffer,
 8790                envelope
 8791                    .payload
 8792                    .only_servers
 8793                    .into_iter()
 8794                    .filter_map(|selector| {
 8795                        Some(match selector.selector? {
 8796                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8797                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8798                            }
 8799                            proto::language_server_selector::Selector::Name(name) => {
 8800                                LanguageServerSelector::Name(LanguageServerName(
 8801                                    SharedString::from(name),
 8802                                ))
 8803                            }
 8804                        })
 8805                    })
 8806                    .collect(),
 8807                false,
 8808                cx,
 8809            );
 8810            this.buffer_store().update(cx, |buffer_store, _| {
 8811                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8812            });
 8813
 8814            Ok(())
 8815        })??;
 8816        Ok(proto::Ack {})
 8817    }
 8818
 8819    async fn handle_rename_project_entry(
 8820        this: Entity<Self>,
 8821        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8822        mut cx: AsyncApp,
 8823    ) -> Result<proto::ProjectEntryResponse> {
 8824        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8825        let (worktree_id, worktree, old_path, is_dir) = this
 8826            .update(&mut cx, |this, cx| {
 8827                this.worktree_store
 8828                    .read(cx)
 8829                    .worktree_and_entry_for_id(entry_id, cx)
 8830                    .map(|(worktree, entry)| {
 8831                        (
 8832                            worktree.read(cx).id(),
 8833                            worktree,
 8834                            entry.path.clone(),
 8835                            entry.is_dir(),
 8836                        )
 8837                    })
 8838            })?
 8839            .context("worktree not found")?;
 8840        let (old_abs_path, new_abs_path) = {
 8841            let root_path = worktree.read_with(&cx, |this, _| this.abs_path())?;
 8842            let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
 8843            (root_path.join(&old_path), root_path.join(&new_path))
 8844        };
 8845
 8846        let _transaction = Self::will_rename_entry(
 8847            this.downgrade(),
 8848            worktree_id,
 8849            &old_abs_path,
 8850            &new_abs_path,
 8851            is_dir,
 8852            cx.clone(),
 8853        )
 8854        .await;
 8855        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
 8856        this.read_with(&cx, |this, _| {
 8857            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
 8858        })
 8859        .ok();
 8860        response
 8861    }
 8862
 8863    async fn handle_update_diagnostic_summary(
 8864        this: Entity<Self>,
 8865        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8866        mut cx: AsyncApp,
 8867    ) -> Result<()> {
 8868        this.update(&mut cx, |lsp_store, cx| {
 8869            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8870            let mut updated_diagnostics_paths = HashMap::default();
 8871            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8872            for message_summary in envelope
 8873                .payload
 8874                .summary
 8875                .into_iter()
 8876                .chain(envelope.payload.more_summaries)
 8877            {
 8878                let project_path = ProjectPath {
 8879                    worktree_id,
 8880                    path: Arc::<Path>::from_proto(message_summary.path),
 8881                };
 8882                let path = project_path.path.clone();
 8883                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8884                let summary = DiagnosticSummary {
 8885                    error_count: message_summary.error_count as usize,
 8886                    warning_count: message_summary.warning_count as usize,
 8887                };
 8888
 8889                if summary.is_empty() {
 8890                    if let Some(worktree_summaries) =
 8891                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8892                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8893                    {
 8894                        summaries.remove(&server_id);
 8895                        if summaries.is_empty() {
 8896                            worktree_summaries.remove(&path);
 8897                        }
 8898                    }
 8899                } else {
 8900                    lsp_store
 8901                        .diagnostic_summaries
 8902                        .entry(worktree_id)
 8903                        .or_default()
 8904                        .entry(path)
 8905                        .or_default()
 8906                        .insert(server_id, summary);
 8907                }
 8908
 8909                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8910                    match &mut diagnostics_summary {
 8911                        Some(diagnostics_summary) => {
 8912                            diagnostics_summary
 8913                                .more_summaries
 8914                                .push(proto::DiagnosticSummary {
 8915                                    path: project_path.path.as_ref().to_proto(),
 8916                                    language_server_id: server_id.0 as u64,
 8917                                    error_count: summary.error_count as u32,
 8918                                    warning_count: summary.warning_count as u32,
 8919                                })
 8920                        }
 8921                        None => {
 8922                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8923                                project_id: *project_id,
 8924                                worktree_id: worktree_id.to_proto(),
 8925                                summary: Some(proto::DiagnosticSummary {
 8926                                    path: project_path.path.as_ref().to_proto(),
 8927                                    language_server_id: server_id.0 as u64,
 8928                                    error_count: summary.error_count as u32,
 8929                                    warning_count: summary.warning_count as u32,
 8930                                }),
 8931                                more_summaries: Vec::new(),
 8932                            })
 8933                        }
 8934                    }
 8935                }
 8936                updated_diagnostics_paths
 8937                    .entry(server_id)
 8938                    .or_insert_with(Vec::new)
 8939                    .push(project_path);
 8940            }
 8941
 8942            if let Some((diagnostics_summary, (downstream_client, _))) =
 8943                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8944            {
 8945                downstream_client.send(diagnostics_summary).log_err();
 8946            }
 8947            for (server_id, paths) in updated_diagnostics_paths {
 8948                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8949            }
 8950            Ok(())
 8951        })?
 8952    }
 8953
 8954    async fn handle_start_language_server(
 8955        lsp_store: Entity<Self>,
 8956        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8957        mut cx: AsyncApp,
 8958    ) -> Result<()> {
 8959        let server = envelope.payload.server.context("invalid server")?;
 8960        let server_capabilities =
 8961            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8962                .with_context(|| {
 8963                    format!(
 8964                        "incorrect server capabilities {}",
 8965                        envelope.payload.capabilities
 8966                    )
 8967                })?;
 8968        lsp_store.update(&mut cx, |lsp_store, cx| {
 8969            let server_id = LanguageServerId(server.id as usize);
 8970            let server_name = LanguageServerName::from_proto(server.name.clone());
 8971            lsp_store
 8972                .lsp_server_capabilities
 8973                .insert(server_id, server_capabilities);
 8974            lsp_store.language_server_statuses.insert(
 8975                server_id,
 8976                LanguageServerStatus {
 8977                    name: server_name.clone(),
 8978                    pending_work: Default::default(),
 8979                    has_pending_diagnostic_updates: false,
 8980                    progress_tokens: Default::default(),
 8981                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8982                },
 8983            );
 8984            cx.emit(LspStoreEvent::LanguageServerAdded(
 8985                server_id,
 8986                server_name,
 8987                server.worktree_id.map(WorktreeId::from_proto),
 8988            ));
 8989            cx.notify();
 8990        })?;
 8991        Ok(())
 8992    }
 8993
 8994    async fn handle_update_language_server(
 8995        lsp_store: Entity<Self>,
 8996        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8997        mut cx: AsyncApp,
 8998    ) -> Result<()> {
 8999        lsp_store.update(&mut cx, |lsp_store, cx| {
 9000            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9001
 9002            match envelope.payload.variant.context("invalid variant")? {
 9003                proto::update_language_server::Variant::WorkStart(payload) => {
 9004                    lsp_store.on_lsp_work_start(
 9005                        language_server_id,
 9006                        payload.token,
 9007                        LanguageServerProgress {
 9008                            title: payload.title,
 9009                            is_disk_based_diagnostics_progress: false,
 9010                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9011                            message: payload.message,
 9012                            percentage: payload.percentage.map(|p| p as usize),
 9013                            last_update_at: cx.background_executor().now(),
 9014                        },
 9015                        cx,
 9016                    );
 9017                }
 9018                proto::update_language_server::Variant::WorkProgress(payload) => {
 9019                    lsp_store.on_lsp_work_progress(
 9020                        language_server_id,
 9021                        payload.token,
 9022                        LanguageServerProgress {
 9023                            title: None,
 9024                            is_disk_based_diagnostics_progress: false,
 9025                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9026                            message: payload.message,
 9027                            percentage: payload.percentage.map(|p| p as usize),
 9028                            last_update_at: cx.background_executor().now(),
 9029                        },
 9030                        cx,
 9031                    );
 9032                }
 9033
 9034                proto::update_language_server::Variant::WorkEnd(payload) => {
 9035                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 9036                }
 9037
 9038                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9039                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9040                }
 9041
 9042                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9043                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9044                }
 9045
 9046                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9047                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9048                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9049                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9050                        language_server_id,
 9051                        name: envelope
 9052                            .payload
 9053                            .server_name
 9054                            .map(SharedString::new)
 9055                            .map(LanguageServerName),
 9056                        message: non_lsp,
 9057                    });
 9058                }
 9059            }
 9060
 9061            Ok(())
 9062        })?
 9063    }
 9064
 9065    async fn handle_language_server_log(
 9066        this: Entity<Self>,
 9067        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9068        mut cx: AsyncApp,
 9069    ) -> Result<()> {
 9070        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9071        let log_type = envelope
 9072            .payload
 9073            .log_type
 9074            .map(LanguageServerLogType::from_proto)
 9075            .context("invalid language server log type")?;
 9076
 9077        let message = envelope.payload.message;
 9078
 9079        this.update(&mut cx, |_, cx| {
 9080            cx.emit(LspStoreEvent::LanguageServerLog(
 9081                language_server_id,
 9082                log_type,
 9083                message,
 9084            ));
 9085        })
 9086    }
 9087
 9088    async fn handle_lsp_ext_cancel_flycheck(
 9089        lsp_store: Entity<Self>,
 9090        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9091        cx: AsyncApp,
 9092    ) -> Result<proto::Ack> {
 9093        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9094        lsp_store.read_with(&cx, |lsp_store, _| {
 9095            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9096                server
 9097                    .notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())
 9098                    .context("handling lsp ext cancel flycheck")
 9099            } else {
 9100                anyhow::Ok(())
 9101            }
 9102        })??;
 9103
 9104        Ok(proto::Ack {})
 9105    }
 9106
 9107    async fn handle_lsp_ext_run_flycheck(
 9108        lsp_store: Entity<Self>,
 9109        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9110        mut cx: AsyncApp,
 9111    ) -> Result<proto::Ack> {
 9112        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9113        lsp_store.update(&mut cx, |lsp_store, cx| {
 9114            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9115                let text_document = if envelope.payload.current_file_only {
 9116                    let buffer_id = envelope
 9117                        .payload
 9118                        .buffer_id
 9119                        .map(|id| BufferId::new(id))
 9120                        .transpose()?;
 9121                    buffer_id
 9122                        .and_then(|buffer_id| {
 9123                            lsp_store
 9124                                .buffer_store()
 9125                                .read(cx)
 9126                                .get(buffer_id)
 9127                                .and_then(|buffer| {
 9128                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9129                                })
 9130                                .map(|path| make_text_document_identifier(&path))
 9131                        })
 9132                        .transpose()?
 9133                } else {
 9134                    None
 9135                };
 9136                server
 9137                    .notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9138                        &lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9139                    )
 9140                    .context("handling lsp ext run flycheck")
 9141            } else {
 9142                anyhow::Ok(())
 9143            }
 9144        })??;
 9145
 9146        Ok(proto::Ack {})
 9147    }
 9148
 9149    async fn handle_lsp_ext_clear_flycheck(
 9150        lsp_store: Entity<Self>,
 9151        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9152        cx: AsyncApp,
 9153    ) -> Result<proto::Ack> {
 9154        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9155        lsp_store.read_with(&cx, |lsp_store, _| {
 9156            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9157                server
 9158                    .notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())
 9159                    .context("handling lsp ext clear flycheck")
 9160            } else {
 9161                anyhow::Ok(())
 9162            }
 9163        })??;
 9164
 9165        Ok(proto::Ack {})
 9166    }
 9167
 9168    pub fn disk_based_diagnostics_started(
 9169        &mut self,
 9170        language_server_id: LanguageServerId,
 9171        cx: &mut Context<Self>,
 9172    ) {
 9173        if let Some(language_server_status) =
 9174            self.language_server_statuses.get_mut(&language_server_id)
 9175        {
 9176            language_server_status.has_pending_diagnostic_updates = true;
 9177        }
 9178
 9179        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9180        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9181            language_server_id,
 9182            name: self
 9183                .language_server_adapter_for_id(language_server_id)
 9184                .map(|adapter| adapter.name()),
 9185            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9186                Default::default(),
 9187            ),
 9188        })
 9189    }
 9190
 9191    pub fn disk_based_diagnostics_finished(
 9192        &mut self,
 9193        language_server_id: LanguageServerId,
 9194        cx: &mut Context<Self>,
 9195    ) {
 9196        if let Some(language_server_status) =
 9197            self.language_server_statuses.get_mut(&language_server_id)
 9198        {
 9199            language_server_status.has_pending_diagnostic_updates = false;
 9200        }
 9201
 9202        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9203        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9204            language_server_id,
 9205            name: self
 9206                .language_server_adapter_for_id(language_server_id)
 9207                .map(|adapter| adapter.name()),
 9208            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9209                Default::default(),
 9210            ),
 9211        })
 9212    }
 9213
 9214    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9215    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9216    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9217    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9218    // the language server might take some time to publish diagnostics.
 9219    fn simulate_disk_based_diagnostics_events_if_needed(
 9220        &mut self,
 9221        language_server_id: LanguageServerId,
 9222        cx: &mut Context<Self>,
 9223    ) {
 9224        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9225
 9226        let Some(LanguageServerState::Running {
 9227            simulate_disk_based_diagnostics_completion,
 9228            adapter,
 9229            ..
 9230        }) = self
 9231            .as_local_mut()
 9232            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9233        else {
 9234            return;
 9235        };
 9236
 9237        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9238            return;
 9239        }
 9240
 9241        let prev_task =
 9242            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9243                cx.background_executor()
 9244                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9245                    .await;
 9246
 9247                this.update(cx, |this, cx| {
 9248                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9249
 9250                    if let Some(LanguageServerState::Running {
 9251                        simulate_disk_based_diagnostics_completion,
 9252                        ..
 9253                    }) = this.as_local_mut().and_then(|local_store| {
 9254                        local_store.language_servers.get_mut(&language_server_id)
 9255                    }) {
 9256                        *simulate_disk_based_diagnostics_completion = None;
 9257                    }
 9258                })
 9259                .ok();
 9260            }));
 9261
 9262        if prev_task.is_none() {
 9263            self.disk_based_diagnostics_started(language_server_id, cx);
 9264        }
 9265    }
 9266
 9267    pub fn language_server_statuses(
 9268        &self,
 9269    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9270        self.language_server_statuses
 9271            .iter()
 9272            .map(|(key, value)| (*key, value))
 9273    }
 9274
 9275    pub(super) fn did_rename_entry(
 9276        &self,
 9277        worktree_id: WorktreeId,
 9278        old_path: &Path,
 9279        new_path: &Path,
 9280        is_dir: bool,
 9281    ) {
 9282        maybe!({
 9283            let local_store = self.as_local()?;
 9284
 9285            let old_uri = lsp::Uri::from_file_path(old_path)
 9286                .ok()
 9287                .map(|uri| uri.to_string())?;
 9288            let new_uri = lsp::Uri::from_file_path(new_path)
 9289                .ok()
 9290                .map(|uri| uri.to_string())?;
 9291
 9292            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9293                let Some(filter) = local_store
 9294                    .language_server_paths_watched_for_rename
 9295                    .get(&language_server.server_id())
 9296                else {
 9297                    continue;
 9298                };
 9299
 9300                if filter.should_send_did_rename(&old_uri, is_dir) {
 9301                    language_server
 9302                        .notify::<DidRenameFiles>(&RenameFilesParams {
 9303                            files: vec![FileRename {
 9304                                old_uri: old_uri.clone(),
 9305                                new_uri: new_uri.clone(),
 9306                            }],
 9307                        })
 9308                        .ok();
 9309                }
 9310            }
 9311            Some(())
 9312        });
 9313    }
 9314
 9315    pub(super) fn will_rename_entry(
 9316        this: WeakEntity<Self>,
 9317        worktree_id: WorktreeId,
 9318        old_path: &Path,
 9319        new_path: &Path,
 9320        is_dir: bool,
 9321        cx: AsyncApp,
 9322    ) -> Task<ProjectTransaction> {
 9323        let old_uri = lsp::Uri::from_file_path(old_path)
 9324            .ok()
 9325            .map(|uri| uri.to_string());
 9326        let new_uri = lsp::Uri::from_file_path(new_path)
 9327            .ok()
 9328            .map(|uri| uri.to_string());
 9329        cx.spawn(async move |cx| {
 9330            let mut tasks = vec![];
 9331            this.update(cx, |this, cx| {
 9332                let local_store = this.as_local()?;
 9333                let old_uri = old_uri?;
 9334                let new_uri = new_uri?;
 9335                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9336                    let Some(filter) = local_store
 9337                        .language_server_paths_watched_for_rename
 9338                        .get(&language_server.server_id())
 9339                    else {
 9340                        continue;
 9341                    };
 9342
 9343                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9344                        let apply_edit = cx.spawn({
 9345                            let old_uri = old_uri.clone();
 9346                            let new_uri = new_uri.clone();
 9347                            let language_server = language_server.clone();
 9348                            async move |this, cx| {
 9349                                let edit = language_server
 9350                                    .request::<WillRenameFiles>(RenameFilesParams {
 9351                                        files: vec![FileRename { old_uri, new_uri }],
 9352                                    })
 9353                                    .await
 9354                                    .into_response()
 9355                                    .context("will rename files")
 9356                                    .log_err()
 9357                                    .flatten()?;
 9358
 9359                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9360                                    this.upgrade()?,
 9361                                    edit,
 9362                                    false,
 9363                                    language_server.clone(),
 9364                                    cx,
 9365                                )
 9366                                .await
 9367                                .ok()?;
 9368                                Some(transaction)
 9369                            }
 9370                        });
 9371                        tasks.push(apply_edit);
 9372                    }
 9373                }
 9374                Some(())
 9375            })
 9376            .ok()
 9377            .flatten();
 9378            let mut merged_transaction = ProjectTransaction::default();
 9379            for task in tasks {
 9380                // Await on tasks sequentially so that the order of application of edits is deterministic
 9381                // (at least with regards to the order of registration of language servers)
 9382                if let Some(transaction) = task.await {
 9383                    for (buffer, buffer_transaction) in transaction.0 {
 9384                        merged_transaction.0.insert(buffer, buffer_transaction);
 9385                    }
 9386                }
 9387            }
 9388            merged_transaction
 9389        })
 9390    }
 9391
 9392    fn lsp_notify_abs_paths_changed(
 9393        &mut self,
 9394        server_id: LanguageServerId,
 9395        changes: Vec<PathEvent>,
 9396    ) {
 9397        maybe!({
 9398            let server = self.language_server_for_id(server_id)?;
 9399            let changes = changes
 9400                .into_iter()
 9401                .filter_map(|event| {
 9402                    let typ = match event.kind? {
 9403                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9404                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9405                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9406                    };
 9407                    Some(lsp::FileEvent {
 9408                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9409                        typ,
 9410                    })
 9411                })
 9412                .collect::<Vec<_>>();
 9413            if !changes.is_empty() {
 9414                server
 9415                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9416                        &lsp::DidChangeWatchedFilesParams { changes },
 9417                    )
 9418                    .ok();
 9419            }
 9420            Some(())
 9421        });
 9422    }
 9423
 9424    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9425        self.as_local()?.language_server_for_id(id)
 9426    }
 9427
 9428    fn on_lsp_progress(
 9429        &mut self,
 9430        progress: lsp::ProgressParams,
 9431        language_server_id: LanguageServerId,
 9432        disk_based_diagnostics_progress_token: Option<String>,
 9433        cx: &mut Context<Self>,
 9434    ) {
 9435        let token = match progress.token {
 9436            lsp::NumberOrString::String(token) => token,
 9437            lsp::NumberOrString::Number(token) => {
 9438                log::info!("skipping numeric progress token {}", token);
 9439                return;
 9440            }
 9441        };
 9442
 9443        match progress.value {
 9444            lsp::ProgressParamsValue::WorkDone(progress) => {
 9445                self.handle_work_done_progress(
 9446                    progress,
 9447                    language_server_id,
 9448                    disk_based_diagnostics_progress_token,
 9449                    token,
 9450                    cx,
 9451                );
 9452            }
 9453            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9454                if let Some(LanguageServerState::Running {
 9455                    workspace_refresh_task: Some(workspace_refresh_task),
 9456                    ..
 9457                }) = self
 9458                    .as_local_mut()
 9459                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9460                {
 9461                    workspace_refresh_task.progress_tx.try_send(()).ok();
 9462                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9463                }
 9464            }
 9465        }
 9466    }
 9467
 9468    fn handle_work_done_progress(
 9469        &mut self,
 9470        progress: lsp::WorkDoneProgress,
 9471        language_server_id: LanguageServerId,
 9472        disk_based_diagnostics_progress_token: Option<String>,
 9473        token: String,
 9474        cx: &mut Context<Self>,
 9475    ) {
 9476        let language_server_status =
 9477            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9478                status
 9479            } else {
 9480                return;
 9481            };
 9482
 9483        if !language_server_status.progress_tokens.contains(&token) {
 9484            return;
 9485        }
 9486
 9487        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9488            .as_ref()
 9489            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9490
 9491        match progress {
 9492            lsp::WorkDoneProgress::Begin(report) => {
 9493                if is_disk_based_diagnostics_progress {
 9494                    self.disk_based_diagnostics_started(language_server_id, cx);
 9495                }
 9496                self.on_lsp_work_start(
 9497                    language_server_id,
 9498                    token.clone(),
 9499                    LanguageServerProgress {
 9500                        title: Some(report.title),
 9501                        is_disk_based_diagnostics_progress,
 9502                        is_cancellable: report.cancellable.unwrap_or(false),
 9503                        message: report.message.clone(),
 9504                        percentage: report.percentage.map(|p| p as usize),
 9505                        last_update_at: cx.background_executor().now(),
 9506                    },
 9507                    cx,
 9508                );
 9509            }
 9510            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9511                language_server_id,
 9512                token,
 9513                LanguageServerProgress {
 9514                    title: None,
 9515                    is_disk_based_diagnostics_progress,
 9516                    is_cancellable: report.cancellable.unwrap_or(false),
 9517                    message: report.message,
 9518                    percentage: report.percentage.map(|p| p as usize),
 9519                    last_update_at: cx.background_executor().now(),
 9520                },
 9521                cx,
 9522            ),
 9523            lsp::WorkDoneProgress::End(_) => {
 9524                language_server_status.progress_tokens.remove(&token);
 9525                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9526                if is_disk_based_diagnostics_progress {
 9527                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9528                }
 9529            }
 9530        }
 9531    }
 9532
 9533    fn on_lsp_work_start(
 9534        &mut self,
 9535        language_server_id: LanguageServerId,
 9536        token: String,
 9537        progress: LanguageServerProgress,
 9538        cx: &mut Context<Self>,
 9539    ) {
 9540        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9541            status.pending_work.insert(token.clone(), progress.clone());
 9542            cx.notify();
 9543        }
 9544        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9545            language_server_id,
 9546            name: self
 9547                .language_server_adapter_for_id(language_server_id)
 9548                .map(|adapter| adapter.name()),
 9549            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9550                token,
 9551                title: progress.title,
 9552                message: progress.message,
 9553                percentage: progress.percentage.map(|p| p as u32),
 9554                is_cancellable: Some(progress.is_cancellable),
 9555            }),
 9556        })
 9557    }
 9558
 9559    fn on_lsp_work_progress(
 9560        &mut self,
 9561        language_server_id: LanguageServerId,
 9562        token: String,
 9563        progress: LanguageServerProgress,
 9564        cx: &mut Context<Self>,
 9565    ) {
 9566        let mut did_update = false;
 9567        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9568            match status.pending_work.entry(token.clone()) {
 9569                btree_map::Entry::Vacant(entry) => {
 9570                    entry.insert(progress.clone());
 9571                    did_update = true;
 9572                }
 9573                btree_map::Entry::Occupied(mut entry) => {
 9574                    let entry = entry.get_mut();
 9575                    if (progress.last_update_at - entry.last_update_at)
 9576                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9577                    {
 9578                        entry.last_update_at = progress.last_update_at;
 9579                        if progress.message.is_some() {
 9580                            entry.message = progress.message.clone();
 9581                        }
 9582                        if progress.percentage.is_some() {
 9583                            entry.percentage = progress.percentage;
 9584                        }
 9585                        if progress.is_cancellable != entry.is_cancellable {
 9586                            entry.is_cancellable = progress.is_cancellable;
 9587                        }
 9588                        did_update = true;
 9589                    }
 9590                }
 9591            }
 9592        }
 9593
 9594        if did_update {
 9595            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9596                language_server_id,
 9597                name: self
 9598                    .language_server_adapter_for_id(language_server_id)
 9599                    .map(|adapter| adapter.name()),
 9600                message: proto::update_language_server::Variant::WorkProgress(
 9601                    proto::LspWorkProgress {
 9602                        token,
 9603                        message: progress.message,
 9604                        percentage: progress.percentage.map(|p| p as u32),
 9605                        is_cancellable: Some(progress.is_cancellable),
 9606                    },
 9607                ),
 9608            })
 9609        }
 9610    }
 9611
 9612    fn on_lsp_work_end(
 9613        &mut self,
 9614        language_server_id: LanguageServerId,
 9615        token: String,
 9616        cx: &mut Context<Self>,
 9617    ) {
 9618        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9619            if let Some(work) = status.pending_work.remove(&token)
 9620                && !work.is_disk_based_diagnostics_progress
 9621            {
 9622                cx.emit(LspStoreEvent::RefreshInlayHints);
 9623            }
 9624            cx.notify();
 9625        }
 9626
 9627        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9628            language_server_id,
 9629            name: self
 9630                .language_server_adapter_for_id(language_server_id)
 9631                .map(|adapter| adapter.name()),
 9632            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9633        })
 9634    }
 9635
 9636    pub async fn handle_resolve_completion_documentation(
 9637        this: Entity<Self>,
 9638        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9639        mut cx: AsyncApp,
 9640    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9641        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9642
 9643        let completion = this
 9644            .read_with(&cx, |this, cx| {
 9645                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9646                let server = this
 9647                    .language_server_for_id(id)
 9648                    .with_context(|| format!("No language server {id}"))?;
 9649
 9650                anyhow::Ok(cx.background_spawn(async move {
 9651                    let can_resolve = server
 9652                        .capabilities()
 9653                        .completion_provider
 9654                        .as_ref()
 9655                        .and_then(|options| options.resolve_provider)
 9656                        .unwrap_or(false);
 9657                    if can_resolve {
 9658                        server
 9659                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9660                            .await
 9661                            .into_response()
 9662                            .context("resolve completion item")
 9663                    } else {
 9664                        anyhow::Ok(lsp_completion)
 9665                    }
 9666                }))
 9667            })??
 9668            .await?;
 9669
 9670        let mut documentation_is_markdown = false;
 9671        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9672        let documentation = match completion.documentation {
 9673            Some(lsp::Documentation::String(text)) => text,
 9674
 9675            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9676                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9677                value
 9678            }
 9679
 9680            _ => String::new(),
 9681        };
 9682
 9683        // If we have a new buffer_id, that means we're talking to a new client
 9684        // and want to check for new text_edits in the completion too.
 9685        let mut old_replace_start = None;
 9686        let mut old_replace_end = None;
 9687        let mut old_insert_start = None;
 9688        let mut old_insert_end = None;
 9689        let mut new_text = String::default();
 9690        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9691            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9692                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9693                anyhow::Ok(buffer.read(cx).snapshot())
 9694            })??;
 9695
 9696            if let Some(text_edit) = completion.text_edit.as_ref() {
 9697                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9698
 9699                if let Some(mut edit) = edit {
 9700                    LineEnding::normalize(&mut edit.new_text);
 9701
 9702                    new_text = edit.new_text;
 9703                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9704                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9705                    if let Some(insert_range) = edit.insert_range {
 9706                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9707                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9708                    }
 9709                }
 9710            }
 9711        }
 9712
 9713        Ok(proto::ResolveCompletionDocumentationResponse {
 9714            documentation,
 9715            documentation_is_markdown,
 9716            old_replace_start,
 9717            old_replace_end,
 9718            new_text,
 9719            lsp_completion,
 9720            old_insert_start,
 9721            old_insert_end,
 9722        })
 9723    }
 9724
 9725    async fn handle_on_type_formatting(
 9726        this: Entity<Self>,
 9727        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9728        mut cx: AsyncApp,
 9729    ) -> Result<proto::OnTypeFormattingResponse> {
 9730        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9731            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9732            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9733            let position = envelope
 9734                .payload
 9735                .position
 9736                .and_then(deserialize_anchor)
 9737                .context("invalid position")?;
 9738            anyhow::Ok(this.apply_on_type_formatting(
 9739                buffer,
 9740                position,
 9741                envelope.payload.trigger.clone(),
 9742                cx,
 9743            ))
 9744        })??;
 9745
 9746        let transaction = on_type_formatting
 9747            .await?
 9748            .as_ref()
 9749            .map(language::proto::serialize_transaction);
 9750        Ok(proto::OnTypeFormattingResponse { transaction })
 9751    }
 9752
 9753    async fn handle_refresh_inlay_hints(
 9754        this: Entity<Self>,
 9755        _: TypedEnvelope<proto::RefreshInlayHints>,
 9756        mut cx: AsyncApp,
 9757    ) -> Result<proto::Ack> {
 9758        this.update(&mut cx, |_, cx| {
 9759            cx.emit(LspStoreEvent::RefreshInlayHints);
 9760        })?;
 9761        Ok(proto::Ack {})
 9762    }
 9763
 9764    async fn handle_pull_workspace_diagnostics(
 9765        lsp_store: Entity<Self>,
 9766        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9767        mut cx: AsyncApp,
 9768    ) -> Result<proto::Ack> {
 9769        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9770        lsp_store.update(&mut cx, |lsp_store, _| {
 9771            lsp_store.pull_workspace_diagnostics(server_id);
 9772        })?;
 9773        Ok(proto::Ack {})
 9774    }
 9775
 9776    async fn handle_inlay_hints(
 9777        this: Entity<Self>,
 9778        envelope: TypedEnvelope<proto::InlayHints>,
 9779        mut cx: AsyncApp,
 9780    ) -> Result<proto::InlayHintsResponse> {
 9781        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9782        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9783        let buffer = this.update(&mut cx, |this, cx| {
 9784            this.buffer_store.read(cx).get_existing(buffer_id)
 9785        })??;
 9786        buffer
 9787            .update(&mut cx, |buffer, _| {
 9788                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9789            })?
 9790            .await
 9791            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9792
 9793        let start = envelope
 9794            .payload
 9795            .start
 9796            .and_then(deserialize_anchor)
 9797            .context("missing range start")?;
 9798        let end = envelope
 9799            .payload
 9800            .end
 9801            .and_then(deserialize_anchor)
 9802            .context("missing range end")?;
 9803        let buffer_hints = this
 9804            .update(&mut cx, |lsp_store, cx| {
 9805                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9806            })?
 9807            .await
 9808            .context("inlay hints fetch")?;
 9809
 9810        this.update(&mut cx, |project, cx| {
 9811            InlayHints::response_to_proto(
 9812                buffer_hints,
 9813                project,
 9814                sender_id,
 9815                &buffer.read(cx).version(),
 9816                cx,
 9817            )
 9818        })
 9819    }
 9820
 9821    async fn handle_get_color_presentation(
 9822        lsp_store: Entity<Self>,
 9823        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9824        mut cx: AsyncApp,
 9825    ) -> Result<proto::GetColorPresentationResponse> {
 9826        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9827        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9828            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9829        })??;
 9830
 9831        let color = envelope
 9832            .payload
 9833            .color
 9834            .context("invalid color resolve request")?;
 9835        let start = color
 9836            .lsp_range_start
 9837            .context("invalid color resolve request")?;
 9838        let end = color
 9839            .lsp_range_end
 9840            .context("invalid color resolve request")?;
 9841
 9842        let color = DocumentColor {
 9843            lsp_range: lsp::Range {
 9844                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9845                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9846            },
 9847            color: lsp::Color {
 9848                red: color.red,
 9849                green: color.green,
 9850                blue: color.blue,
 9851                alpha: color.alpha,
 9852            },
 9853            resolved: false,
 9854            color_presentations: Vec::new(),
 9855        };
 9856        let resolved_color = lsp_store
 9857            .update(&mut cx, |lsp_store, cx| {
 9858                lsp_store.resolve_color_presentation(
 9859                    color,
 9860                    buffer.clone(),
 9861                    LanguageServerId(envelope.payload.server_id as usize),
 9862                    cx,
 9863                )
 9864            })?
 9865            .await
 9866            .context("resolving color presentation")?;
 9867
 9868        Ok(proto::GetColorPresentationResponse {
 9869            presentations: resolved_color
 9870                .color_presentations
 9871                .into_iter()
 9872                .map(|presentation| proto::ColorPresentation {
 9873                    label: presentation.label.to_string(),
 9874                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9875                    additional_text_edits: presentation
 9876                        .additional_text_edits
 9877                        .into_iter()
 9878                        .map(serialize_lsp_edit)
 9879                        .collect(),
 9880                })
 9881                .collect(),
 9882        })
 9883    }
 9884
 9885    async fn handle_resolve_inlay_hint(
 9886        this: Entity<Self>,
 9887        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9888        mut cx: AsyncApp,
 9889    ) -> Result<proto::ResolveInlayHintResponse> {
 9890        let proto_hint = envelope
 9891            .payload
 9892            .hint
 9893            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9894        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9895            .context("resolved proto inlay hint conversion")?;
 9896        let buffer = this.update(&mut cx, |this, cx| {
 9897            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9898            this.buffer_store.read(cx).get_existing(buffer_id)
 9899        })??;
 9900        let response_hint = this
 9901            .update(&mut cx, |this, cx| {
 9902                this.resolve_inlay_hint(
 9903                    hint,
 9904                    buffer,
 9905                    LanguageServerId(envelope.payload.language_server_id as usize),
 9906                    cx,
 9907                )
 9908            })?
 9909            .await
 9910            .context("inlay hints fetch")?;
 9911        Ok(proto::ResolveInlayHintResponse {
 9912            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9913        })
 9914    }
 9915
 9916    async fn handle_refresh_code_lens(
 9917        this: Entity<Self>,
 9918        _: TypedEnvelope<proto::RefreshCodeLens>,
 9919        mut cx: AsyncApp,
 9920    ) -> Result<proto::Ack> {
 9921        this.update(&mut cx, |_, cx| {
 9922            cx.emit(LspStoreEvent::RefreshCodeLens);
 9923        })?;
 9924        Ok(proto::Ack {})
 9925    }
 9926
 9927    async fn handle_open_buffer_for_symbol(
 9928        this: Entity<Self>,
 9929        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9930        mut cx: AsyncApp,
 9931    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9932        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9933        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9934        let symbol = Self::deserialize_symbol(symbol)?;
 9935        let symbol = this.read_with(&cx, |this, _| {
 9936            let signature = this.symbol_signature(&symbol.path);
 9937            anyhow::ensure!(signature == symbol.signature, "invalid symbol signature");
 9938            Ok(symbol)
 9939        })??;
 9940        let buffer = this
 9941            .update(&mut cx, |this, cx| {
 9942                this.open_buffer_for_symbol(
 9943                    &Symbol {
 9944                        language_server_name: symbol.language_server_name,
 9945                        source_worktree_id: symbol.source_worktree_id,
 9946                        source_language_server_id: symbol.source_language_server_id,
 9947                        path: symbol.path,
 9948                        name: symbol.name,
 9949                        kind: symbol.kind,
 9950                        range: symbol.range,
 9951                        signature: symbol.signature,
 9952                        label: CodeLabel {
 9953                            text: Default::default(),
 9954                            runs: Default::default(),
 9955                            filter_range: Default::default(),
 9956                        },
 9957                    },
 9958                    cx,
 9959                )
 9960            })?
 9961            .await?;
 9962
 9963        this.update(&mut cx, |this, cx| {
 9964            let is_private = buffer
 9965                .read(cx)
 9966                .file()
 9967                .map(|f| f.is_private())
 9968                .unwrap_or_default();
 9969            if is_private {
 9970                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9971            } else {
 9972                this.buffer_store
 9973                    .update(cx, |buffer_store, cx| {
 9974                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9975                    })
 9976                    .detach_and_log_err(cx);
 9977                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9978                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9979            }
 9980        })?
 9981    }
 9982
 9983    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
 9984        let mut hasher = Sha256::new();
 9985        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
 9986        hasher.update(project_path.path.to_string_lossy().as_bytes());
 9987        hasher.update(self.nonce.to_be_bytes());
 9988        hasher.finalize().as_slice().try_into().unwrap()
 9989    }
 9990
 9991    pub async fn handle_get_project_symbols(
 9992        this: Entity<Self>,
 9993        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9994        mut cx: AsyncApp,
 9995    ) -> Result<proto::GetProjectSymbolsResponse> {
 9996        let symbols = this
 9997            .update(&mut cx, |this, cx| {
 9998                this.symbols(&envelope.payload.query, cx)
 9999            })?
10000            .await?;
10001
10002        Ok(proto::GetProjectSymbolsResponse {
10003            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10004        })
10005    }
10006
10007    pub async fn handle_restart_language_servers(
10008        this: Entity<Self>,
10009        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10010        mut cx: AsyncApp,
10011    ) -> Result<proto::Ack> {
10012        this.update(&mut cx, |lsp_store, cx| {
10013            let buffers =
10014                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10015            lsp_store.restart_language_servers_for_buffers(
10016                buffers,
10017                envelope
10018                    .payload
10019                    .only_servers
10020                    .into_iter()
10021                    .filter_map(|selector| {
10022                        Some(match selector.selector? {
10023                            proto::language_server_selector::Selector::ServerId(server_id) => {
10024                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10025                            }
10026                            proto::language_server_selector::Selector::Name(name) => {
10027                                LanguageServerSelector::Name(LanguageServerName(
10028                                    SharedString::from(name),
10029                                ))
10030                            }
10031                        })
10032                    })
10033                    .collect(),
10034                cx,
10035            );
10036        })?;
10037
10038        Ok(proto::Ack {})
10039    }
10040
10041    pub async fn handle_stop_language_servers(
10042        lsp_store: Entity<Self>,
10043        envelope: TypedEnvelope<proto::StopLanguageServers>,
10044        mut cx: AsyncApp,
10045    ) -> Result<proto::Ack> {
10046        lsp_store.update(&mut cx, |lsp_store, cx| {
10047            if envelope.payload.all
10048                && envelope.payload.also_servers.is_empty()
10049                && envelope.payload.buffer_ids.is_empty()
10050            {
10051                lsp_store.stop_all_language_servers(cx);
10052            } else {
10053                let buffers =
10054                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10055                lsp_store
10056                    .stop_language_servers_for_buffers(
10057                        buffers,
10058                        envelope
10059                            .payload
10060                            .also_servers
10061                            .into_iter()
10062                            .filter_map(|selector| {
10063                                Some(match selector.selector? {
10064                                    proto::language_server_selector::Selector::ServerId(
10065                                        server_id,
10066                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10067                                        server_id,
10068                                    )),
10069                                    proto::language_server_selector::Selector::Name(name) => {
10070                                        LanguageServerSelector::Name(LanguageServerName(
10071                                            SharedString::from(name),
10072                                        ))
10073                                    }
10074                                })
10075                            })
10076                            .collect(),
10077                        cx,
10078                    )
10079                    .detach_and_log_err(cx);
10080            }
10081        })?;
10082
10083        Ok(proto::Ack {})
10084    }
10085
10086    pub async fn handle_cancel_language_server_work(
10087        this: Entity<Self>,
10088        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10089        mut cx: AsyncApp,
10090    ) -> Result<proto::Ack> {
10091        this.update(&mut cx, |this, cx| {
10092            if let Some(work) = envelope.payload.work {
10093                match work {
10094                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10095                        let buffers =
10096                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10097                        this.cancel_language_server_work_for_buffers(buffers, cx);
10098                    }
10099                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10100                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10101                        this.cancel_language_server_work(server_id, work.token, cx);
10102                    }
10103                }
10104            }
10105        })?;
10106
10107        Ok(proto::Ack {})
10108    }
10109
10110    fn buffer_ids_to_buffers(
10111        &mut self,
10112        buffer_ids: impl Iterator<Item = u64>,
10113        cx: &mut Context<Self>,
10114    ) -> Vec<Entity<Buffer>> {
10115        buffer_ids
10116            .into_iter()
10117            .flat_map(|buffer_id| {
10118                self.buffer_store
10119                    .read(cx)
10120                    .get(BufferId::new(buffer_id).log_err()?)
10121            })
10122            .collect::<Vec<_>>()
10123    }
10124
10125    async fn handle_apply_additional_edits_for_completion(
10126        this: Entity<Self>,
10127        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10128        mut cx: AsyncApp,
10129    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10130        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10131            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10132            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10133            let completion = Self::deserialize_completion(
10134                envelope.payload.completion.context("invalid completion")?,
10135            )?;
10136            anyhow::Ok((buffer, completion))
10137        })??;
10138
10139        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10140            this.apply_additional_edits_for_completion(
10141                buffer,
10142                Rc::new(RefCell::new(Box::new([Completion {
10143                    replace_range: completion.replace_range,
10144                    new_text: completion.new_text,
10145                    source: completion.source,
10146                    documentation: None,
10147                    label: CodeLabel {
10148                        text: Default::default(),
10149                        runs: Default::default(),
10150                        filter_range: Default::default(),
10151                    },
10152                    insert_text_mode: None,
10153                    icon_path: None,
10154                    confirm: None,
10155                }]))),
10156                0,
10157                false,
10158                cx,
10159            )
10160        })?;
10161
10162        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10163            transaction: apply_additional_edits
10164                .await?
10165                .as_ref()
10166                .map(language::proto::serialize_transaction),
10167        })
10168    }
10169
10170    pub fn last_formatting_failure(&self) -> Option<&str> {
10171        self.last_formatting_failure.as_deref()
10172    }
10173
10174    pub fn reset_last_formatting_failure(&mut self) {
10175        self.last_formatting_failure = None;
10176    }
10177
10178    pub fn environment_for_buffer(
10179        &self,
10180        buffer: &Entity<Buffer>,
10181        cx: &mut Context<Self>,
10182    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10183        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10184            environment.update(cx, |env, cx| {
10185                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10186            })
10187        } else {
10188            Task::ready(None).shared()
10189        }
10190    }
10191
10192    pub fn format(
10193        &mut self,
10194        buffers: HashSet<Entity<Buffer>>,
10195        target: LspFormatTarget,
10196        push_to_history: bool,
10197        trigger: FormatTrigger,
10198        cx: &mut Context<Self>,
10199    ) -> Task<anyhow::Result<ProjectTransaction>> {
10200        let logger = zlog::scoped!("format");
10201        if self.as_local().is_some() {
10202            zlog::trace!(logger => "Formatting locally");
10203            let logger = zlog::scoped!(logger => "local");
10204            let buffers = buffers
10205                .into_iter()
10206                .map(|buffer_handle| {
10207                    let buffer = buffer_handle.read(cx);
10208                    let buffer_abs_path = File::from_dyn(buffer.file())
10209                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10210
10211                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10212                })
10213                .collect::<Vec<_>>();
10214
10215            cx.spawn(async move |lsp_store, cx| {
10216                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10217
10218                for (handle, abs_path, id) in buffers {
10219                    let env = lsp_store
10220                        .update(cx, |lsp_store, cx| {
10221                            lsp_store.environment_for_buffer(&handle, cx)
10222                        })?
10223                        .await;
10224
10225                    let ranges = match &target {
10226                        LspFormatTarget::Buffers => None,
10227                        LspFormatTarget::Ranges(ranges) => {
10228                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10229                        }
10230                    };
10231
10232                    formattable_buffers.push(FormattableBuffer {
10233                        handle,
10234                        abs_path,
10235                        env,
10236                        ranges,
10237                    });
10238                }
10239                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10240
10241                let format_timer = zlog::time!(logger => "Formatting buffers");
10242                let result = LocalLspStore::format_locally(
10243                    lsp_store.clone(),
10244                    formattable_buffers,
10245                    push_to_history,
10246                    trigger,
10247                    logger,
10248                    cx,
10249                )
10250                .await;
10251                format_timer.end();
10252
10253                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10254
10255                lsp_store.update(cx, |lsp_store, _| {
10256                    lsp_store.update_last_formatting_failure(&result);
10257                })?;
10258
10259                result
10260            })
10261        } else if let Some((client, project_id)) = self.upstream_client() {
10262            zlog::trace!(logger => "Formatting remotely");
10263            let logger = zlog::scoped!(logger => "remote");
10264            // Don't support formatting ranges via remote
10265            match target {
10266                LspFormatTarget::Buffers => {}
10267                LspFormatTarget::Ranges(_) => {
10268                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10269                    return Task::ready(Ok(ProjectTransaction::default()));
10270                }
10271            }
10272
10273            let buffer_store = self.buffer_store();
10274            cx.spawn(async move |lsp_store, cx| {
10275                zlog::trace!(logger => "Sending remote format request");
10276                let request_timer = zlog::time!(logger => "remote format request");
10277                let result = client
10278                    .request(proto::FormatBuffers {
10279                        project_id,
10280                        trigger: trigger as i32,
10281                        buffer_ids: buffers
10282                            .iter()
10283                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10284                            .collect::<Result<_>>()?,
10285                    })
10286                    .await
10287                    .and_then(|result| result.transaction.context("missing transaction"));
10288                request_timer.end();
10289
10290                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10291
10292                lsp_store.update(cx, |lsp_store, _| {
10293                    lsp_store.update_last_formatting_failure(&result);
10294                })?;
10295
10296                let transaction_response = result?;
10297                let _timer = zlog::time!(logger => "deserializing project transaction");
10298                buffer_store
10299                    .update(cx, |buffer_store, cx| {
10300                        buffer_store.deserialize_project_transaction(
10301                            transaction_response,
10302                            push_to_history,
10303                            cx,
10304                        )
10305                    })?
10306                    .await
10307            })
10308        } else {
10309            zlog::trace!(logger => "Not formatting");
10310            Task::ready(Ok(ProjectTransaction::default()))
10311        }
10312    }
10313
10314    async fn handle_format_buffers(
10315        this: Entity<Self>,
10316        envelope: TypedEnvelope<proto::FormatBuffers>,
10317        mut cx: AsyncApp,
10318    ) -> Result<proto::FormatBuffersResponse> {
10319        let sender_id = envelope.original_sender_id().unwrap_or_default();
10320        let format = this.update(&mut cx, |this, cx| {
10321            let mut buffers = HashSet::default();
10322            for buffer_id in &envelope.payload.buffer_ids {
10323                let buffer_id = BufferId::new(*buffer_id)?;
10324                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10325            }
10326            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10327            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10328        })??;
10329
10330        let project_transaction = format.await?;
10331        let project_transaction = this.update(&mut cx, |this, cx| {
10332            this.buffer_store.update(cx, |buffer_store, cx| {
10333                buffer_store.serialize_project_transaction_for_peer(
10334                    project_transaction,
10335                    sender_id,
10336                    cx,
10337                )
10338            })
10339        })?;
10340        Ok(proto::FormatBuffersResponse {
10341            transaction: Some(project_transaction),
10342        })
10343    }
10344
10345    async fn handle_apply_code_action_kind(
10346        this: Entity<Self>,
10347        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10348        mut cx: AsyncApp,
10349    ) -> Result<proto::ApplyCodeActionKindResponse> {
10350        let sender_id = envelope.original_sender_id().unwrap_or_default();
10351        let format = this.update(&mut cx, |this, cx| {
10352            let mut buffers = HashSet::default();
10353            for buffer_id in &envelope.payload.buffer_ids {
10354                let buffer_id = BufferId::new(*buffer_id)?;
10355                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10356            }
10357            let kind = match envelope.payload.kind.as_str() {
10358                "" => CodeActionKind::EMPTY,
10359                "quickfix" => CodeActionKind::QUICKFIX,
10360                "refactor" => CodeActionKind::REFACTOR,
10361                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10362                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10363                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10364                "source" => CodeActionKind::SOURCE,
10365                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10366                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10367                _ => anyhow::bail!(
10368                    "Invalid code action kind {}",
10369                    envelope.payload.kind.as_str()
10370                ),
10371            };
10372            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10373        })??;
10374
10375        let project_transaction = format.await?;
10376        let project_transaction = this.update(&mut cx, |this, cx| {
10377            this.buffer_store.update(cx, |buffer_store, cx| {
10378                buffer_store.serialize_project_transaction_for_peer(
10379                    project_transaction,
10380                    sender_id,
10381                    cx,
10382                )
10383            })
10384        })?;
10385        Ok(proto::ApplyCodeActionKindResponse {
10386            transaction: Some(project_transaction),
10387        })
10388    }
10389
10390    async fn shutdown_language_server(
10391        server_state: Option<LanguageServerState>,
10392        name: LanguageServerName,
10393        cx: &mut AsyncApp,
10394    ) {
10395        let server = match server_state {
10396            Some(LanguageServerState::Starting { startup, .. }) => {
10397                let mut timer = cx
10398                    .background_executor()
10399                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10400                    .fuse();
10401
10402                select! {
10403                    server = startup.fuse() => server,
10404                    () = timer => {
10405                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10406                        None
10407                    },
10408                }
10409            }
10410
10411            Some(LanguageServerState::Running { server, .. }) => Some(server),
10412
10413            None => None,
10414        };
10415
10416        if let Some(server) = server
10417            && let Some(shutdown) = server.shutdown()
10418        {
10419            shutdown.await;
10420        }
10421    }
10422
10423    // Returns a list of all of the worktrees which no longer have a language server and the root path
10424    // for the stopped server
10425    fn stop_local_language_server(
10426        &mut self,
10427        server_id: LanguageServerId,
10428        cx: &mut Context<Self>,
10429    ) -> Task<()> {
10430        let local = match &mut self.mode {
10431            LspStoreMode::Local(local) => local,
10432            _ => {
10433                return Task::ready(());
10434            }
10435        };
10436
10437        // Remove this server ID from all entries in the given worktree.
10438        local
10439            .language_server_ids
10440            .retain(|_, state| state.id != server_id);
10441        self.buffer_store.update(cx, |buffer_store, cx| {
10442            for buffer in buffer_store.buffers() {
10443                buffer.update(cx, |buffer, cx| {
10444                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10445                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10446                });
10447            }
10448        });
10449
10450        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10451            summaries.retain(|path, summaries_by_server_id| {
10452                if summaries_by_server_id.remove(&server_id).is_some() {
10453                    if let Some((client, project_id)) = self.downstream_client.clone() {
10454                        client
10455                            .send(proto::UpdateDiagnosticSummary {
10456                                project_id,
10457                                worktree_id: worktree_id.to_proto(),
10458                                summary: Some(proto::DiagnosticSummary {
10459                                    path: path.as_ref().to_proto(),
10460                                    language_server_id: server_id.0 as u64,
10461                                    error_count: 0,
10462                                    warning_count: 0,
10463                                }),
10464                                more_summaries: Vec::new(),
10465                            })
10466                            .log_err();
10467                    }
10468                    !summaries_by_server_id.is_empty()
10469                } else {
10470                    true
10471                }
10472            });
10473        }
10474
10475        let local = self.as_local_mut().unwrap();
10476        for diagnostics in local.diagnostics.values_mut() {
10477            diagnostics.retain(|_, diagnostics_by_server_id| {
10478                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10479                    diagnostics_by_server_id.remove(ix);
10480                    !diagnostics_by_server_id.is_empty()
10481                } else {
10482                    true
10483                }
10484            });
10485        }
10486        local.language_server_watched_paths.remove(&server_id);
10487
10488        let server_state = local.language_servers.remove(&server_id);
10489        self.cleanup_lsp_data(server_id);
10490        let name = self
10491            .language_server_statuses
10492            .remove(&server_id)
10493            .map(|status| status.name)
10494            .or_else(|| {
10495                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10496                    Some(adapter.name())
10497                } else {
10498                    None
10499                }
10500            });
10501
10502        if let Some(name) = name {
10503            log::info!("stopping language server {name}");
10504            self.languages
10505                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10506            cx.notify();
10507
10508            return cx.spawn(async move |lsp_store, cx| {
10509                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10510                lsp_store
10511                    .update(cx, |lsp_store, cx| {
10512                        lsp_store
10513                            .languages
10514                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10515                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10516                        cx.notify();
10517                    })
10518                    .ok();
10519            });
10520        }
10521
10522        if server_state.is_some() {
10523            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10524        }
10525        Task::ready(())
10526    }
10527
10528    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10529        if let Some((client, project_id)) = self.upstream_client() {
10530            let request = client.request(proto::StopLanguageServers {
10531                project_id,
10532                buffer_ids: Vec::new(),
10533                also_servers: Vec::new(),
10534                all: true,
10535            });
10536            cx.background_spawn(request).detach_and_log_err(cx);
10537        } else {
10538            let Some(local) = self.as_local_mut() else {
10539                return;
10540            };
10541            let language_servers_to_stop = local
10542                .language_server_ids
10543                .values()
10544                .map(|state| state.id)
10545                .collect();
10546            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10547            let tasks = language_servers_to_stop
10548                .into_iter()
10549                .map(|server| self.stop_local_language_server(server, cx))
10550                .collect::<Vec<_>>();
10551            cx.background_spawn(async move {
10552                futures::future::join_all(tasks).await;
10553            })
10554            .detach();
10555        }
10556    }
10557
10558    pub fn restart_language_servers_for_buffers(
10559        &mut self,
10560        buffers: Vec<Entity<Buffer>>,
10561        only_restart_servers: HashSet<LanguageServerSelector>,
10562        cx: &mut Context<Self>,
10563    ) {
10564        if let Some((client, project_id)) = self.upstream_client() {
10565            let request = client.request(proto::RestartLanguageServers {
10566                project_id,
10567                buffer_ids: buffers
10568                    .into_iter()
10569                    .map(|b| b.read(cx).remote_id().to_proto())
10570                    .collect(),
10571                only_servers: only_restart_servers
10572                    .into_iter()
10573                    .map(|selector| {
10574                        let selector = match selector {
10575                            LanguageServerSelector::Id(language_server_id) => {
10576                                proto::language_server_selector::Selector::ServerId(
10577                                    language_server_id.to_proto(),
10578                                )
10579                            }
10580                            LanguageServerSelector::Name(language_server_name) => {
10581                                proto::language_server_selector::Selector::Name(
10582                                    language_server_name.to_string(),
10583                                )
10584                            }
10585                        };
10586                        proto::LanguageServerSelector {
10587                            selector: Some(selector),
10588                        }
10589                    })
10590                    .collect(),
10591                all: false,
10592            });
10593            cx.background_spawn(request).detach_and_log_err(cx);
10594        } else {
10595            let stop_task = if only_restart_servers.is_empty() {
10596                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10597            } else {
10598                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10599            };
10600            cx.spawn(async move |lsp_store, cx| {
10601                stop_task.await;
10602                lsp_store
10603                    .update(cx, |lsp_store, cx| {
10604                        for buffer in buffers {
10605                            lsp_store.register_buffer_with_language_servers(
10606                                &buffer,
10607                                only_restart_servers.clone(),
10608                                true,
10609                                cx,
10610                            );
10611                        }
10612                    })
10613                    .ok()
10614            })
10615            .detach();
10616        }
10617    }
10618
10619    pub fn stop_language_servers_for_buffers(
10620        &mut self,
10621        buffers: Vec<Entity<Buffer>>,
10622        also_stop_servers: HashSet<LanguageServerSelector>,
10623        cx: &mut Context<Self>,
10624    ) -> Task<Result<()>> {
10625        if let Some((client, project_id)) = self.upstream_client() {
10626            let request = client.request(proto::StopLanguageServers {
10627                project_id,
10628                buffer_ids: buffers
10629                    .into_iter()
10630                    .map(|b| b.read(cx).remote_id().to_proto())
10631                    .collect(),
10632                also_servers: also_stop_servers
10633                    .into_iter()
10634                    .map(|selector| {
10635                        let selector = match selector {
10636                            LanguageServerSelector::Id(language_server_id) => {
10637                                proto::language_server_selector::Selector::ServerId(
10638                                    language_server_id.to_proto(),
10639                                )
10640                            }
10641                            LanguageServerSelector::Name(language_server_name) => {
10642                                proto::language_server_selector::Selector::Name(
10643                                    language_server_name.to_string(),
10644                                )
10645                            }
10646                        };
10647                        proto::LanguageServerSelector {
10648                            selector: Some(selector),
10649                        }
10650                    })
10651                    .collect(),
10652                all: false,
10653            });
10654            cx.background_spawn(async move {
10655                let _ = request.await?;
10656                Ok(())
10657            })
10658        } else {
10659            let task =
10660                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10661            cx.background_spawn(async move {
10662                task.await;
10663                Ok(())
10664            })
10665        }
10666    }
10667
10668    fn stop_local_language_servers_for_buffers(
10669        &mut self,
10670        buffers: &[Entity<Buffer>],
10671        also_stop_servers: HashSet<LanguageServerSelector>,
10672        cx: &mut Context<Self>,
10673    ) -> Task<()> {
10674        let Some(local) = self.as_local_mut() else {
10675            return Task::ready(());
10676        };
10677        let mut language_server_names_to_stop = BTreeSet::default();
10678        let mut language_servers_to_stop = also_stop_servers
10679            .into_iter()
10680            .flat_map(|selector| match selector {
10681                LanguageServerSelector::Id(id) => Some(id),
10682                LanguageServerSelector::Name(name) => {
10683                    language_server_names_to_stop.insert(name);
10684                    None
10685                }
10686            })
10687            .collect::<BTreeSet<_>>();
10688
10689        let mut covered_worktrees = HashSet::default();
10690        for buffer in buffers {
10691            buffer.update(cx, |buffer, cx| {
10692                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10693                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10694                    && covered_worktrees.insert(worktree_id)
10695                {
10696                    language_server_names_to_stop.retain(|name| {
10697                        let old_ids_count = language_servers_to_stop.len();
10698                        let all_language_servers_with_this_name = local
10699                            .language_server_ids
10700                            .iter()
10701                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10702                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10703                        old_ids_count == language_servers_to_stop.len()
10704                    });
10705                }
10706            });
10707        }
10708        for name in language_server_names_to_stop {
10709            language_servers_to_stop.extend(
10710                local
10711                    .language_server_ids
10712                    .iter()
10713                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10714            );
10715        }
10716
10717        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10718        let tasks = language_servers_to_stop
10719            .into_iter()
10720            .map(|server| self.stop_local_language_server(server, cx))
10721            .collect::<Vec<_>>();
10722
10723        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10724    }
10725
10726    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10727        let (worktree, relative_path) =
10728            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10729
10730        let project_path = ProjectPath {
10731            worktree_id: worktree.read(cx).id(),
10732            path: relative_path.into(),
10733        };
10734
10735        Some(
10736            self.buffer_store()
10737                .read(cx)
10738                .get_by_path(&project_path)?
10739                .read(cx),
10740        )
10741    }
10742
10743    #[cfg(any(test, feature = "test-support"))]
10744    pub fn update_diagnostics(
10745        &mut self,
10746        server_id: LanguageServerId,
10747        diagnostics: lsp::PublishDiagnosticsParams,
10748        result_id: Option<String>,
10749        source_kind: DiagnosticSourceKind,
10750        disk_based_sources: &[String],
10751        cx: &mut Context<Self>,
10752    ) -> Result<()> {
10753        self.merge_lsp_diagnostics(
10754            source_kind,
10755            vec![DocumentDiagnosticsUpdate {
10756                diagnostics,
10757                result_id,
10758                server_id,
10759                disk_based_sources: Cow::Borrowed(disk_based_sources),
10760            }],
10761            |_, _, _| false,
10762            cx,
10763        )
10764    }
10765
10766    pub fn merge_lsp_diagnostics(
10767        &mut self,
10768        source_kind: DiagnosticSourceKind,
10769        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10770        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10771        cx: &mut Context<Self>,
10772    ) -> Result<()> {
10773        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10774        let updates = lsp_diagnostics
10775            .into_iter()
10776            .filter_map(|update| {
10777                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10778                Some(DocumentDiagnosticsUpdate {
10779                    diagnostics: self.lsp_to_document_diagnostics(
10780                        abs_path,
10781                        source_kind,
10782                        update.server_id,
10783                        update.diagnostics,
10784                        &update.disk_based_sources,
10785                    ),
10786                    result_id: update.result_id,
10787                    server_id: update.server_id,
10788                    disk_based_sources: update.disk_based_sources,
10789                })
10790            })
10791            .collect();
10792        self.merge_diagnostic_entries(updates, merge, cx)?;
10793        Ok(())
10794    }
10795
10796    fn lsp_to_document_diagnostics(
10797        &mut self,
10798        document_abs_path: PathBuf,
10799        source_kind: DiagnosticSourceKind,
10800        server_id: LanguageServerId,
10801        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10802        disk_based_sources: &[String],
10803    ) -> DocumentDiagnostics {
10804        let mut diagnostics = Vec::default();
10805        let mut primary_diagnostic_group_ids = HashMap::default();
10806        let mut sources_by_group_id = HashMap::default();
10807        let mut supporting_diagnostics = HashMap::default();
10808
10809        let adapter = self.language_server_adapter_for_id(server_id);
10810
10811        // Ensure that primary diagnostics are always the most severe
10812        lsp_diagnostics
10813            .diagnostics
10814            .sort_by_key(|item| item.severity);
10815
10816        for diagnostic in &lsp_diagnostics.diagnostics {
10817            let source = diagnostic.source.as_ref();
10818            let range = range_from_lsp(diagnostic.range);
10819            let is_supporting = diagnostic
10820                .related_information
10821                .as_ref()
10822                .is_some_and(|infos| {
10823                    infos.iter().any(|info| {
10824                        primary_diagnostic_group_ids.contains_key(&(
10825                            source,
10826                            diagnostic.code.clone(),
10827                            range_from_lsp(info.location.range),
10828                        ))
10829                    })
10830                });
10831
10832            let is_unnecessary = diagnostic
10833                .tags
10834                .as_ref()
10835                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10836
10837            let underline = self
10838                .language_server_adapter_for_id(server_id)
10839                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10840
10841            if is_supporting {
10842                supporting_diagnostics.insert(
10843                    (source, diagnostic.code.clone(), range),
10844                    (diagnostic.severity, is_unnecessary),
10845                );
10846            } else {
10847                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10848                let is_disk_based =
10849                    source.is_some_and(|source| disk_based_sources.contains(source));
10850
10851                sources_by_group_id.insert(group_id, source);
10852                primary_diagnostic_group_ids
10853                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10854
10855                diagnostics.push(DiagnosticEntry {
10856                    range,
10857                    diagnostic: Diagnostic {
10858                        source: diagnostic.source.clone(),
10859                        source_kind,
10860                        code: diagnostic.code.clone(),
10861                        code_description: diagnostic
10862                            .code_description
10863                            .as_ref()
10864                            .and_then(|d| d.href.clone()),
10865                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10866                        markdown: adapter.as_ref().and_then(|adapter| {
10867                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10868                        }),
10869                        message: diagnostic.message.trim().to_string(),
10870                        group_id,
10871                        is_primary: true,
10872                        is_disk_based,
10873                        is_unnecessary,
10874                        underline,
10875                        data: diagnostic.data.clone(),
10876                    },
10877                });
10878                if let Some(infos) = &diagnostic.related_information {
10879                    for info in infos {
10880                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10881                            let range = range_from_lsp(info.location.range);
10882                            diagnostics.push(DiagnosticEntry {
10883                                range,
10884                                diagnostic: Diagnostic {
10885                                    source: diagnostic.source.clone(),
10886                                    source_kind,
10887                                    code: diagnostic.code.clone(),
10888                                    code_description: diagnostic
10889                                        .code_description
10890                                        .as_ref()
10891                                        .and_then(|d| d.href.clone()),
10892                                    severity: DiagnosticSeverity::INFORMATION,
10893                                    markdown: adapter.as_ref().and_then(|adapter| {
10894                                        adapter.diagnostic_message_to_markdown(&info.message)
10895                                    }),
10896                                    message: info.message.trim().to_string(),
10897                                    group_id,
10898                                    is_primary: false,
10899                                    is_disk_based,
10900                                    is_unnecessary: false,
10901                                    underline,
10902                                    data: diagnostic.data.clone(),
10903                                },
10904                            });
10905                        }
10906                    }
10907                }
10908            }
10909        }
10910
10911        for entry in &mut diagnostics {
10912            let diagnostic = &mut entry.diagnostic;
10913            if !diagnostic.is_primary {
10914                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10915                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10916                    source,
10917                    diagnostic.code.clone(),
10918                    entry.range.clone(),
10919                )) {
10920                    if let Some(severity) = severity {
10921                        diagnostic.severity = severity;
10922                    }
10923                    diagnostic.is_unnecessary = is_unnecessary;
10924                }
10925            }
10926        }
10927
10928        DocumentDiagnostics {
10929            diagnostics,
10930            document_abs_path,
10931            version: lsp_diagnostics.version,
10932        }
10933    }
10934
10935    fn insert_newly_running_language_server(
10936        &mut self,
10937        adapter: Arc<CachedLspAdapter>,
10938        language_server: Arc<LanguageServer>,
10939        server_id: LanguageServerId,
10940        key: LanguageServerSeed,
10941        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10942        cx: &mut Context<Self>,
10943    ) {
10944        let Some(local) = self.as_local_mut() else {
10945            return;
10946        };
10947        // If the language server for this key doesn't match the server id, don't store the
10948        // server. Which will cause it to be dropped, killing the process
10949        if local
10950            .language_server_ids
10951            .get(&key)
10952            .map(|state| state.id != server_id)
10953            .unwrap_or(false)
10954        {
10955            return;
10956        }
10957
10958        // Update language_servers collection with Running variant of LanguageServerState
10959        // indicating that the server is up and running and ready
10960        let workspace_folders = workspace_folders.lock().clone();
10961        language_server.set_workspace_folders(workspace_folders);
10962
10963        local.language_servers.insert(
10964            server_id,
10965            LanguageServerState::Running {
10966                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10967                    language_server.clone(),
10968                    cx,
10969                ),
10970                adapter: adapter.clone(),
10971                server: language_server.clone(),
10972                simulate_disk_based_diagnostics_completion: None,
10973            },
10974        );
10975        local
10976            .languages
10977            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10978        if let Some(file_ops_caps) = language_server
10979            .capabilities()
10980            .workspace
10981            .as_ref()
10982            .and_then(|ws| ws.file_operations.as_ref())
10983        {
10984            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10985            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10986            if did_rename_caps.or(will_rename_caps).is_some() {
10987                let watcher = RenamePathsWatchedForServer::default()
10988                    .with_did_rename_patterns(did_rename_caps)
10989                    .with_will_rename_patterns(will_rename_caps);
10990                local
10991                    .language_server_paths_watched_for_rename
10992                    .insert(server_id, watcher);
10993            }
10994        }
10995
10996        self.language_server_statuses.insert(
10997            server_id,
10998            LanguageServerStatus {
10999                name: language_server.name(),
11000                pending_work: Default::default(),
11001                has_pending_diagnostic_updates: false,
11002                progress_tokens: Default::default(),
11003                worktree: Some(key.worktree_id),
11004            },
11005        );
11006
11007        cx.emit(LspStoreEvent::LanguageServerAdded(
11008            server_id,
11009            language_server.name(),
11010            Some(key.worktree_id),
11011        ));
11012        cx.emit(LspStoreEvent::RefreshInlayHints);
11013
11014        let server_capabilities = language_server.capabilities();
11015        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11016            downstream_client
11017                .send(proto::StartLanguageServer {
11018                    project_id: *project_id,
11019                    server: Some(proto::LanguageServer {
11020                        id: server_id.to_proto(),
11021                        name: language_server.name().to_string(),
11022                        worktree_id: Some(key.worktree_id.to_proto()),
11023                    }),
11024                    capabilities: serde_json::to_string(&server_capabilities)
11025                        .expect("serializing server LSP capabilities"),
11026                })
11027                .log_err();
11028        }
11029        self.lsp_server_capabilities
11030            .insert(server_id, server_capabilities);
11031
11032        // Tell the language server about every open buffer in the worktree that matches the language.
11033        // Also check for buffers in worktrees that reused this server
11034        let mut worktrees_using_server = vec![key.worktree_id];
11035        if let Some(local) = self.as_local() {
11036            // Find all worktrees that have this server in their language server tree
11037            for (worktree_id, servers) in &local.lsp_tree.instances {
11038                if *worktree_id != key.worktree_id {
11039                    for server_map in servers.roots.values() {
11040                        if server_map.contains_key(&key.name) {
11041                            worktrees_using_server.push(*worktree_id);
11042                        }
11043                    }
11044                }
11045            }
11046        }
11047
11048        let mut buffer_paths_registered = Vec::new();
11049        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11050            for buffer_handle in buffer_store.buffers() {
11051                let buffer = buffer_handle.read(cx);
11052                let file = match File::from_dyn(buffer.file()) {
11053                    Some(file) => file,
11054                    None => continue,
11055                };
11056                let language = match buffer.language() {
11057                    Some(language) => language,
11058                    None => continue,
11059                };
11060
11061                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11062                    || !self
11063                        .languages
11064                        .lsp_adapters(&language.name())
11065                        .iter()
11066                        .any(|a| a.name == key.name)
11067                {
11068                    continue;
11069                }
11070                // didOpen
11071                let file = match file.as_local() {
11072                    Some(file) => file,
11073                    None => continue,
11074                };
11075
11076                let local = self.as_local_mut().unwrap();
11077
11078                let buffer_id = buffer.remote_id();
11079                if local.registered_buffers.contains_key(&buffer_id) {
11080                    let versions = local
11081                        .buffer_snapshots
11082                        .entry(buffer_id)
11083                        .or_default()
11084                        .entry(server_id)
11085                        .and_modify(|_| {
11086                            assert!(
11087                            false,
11088                            "There should not be an existing snapshot for a newly inserted buffer"
11089                        )
11090                        })
11091                        .or_insert_with(|| {
11092                            vec![LspBufferSnapshot {
11093                                version: 0,
11094                                snapshot: buffer.text_snapshot(),
11095                            }]
11096                        });
11097
11098                    let snapshot = versions.last().unwrap();
11099                    let version = snapshot.version;
11100                    let initial_snapshot = &snapshot.snapshot;
11101                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11102                    language_server.register_buffer(
11103                        uri,
11104                        adapter.language_id(&language.name()),
11105                        version,
11106                        initial_snapshot.text(),
11107                    );
11108                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11109                    local
11110                        .buffers_opened_in_servers
11111                        .entry(buffer_id)
11112                        .or_default()
11113                        .insert(server_id);
11114                }
11115                buffer_handle.update(cx, |buffer, cx| {
11116                    buffer.set_completion_triggers(
11117                        server_id,
11118                        language_server
11119                            .capabilities()
11120                            .completion_provider
11121                            .as_ref()
11122                            .and_then(|provider| {
11123                                provider
11124                                    .trigger_characters
11125                                    .as_ref()
11126                                    .map(|characters| characters.iter().cloned().collect())
11127                            })
11128                            .unwrap_or_default(),
11129                        cx,
11130                    )
11131                });
11132            }
11133        });
11134
11135        for (buffer_id, abs_path) in buffer_paths_registered {
11136            cx.emit(LspStoreEvent::LanguageServerUpdate {
11137                language_server_id: server_id,
11138                name: Some(adapter.name()),
11139                message: proto::update_language_server::Variant::RegisteredForBuffer(
11140                    proto::RegisteredForBuffer {
11141                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
11142                        buffer_id: buffer_id.to_proto(),
11143                    },
11144                ),
11145            });
11146        }
11147
11148        cx.notify();
11149    }
11150
11151    pub fn language_servers_running_disk_based_diagnostics(
11152        &self,
11153    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11154        self.language_server_statuses
11155            .iter()
11156            .filter_map(|(id, status)| {
11157                if status.has_pending_diagnostic_updates {
11158                    Some(*id)
11159                } else {
11160                    None
11161                }
11162            })
11163    }
11164
11165    pub(crate) fn cancel_language_server_work_for_buffers(
11166        &mut self,
11167        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11168        cx: &mut Context<Self>,
11169    ) {
11170        if let Some((client, project_id)) = self.upstream_client() {
11171            let request = client.request(proto::CancelLanguageServerWork {
11172                project_id,
11173                work: Some(proto::cancel_language_server_work::Work::Buffers(
11174                    proto::cancel_language_server_work::Buffers {
11175                        buffer_ids: buffers
11176                            .into_iter()
11177                            .map(|b| b.read(cx).remote_id().to_proto())
11178                            .collect(),
11179                    },
11180                )),
11181            });
11182            cx.background_spawn(request).detach_and_log_err(cx);
11183        } else if let Some(local) = self.as_local() {
11184            let servers = buffers
11185                .into_iter()
11186                .flat_map(|buffer| {
11187                    buffer.update(cx, |buffer, cx| {
11188                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11189                    })
11190                })
11191                .collect::<HashSet<_>>();
11192            for server_id in servers {
11193                self.cancel_language_server_work(server_id, None, cx);
11194            }
11195        }
11196    }
11197
11198    pub(crate) fn cancel_language_server_work(
11199        &mut self,
11200        server_id: LanguageServerId,
11201        token_to_cancel: Option<String>,
11202        cx: &mut Context<Self>,
11203    ) {
11204        if let Some(local) = self.as_local() {
11205            let status = self.language_server_statuses.get(&server_id);
11206            let server = local.language_servers.get(&server_id);
11207            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11208            {
11209                for (token, progress) in &status.pending_work {
11210                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11211                        && token != token_to_cancel
11212                    {
11213                        continue;
11214                    }
11215                    if progress.is_cancellable {
11216                        server
11217                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11218                                &WorkDoneProgressCancelParams {
11219                                    token: lsp::NumberOrString::String(token.clone()),
11220                                },
11221                            )
11222                            .ok();
11223                    }
11224                }
11225            }
11226        } else if let Some((client, project_id)) = self.upstream_client() {
11227            let request = client.request(proto::CancelLanguageServerWork {
11228                project_id,
11229                work: Some(
11230                    proto::cancel_language_server_work::Work::LanguageServerWork(
11231                        proto::cancel_language_server_work::LanguageServerWork {
11232                            language_server_id: server_id.to_proto(),
11233                            token: token_to_cancel,
11234                        },
11235                    ),
11236                ),
11237            });
11238            cx.background_spawn(request).detach_and_log_err(cx);
11239        }
11240    }
11241
11242    fn register_supplementary_language_server(
11243        &mut self,
11244        id: LanguageServerId,
11245        name: LanguageServerName,
11246        server: Arc<LanguageServer>,
11247        cx: &mut Context<Self>,
11248    ) {
11249        if let Some(local) = self.as_local_mut() {
11250            local
11251                .supplementary_language_servers
11252                .insert(id, (name.clone(), server));
11253            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11254        }
11255    }
11256
11257    fn unregister_supplementary_language_server(
11258        &mut self,
11259        id: LanguageServerId,
11260        cx: &mut Context<Self>,
11261    ) {
11262        if let Some(local) = self.as_local_mut() {
11263            local.supplementary_language_servers.remove(&id);
11264            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11265        }
11266    }
11267
11268    pub(crate) fn supplementary_language_servers(
11269        &self,
11270    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11271        self.as_local().into_iter().flat_map(|local| {
11272            local
11273                .supplementary_language_servers
11274                .iter()
11275                .map(|(id, (name, _))| (*id, name.clone()))
11276        })
11277    }
11278
11279    pub fn language_server_adapter_for_id(
11280        &self,
11281        id: LanguageServerId,
11282    ) -> Option<Arc<CachedLspAdapter>> {
11283        self.as_local()
11284            .and_then(|local| local.language_servers.get(&id))
11285            .and_then(|language_server_state| match language_server_state {
11286                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11287                _ => None,
11288            })
11289    }
11290
11291    pub(super) fn update_local_worktree_language_servers(
11292        &mut self,
11293        worktree_handle: &Entity<Worktree>,
11294        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
11295        cx: &mut Context<Self>,
11296    ) {
11297        if changes.is_empty() {
11298            return;
11299        }
11300
11301        let Some(local) = self.as_local() else { return };
11302
11303        local.prettier_store.update(cx, |prettier_store, cx| {
11304            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11305        });
11306
11307        let worktree_id = worktree_handle.read(cx).id();
11308        let mut language_server_ids = local
11309            .language_server_ids
11310            .iter()
11311            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11312            .collect::<Vec<_>>();
11313        language_server_ids.sort();
11314        language_server_ids.dedup();
11315
11316        let abs_path = worktree_handle.read(cx).abs_path();
11317        for server_id in &language_server_ids {
11318            if let Some(LanguageServerState::Running { server, .. }) =
11319                local.language_servers.get(server_id)
11320                && let Some(watched_paths) = local
11321                    .language_server_watched_paths
11322                    .get(server_id)
11323                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11324            {
11325                let params = lsp::DidChangeWatchedFilesParams {
11326                    changes: changes
11327                        .iter()
11328                        .filter_map(|(path, _, change)| {
11329                            if !watched_paths.is_match(path) {
11330                                return None;
11331                            }
11332                            let typ = match change {
11333                                PathChange::Loaded => return None,
11334                                PathChange::Added => lsp::FileChangeType::CREATED,
11335                                PathChange::Removed => lsp::FileChangeType::DELETED,
11336                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11337                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11338                            };
11339                            Some(lsp::FileEvent {
11340                                uri: lsp::Uri::from_file_path(abs_path.join(path)).unwrap(),
11341                                typ,
11342                            })
11343                        })
11344                        .collect(),
11345                };
11346                if !params.changes.is_empty() {
11347                    server
11348                        .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
11349                        .ok();
11350                }
11351            }
11352        }
11353        for (path, _, _) in changes {
11354            if let Some(file_name) = path.file_name().and_then(|file_name| file_name.to_str())
11355                && local.watched_manifest_filenames.contains(file_name)
11356            {
11357                self.request_workspace_config_refresh();
11358                break;
11359            }
11360        }
11361    }
11362
11363    pub fn wait_for_remote_buffer(
11364        &mut self,
11365        id: BufferId,
11366        cx: &mut Context<Self>,
11367    ) -> Task<Result<Entity<Buffer>>> {
11368        self.buffer_store.update(cx, |buffer_store, cx| {
11369            buffer_store.wait_for_remote_buffer(id, cx)
11370        })
11371    }
11372
11373    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11374        proto::Symbol {
11375            language_server_name: symbol.language_server_name.0.to_string(),
11376            source_worktree_id: symbol.source_worktree_id.to_proto(),
11377            language_server_id: symbol.source_language_server_id.to_proto(),
11378            worktree_id: symbol.path.worktree_id.to_proto(),
11379            path: symbol.path.path.as_ref().to_proto(),
11380            name: symbol.name.clone(),
11381            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11382            start: Some(proto::PointUtf16 {
11383                row: symbol.range.start.0.row,
11384                column: symbol.range.start.0.column,
11385            }),
11386            end: Some(proto::PointUtf16 {
11387                row: symbol.range.end.0.row,
11388                column: symbol.range.end.0.column,
11389            }),
11390            signature: symbol.signature.to_vec(),
11391        }
11392    }
11393
11394    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11395        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11396        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11397        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11398        let path = ProjectPath {
11399            worktree_id,
11400            path: Arc::<Path>::from_proto(serialized_symbol.path),
11401        };
11402
11403        let start = serialized_symbol.start.context("invalid start")?;
11404        let end = serialized_symbol.end.context("invalid end")?;
11405        Ok(CoreSymbol {
11406            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11407            source_worktree_id,
11408            source_language_server_id: LanguageServerId::from_proto(
11409                serialized_symbol.language_server_id,
11410            ),
11411            path,
11412            name: serialized_symbol.name,
11413            range: Unclipped(PointUtf16::new(start.row, start.column))
11414                ..Unclipped(PointUtf16::new(end.row, end.column)),
11415            kind,
11416            signature: serialized_symbol
11417                .signature
11418                .try_into()
11419                .map_err(|_| anyhow!("invalid signature"))?,
11420        })
11421    }
11422
11423    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11424        let mut serialized_completion = proto::Completion {
11425            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11426            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11427            new_text: completion.new_text.clone(),
11428            ..proto::Completion::default()
11429        };
11430        match &completion.source {
11431            CompletionSource::Lsp {
11432                insert_range,
11433                server_id,
11434                lsp_completion,
11435                lsp_defaults,
11436                resolved,
11437            } => {
11438                let (old_insert_start, old_insert_end) = insert_range
11439                    .as_ref()
11440                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11441                    .unzip();
11442
11443                serialized_completion.old_insert_start = old_insert_start;
11444                serialized_completion.old_insert_end = old_insert_end;
11445                serialized_completion.source = proto::completion::Source::Lsp as i32;
11446                serialized_completion.server_id = server_id.0 as u64;
11447                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11448                serialized_completion.lsp_defaults = lsp_defaults
11449                    .as_deref()
11450                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11451                serialized_completion.resolved = *resolved;
11452            }
11453            CompletionSource::BufferWord {
11454                word_range,
11455                resolved,
11456            } => {
11457                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11458                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11459                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11460                serialized_completion.resolved = *resolved;
11461            }
11462            CompletionSource::Custom => {
11463                serialized_completion.source = proto::completion::Source::Custom as i32;
11464                serialized_completion.resolved = true;
11465            }
11466            CompletionSource::Dap { sort_text } => {
11467                serialized_completion.source = proto::completion::Source::Dap as i32;
11468                serialized_completion.sort_text = Some(sort_text.clone());
11469            }
11470        }
11471
11472        serialized_completion
11473    }
11474
11475    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11476        let old_replace_start = completion
11477            .old_replace_start
11478            .and_then(deserialize_anchor)
11479            .context("invalid old start")?;
11480        let old_replace_end = completion
11481            .old_replace_end
11482            .and_then(deserialize_anchor)
11483            .context("invalid old end")?;
11484        let insert_range = {
11485            match completion.old_insert_start.zip(completion.old_insert_end) {
11486                Some((start, end)) => {
11487                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11488                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11489                    Some(start..end)
11490                }
11491                None => None,
11492            }
11493        };
11494        Ok(CoreCompletion {
11495            replace_range: old_replace_start..old_replace_end,
11496            new_text: completion.new_text,
11497            source: match proto::completion::Source::from_i32(completion.source) {
11498                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11499                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11500                    insert_range,
11501                    server_id: LanguageServerId::from_proto(completion.server_id),
11502                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11503                    lsp_defaults: completion
11504                        .lsp_defaults
11505                        .as_deref()
11506                        .map(serde_json::from_slice)
11507                        .transpose()?,
11508                    resolved: completion.resolved,
11509                },
11510                Some(proto::completion::Source::BufferWord) => {
11511                    let word_range = completion
11512                        .buffer_word_start
11513                        .and_then(deserialize_anchor)
11514                        .context("invalid buffer word start")?
11515                        ..completion
11516                            .buffer_word_end
11517                            .and_then(deserialize_anchor)
11518                            .context("invalid buffer word end")?;
11519                    CompletionSource::BufferWord {
11520                        word_range,
11521                        resolved: completion.resolved,
11522                    }
11523                }
11524                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11525                    sort_text: completion
11526                        .sort_text
11527                        .context("expected sort text to exist")?,
11528                },
11529                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11530            },
11531        })
11532    }
11533
11534    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11535        let (kind, lsp_action) = match &action.lsp_action {
11536            LspAction::Action(code_action) => (
11537                proto::code_action::Kind::Action as i32,
11538                serde_json::to_vec(code_action).unwrap(),
11539            ),
11540            LspAction::Command(command) => (
11541                proto::code_action::Kind::Command as i32,
11542                serde_json::to_vec(command).unwrap(),
11543            ),
11544            LspAction::CodeLens(code_lens) => (
11545                proto::code_action::Kind::CodeLens as i32,
11546                serde_json::to_vec(code_lens).unwrap(),
11547            ),
11548        };
11549
11550        proto::CodeAction {
11551            server_id: action.server_id.0 as u64,
11552            start: Some(serialize_anchor(&action.range.start)),
11553            end: Some(serialize_anchor(&action.range.end)),
11554            lsp_action,
11555            kind,
11556            resolved: action.resolved,
11557        }
11558    }
11559
11560    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11561        let start = action
11562            .start
11563            .and_then(deserialize_anchor)
11564            .context("invalid start")?;
11565        let end = action
11566            .end
11567            .and_then(deserialize_anchor)
11568            .context("invalid end")?;
11569        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11570            Some(proto::code_action::Kind::Action) => {
11571                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11572            }
11573            Some(proto::code_action::Kind::Command) => {
11574                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11575            }
11576            Some(proto::code_action::Kind::CodeLens) => {
11577                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11578            }
11579            None => anyhow::bail!("Unknown action kind {}", action.kind),
11580        };
11581        Ok(CodeAction {
11582            server_id: LanguageServerId(action.server_id as usize),
11583            range: start..end,
11584            resolved: action.resolved,
11585            lsp_action,
11586        })
11587    }
11588
11589    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11590        match &formatting_result {
11591            Ok(_) => self.last_formatting_failure = None,
11592            Err(error) => {
11593                let error_string = format!("{error:#}");
11594                log::error!("Formatting failed: {error_string}");
11595                self.last_formatting_failure
11596                    .replace(error_string.lines().join(" "));
11597            }
11598        }
11599    }
11600
11601    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11602        self.lsp_server_capabilities.remove(&for_server);
11603        for buffer_colors in self.lsp_document_colors.values_mut() {
11604            buffer_colors.colors.remove(&for_server);
11605            buffer_colors.cache_version += 1;
11606        }
11607        for buffer_lens in self.lsp_code_lens.values_mut() {
11608            buffer_lens.lens.remove(&for_server);
11609        }
11610        if let Some(local) = self.as_local_mut() {
11611            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11612            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11613                buffer_servers.remove(&for_server);
11614            }
11615        }
11616    }
11617
11618    pub fn result_id(
11619        &self,
11620        server_id: LanguageServerId,
11621        buffer_id: BufferId,
11622        cx: &App,
11623    ) -> Option<String> {
11624        let abs_path = self
11625            .buffer_store
11626            .read(cx)
11627            .get(buffer_id)
11628            .and_then(|b| File::from_dyn(b.read(cx).file()))
11629            .map(|f| f.abs_path(cx))?;
11630        self.as_local()?
11631            .buffer_pull_diagnostics_result_ids
11632            .get(&server_id)?
11633            .get(&abs_path)?
11634            .clone()
11635    }
11636
11637    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11638        let Some(local) = self.as_local() else {
11639            return HashMap::default();
11640        };
11641        local
11642            .buffer_pull_diagnostics_result_ids
11643            .get(&server_id)
11644            .into_iter()
11645            .flatten()
11646            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11647            .collect()
11648    }
11649
11650    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11651        if let Some(LanguageServerState::Running {
11652            workspace_refresh_task: Some(workspace_refresh_task),
11653            ..
11654        }) = self
11655            .as_local_mut()
11656            .and_then(|local| local.language_servers.get_mut(&server_id))
11657        {
11658            workspace_refresh_task.refresh_tx.try_send(()).ok();
11659        }
11660    }
11661
11662    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11663        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11664            return;
11665        };
11666        let Some(local) = self.as_local_mut() else {
11667            return;
11668        };
11669
11670        for server_id in buffer.update(cx, |buffer, cx| {
11671            local.language_server_ids_for_buffer(buffer, cx)
11672        }) {
11673            if let Some(LanguageServerState::Running {
11674                workspace_refresh_task: Some(workspace_refresh_task),
11675                ..
11676            }) = local.language_servers.get_mut(&server_id)
11677            {
11678                workspace_refresh_task.refresh_tx.try_send(()).ok();
11679            }
11680        }
11681    }
11682
11683    fn apply_workspace_diagnostic_report(
11684        &mut self,
11685        server_id: LanguageServerId,
11686        report: lsp::WorkspaceDiagnosticReportResult,
11687        cx: &mut Context<Self>,
11688    ) {
11689        let workspace_diagnostics =
11690            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11691        let mut unchanged_buffers = HashSet::default();
11692        let mut changed_buffers = HashSet::default();
11693        let workspace_diagnostics_updates = workspace_diagnostics
11694            .into_iter()
11695            .filter_map(
11696                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11697                    LspPullDiagnostics::Response {
11698                        server_id,
11699                        uri,
11700                        diagnostics,
11701                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11702                    LspPullDiagnostics::Default => None,
11703                },
11704            )
11705            .fold(
11706                HashMap::default(),
11707                |mut acc, (server_id, uri, diagnostics, version)| {
11708                    let (result_id, diagnostics) = match diagnostics {
11709                        PulledDiagnostics::Unchanged { result_id } => {
11710                            unchanged_buffers.insert(uri.clone());
11711                            (Some(result_id), Vec::new())
11712                        }
11713                        PulledDiagnostics::Changed {
11714                            result_id,
11715                            diagnostics,
11716                        } => {
11717                            changed_buffers.insert(uri.clone());
11718                            (result_id, diagnostics)
11719                        }
11720                    };
11721                    let disk_based_sources = Cow::Owned(
11722                        self.language_server_adapter_for_id(server_id)
11723                            .as_ref()
11724                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11725                            .unwrap_or(&[])
11726                            .to_vec(),
11727                    );
11728                    acc.entry(server_id)
11729                        .or_insert_with(Vec::new)
11730                        .push(DocumentDiagnosticsUpdate {
11731                            server_id,
11732                            diagnostics: lsp::PublishDiagnosticsParams {
11733                                uri,
11734                                diagnostics,
11735                                version,
11736                            },
11737                            result_id,
11738                            disk_based_sources,
11739                        });
11740                    acc
11741                },
11742            );
11743
11744        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11745            self.merge_lsp_diagnostics(
11746                DiagnosticSourceKind::Pulled,
11747                diagnostic_updates,
11748                |buffer, old_diagnostic, cx| {
11749                    File::from_dyn(buffer.file())
11750                        .and_then(|file| {
11751                            let abs_path = file.as_local()?.abs_path(cx);
11752                            lsp::Uri::from_file_path(abs_path).ok()
11753                        })
11754                        .is_none_or(|buffer_uri| {
11755                            unchanged_buffers.contains(&buffer_uri)
11756                                || match old_diagnostic.source_kind {
11757                                    DiagnosticSourceKind::Pulled => {
11758                                        !changed_buffers.contains(&buffer_uri)
11759                                    }
11760                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11761                                        true
11762                                    }
11763                                }
11764                        })
11765                },
11766                cx,
11767            )
11768            .log_err();
11769        }
11770    }
11771
11772    fn register_server_capabilities(
11773        &mut self,
11774        server_id: LanguageServerId,
11775        params: lsp::RegistrationParams,
11776        cx: &mut Context<Self>,
11777    ) -> anyhow::Result<()> {
11778        let server = self
11779            .language_server_for_id(server_id)
11780            .with_context(|| format!("no server {server_id} found"))?;
11781        for reg in params.registrations {
11782            match reg.method.as_str() {
11783                "workspace/didChangeWatchedFiles" => {
11784                    if let Some(options) = reg.register_options {
11785                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11786                            let caps = serde_json::from_value(options)?;
11787                            local_lsp_store
11788                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11789                            true
11790                        } else {
11791                            false
11792                        };
11793                        if notify {
11794                            notify_server_capabilities_updated(&server, cx);
11795                        }
11796                    }
11797                }
11798                "workspace/didChangeConfiguration" => {
11799                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11800                }
11801                "workspace/didChangeWorkspaceFolders" => {
11802                    // In this case register options is an empty object, we can ignore it
11803                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11804                        supported: Some(true),
11805                        change_notifications: Some(OneOf::Right(reg.id)),
11806                    };
11807                    server.update_capabilities(|capabilities| {
11808                        capabilities
11809                            .workspace
11810                            .get_or_insert_default()
11811                            .workspace_folders = Some(caps);
11812                    });
11813                    notify_server_capabilities_updated(&server, cx);
11814                }
11815                "workspace/symbol" => {
11816                    let options = parse_register_capabilities(reg)?;
11817                    server.update_capabilities(|capabilities| {
11818                        capabilities.workspace_symbol_provider = Some(options);
11819                    });
11820                    notify_server_capabilities_updated(&server, cx);
11821                }
11822                "workspace/fileOperations" => {
11823                    if let Some(options) = reg.register_options {
11824                        let caps = serde_json::from_value(options)?;
11825                        server.update_capabilities(|capabilities| {
11826                            capabilities
11827                                .workspace
11828                                .get_or_insert_default()
11829                                .file_operations = Some(caps);
11830                        });
11831                        notify_server_capabilities_updated(&server, cx);
11832                    }
11833                }
11834                "workspace/executeCommand" => {
11835                    if let Some(options) = reg.register_options {
11836                        let options = serde_json::from_value(options)?;
11837                        server.update_capabilities(|capabilities| {
11838                            capabilities.execute_command_provider = Some(options);
11839                        });
11840                        notify_server_capabilities_updated(&server, cx);
11841                    }
11842                }
11843                "textDocument/rangeFormatting" => {
11844                    let options = parse_register_capabilities(reg)?;
11845                    server.update_capabilities(|capabilities| {
11846                        capabilities.document_range_formatting_provider = Some(options);
11847                    });
11848                    notify_server_capabilities_updated(&server, cx);
11849                }
11850                "textDocument/onTypeFormatting" => {
11851                    if let Some(options) = reg
11852                        .register_options
11853                        .map(serde_json::from_value)
11854                        .transpose()?
11855                    {
11856                        server.update_capabilities(|capabilities| {
11857                            capabilities.document_on_type_formatting_provider = Some(options);
11858                        });
11859                        notify_server_capabilities_updated(&server, cx);
11860                    }
11861                }
11862                "textDocument/formatting" => {
11863                    let options = parse_register_capabilities(reg)?;
11864                    server.update_capabilities(|capabilities| {
11865                        capabilities.document_formatting_provider = Some(options);
11866                    });
11867                    notify_server_capabilities_updated(&server, cx);
11868                }
11869                "textDocument/rename" => {
11870                    let options = parse_register_capabilities(reg)?;
11871                    server.update_capabilities(|capabilities| {
11872                        capabilities.rename_provider = Some(options);
11873                    });
11874                    notify_server_capabilities_updated(&server, cx);
11875                }
11876                "textDocument/inlayHint" => {
11877                    let options = parse_register_capabilities(reg)?;
11878                    server.update_capabilities(|capabilities| {
11879                        capabilities.inlay_hint_provider = Some(options);
11880                    });
11881                    notify_server_capabilities_updated(&server, cx);
11882                }
11883                "textDocument/documentSymbol" => {
11884                    let options = parse_register_capabilities(reg)?;
11885                    server.update_capabilities(|capabilities| {
11886                        capabilities.document_symbol_provider = Some(options);
11887                    });
11888                    notify_server_capabilities_updated(&server, cx);
11889                }
11890                "textDocument/codeAction" => {
11891                    let options = parse_register_capabilities(reg)?;
11892                    let provider = match options {
11893                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11894                        OneOf::Right(caps) => caps,
11895                    };
11896                    server.update_capabilities(|capabilities| {
11897                        capabilities.code_action_provider = Some(provider);
11898                    });
11899                    notify_server_capabilities_updated(&server, cx);
11900                }
11901                "textDocument/definition" => {
11902                    let options = parse_register_capabilities(reg)?;
11903                    server.update_capabilities(|capabilities| {
11904                        capabilities.definition_provider = Some(options);
11905                    });
11906                    notify_server_capabilities_updated(&server, cx);
11907                }
11908                "textDocument/completion" => {
11909                    if let Some(caps) = reg
11910                        .register_options
11911                        .map(serde_json::from_value)
11912                        .transpose()?
11913                    {
11914                        server.update_capabilities(|capabilities| {
11915                            capabilities.completion_provider = Some(caps);
11916                        });
11917                        notify_server_capabilities_updated(&server, cx);
11918                    }
11919                }
11920                "textDocument/hover" => {
11921                    let options = parse_register_capabilities(reg)?;
11922                    let provider = match options {
11923                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11924                        OneOf::Right(caps) => caps,
11925                    };
11926                    server.update_capabilities(|capabilities| {
11927                        capabilities.hover_provider = Some(provider);
11928                    });
11929                    notify_server_capabilities_updated(&server, cx);
11930                }
11931                "textDocument/signatureHelp" => {
11932                    if let Some(caps) = reg
11933                        .register_options
11934                        .map(serde_json::from_value)
11935                        .transpose()?
11936                    {
11937                        server.update_capabilities(|capabilities| {
11938                            capabilities.signature_help_provider = Some(caps);
11939                        });
11940                        notify_server_capabilities_updated(&server, cx);
11941                    }
11942                }
11943                "textDocument/didChange" => {
11944                    if let Some(sync_kind) = reg
11945                        .register_options
11946                        .and_then(|opts| opts.get("syncKind").cloned())
11947                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11948                        .transpose()?
11949                    {
11950                        server.update_capabilities(|capabilities| {
11951                            let mut sync_options =
11952                                Self::take_text_document_sync_options(capabilities);
11953                            sync_options.change = Some(sync_kind);
11954                            capabilities.text_document_sync =
11955                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11956                        });
11957                        notify_server_capabilities_updated(&server, cx);
11958                    }
11959                }
11960                "textDocument/didSave" => {
11961                    if let Some(include_text) = reg
11962                        .register_options
11963                        .map(|opts| {
11964                            let transpose = opts
11965                                .get("includeText")
11966                                .cloned()
11967                                .map(serde_json::from_value::<Option<bool>>)
11968                                .transpose();
11969                            match transpose {
11970                                Ok(value) => Ok(value.flatten()),
11971                                Err(e) => Err(e),
11972                            }
11973                        })
11974                        .transpose()?
11975                    {
11976                        server.update_capabilities(|capabilities| {
11977                            let mut sync_options =
11978                                Self::take_text_document_sync_options(capabilities);
11979                            sync_options.save =
11980                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11981                                    include_text,
11982                                }));
11983                            capabilities.text_document_sync =
11984                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11985                        });
11986                        notify_server_capabilities_updated(&server, cx);
11987                    }
11988                }
11989                "textDocument/codeLens" => {
11990                    if let Some(caps) = reg
11991                        .register_options
11992                        .map(serde_json::from_value)
11993                        .transpose()?
11994                    {
11995                        server.update_capabilities(|capabilities| {
11996                            capabilities.code_lens_provider = Some(caps);
11997                        });
11998                        notify_server_capabilities_updated(&server, cx);
11999                    }
12000                }
12001                "textDocument/diagnostic" => {
12002                    if let Some(caps) = reg
12003                        .register_options
12004                        .map(serde_json::from_value)
12005                        .transpose()?
12006                    {
12007                        server.update_capabilities(|capabilities| {
12008                            capabilities.diagnostic_provider = Some(caps);
12009                        });
12010                        notify_server_capabilities_updated(&server, cx);
12011                    }
12012                }
12013                "textDocument/documentColor" => {
12014                    let options = parse_register_capabilities(reg)?;
12015                    let provider = match options {
12016                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12017                        OneOf::Right(caps) => caps,
12018                    };
12019                    server.update_capabilities(|capabilities| {
12020                        capabilities.color_provider = Some(provider);
12021                    });
12022                    notify_server_capabilities_updated(&server, cx);
12023                }
12024                _ => log::warn!("unhandled capability registration: {reg:?}"),
12025            }
12026        }
12027
12028        Ok(())
12029    }
12030
12031    fn unregister_server_capabilities(
12032        &mut self,
12033        server_id: LanguageServerId,
12034        params: lsp::UnregistrationParams,
12035        cx: &mut Context<Self>,
12036    ) -> anyhow::Result<()> {
12037        let server = self
12038            .language_server_for_id(server_id)
12039            .with_context(|| format!("no server {server_id} found"))?;
12040        for unreg in params.unregisterations.iter() {
12041            match unreg.method.as_str() {
12042                "workspace/didChangeWatchedFiles" => {
12043                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12044                        local_lsp_store
12045                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12046                        true
12047                    } else {
12048                        false
12049                    };
12050                    if notify {
12051                        notify_server_capabilities_updated(&server, cx);
12052                    }
12053                }
12054                "workspace/didChangeConfiguration" => {
12055                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12056                }
12057                "workspace/didChangeWorkspaceFolders" => {
12058                    server.update_capabilities(|capabilities| {
12059                        capabilities
12060                            .workspace
12061                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12062                                workspace_folders: None,
12063                                file_operations: None,
12064                            })
12065                            .workspace_folders = None;
12066                    });
12067                    notify_server_capabilities_updated(&server, cx);
12068                }
12069                "workspace/symbol" => {
12070                    server.update_capabilities(|capabilities| {
12071                        capabilities.workspace_symbol_provider = None
12072                    });
12073                    notify_server_capabilities_updated(&server, cx);
12074                }
12075                "workspace/fileOperations" => {
12076                    server.update_capabilities(|capabilities| {
12077                        capabilities
12078                            .workspace
12079                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12080                                workspace_folders: None,
12081                                file_operations: None,
12082                            })
12083                            .file_operations = None;
12084                    });
12085                    notify_server_capabilities_updated(&server, cx);
12086                }
12087                "workspace/executeCommand" => {
12088                    server.update_capabilities(|capabilities| {
12089                        capabilities.execute_command_provider = None;
12090                    });
12091                    notify_server_capabilities_updated(&server, cx);
12092                }
12093                "textDocument/rangeFormatting" => {
12094                    server.update_capabilities(|capabilities| {
12095                        capabilities.document_range_formatting_provider = None
12096                    });
12097                    notify_server_capabilities_updated(&server, cx);
12098                }
12099                "textDocument/onTypeFormatting" => {
12100                    server.update_capabilities(|capabilities| {
12101                        capabilities.document_on_type_formatting_provider = None;
12102                    });
12103                    notify_server_capabilities_updated(&server, cx);
12104                }
12105                "textDocument/formatting" => {
12106                    server.update_capabilities(|capabilities| {
12107                        capabilities.document_formatting_provider = None;
12108                    });
12109                    notify_server_capabilities_updated(&server, cx);
12110                }
12111                "textDocument/rename" => {
12112                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12113                    notify_server_capabilities_updated(&server, cx);
12114                }
12115                "textDocument/codeAction" => {
12116                    server.update_capabilities(|capabilities| {
12117                        capabilities.code_action_provider = None;
12118                    });
12119                    notify_server_capabilities_updated(&server, cx);
12120                }
12121                "textDocument/definition" => {
12122                    server.update_capabilities(|capabilities| {
12123                        capabilities.definition_provider = None;
12124                    });
12125                    notify_server_capabilities_updated(&server, cx);
12126                }
12127                "textDocument/completion" => {
12128                    server.update_capabilities(|capabilities| {
12129                        capabilities.completion_provider = None;
12130                    });
12131                    notify_server_capabilities_updated(&server, cx);
12132                }
12133                "textDocument/hover" => {
12134                    server.update_capabilities(|capabilities| {
12135                        capabilities.hover_provider = None;
12136                    });
12137                    notify_server_capabilities_updated(&server, cx);
12138                }
12139                "textDocument/signatureHelp" => {
12140                    server.update_capabilities(|capabilities| {
12141                        capabilities.signature_help_provider = None;
12142                    });
12143                    notify_server_capabilities_updated(&server, cx);
12144                }
12145                "textDocument/didChange" => {
12146                    server.update_capabilities(|capabilities| {
12147                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12148                        sync_options.change = None;
12149                        capabilities.text_document_sync =
12150                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12151                    });
12152                    notify_server_capabilities_updated(&server, cx);
12153                }
12154                "textDocument/didSave" => {
12155                    server.update_capabilities(|capabilities| {
12156                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12157                        sync_options.save = None;
12158                        capabilities.text_document_sync =
12159                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12160                    });
12161                    notify_server_capabilities_updated(&server, cx);
12162                }
12163                "textDocument/codeLens" => {
12164                    server.update_capabilities(|capabilities| {
12165                        capabilities.code_lens_provider = None;
12166                    });
12167                    notify_server_capabilities_updated(&server, cx);
12168                }
12169                "textDocument/diagnostic" => {
12170                    server.update_capabilities(|capabilities| {
12171                        capabilities.diagnostic_provider = None;
12172                    });
12173                    notify_server_capabilities_updated(&server, cx);
12174                }
12175                "textDocument/documentColor" => {
12176                    server.update_capabilities(|capabilities| {
12177                        capabilities.color_provider = None;
12178                    });
12179                    notify_server_capabilities_updated(&server, cx);
12180                }
12181                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12182            }
12183        }
12184
12185        Ok(())
12186    }
12187
12188    async fn query_lsp_locally<T>(
12189        lsp_store: Entity<Self>,
12190        sender_id: proto::PeerId,
12191        lsp_request_id: LspRequestId,
12192        proto_request: T::ProtoRequest,
12193        position: Option<Anchor>,
12194        mut cx: AsyncApp,
12195    ) -> Result<()>
12196    where
12197        T: LspCommand + Clone,
12198        T::ProtoRequest: proto::LspRequestMessage,
12199        <T::ProtoRequest as proto::RequestMessage>::Response:
12200            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12201    {
12202        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12203        let version = deserialize_version(proto_request.buffer_version());
12204        let buffer = lsp_store.update(&mut cx, |this, cx| {
12205            this.buffer_store.read(cx).get_existing(buffer_id)
12206        })??;
12207        buffer
12208            .update(&mut cx, |buffer, _| {
12209                buffer.wait_for_version(version.clone())
12210            })?
12211            .await?;
12212        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
12213        let request =
12214            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12215        lsp_store.update(&mut cx, |lsp_store, cx| {
12216            let request_task =
12217                lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx);
12218            let existing_queries = lsp_store
12219                .running_lsp_requests
12220                .entry(TypeId::of::<T>())
12221                .or_default();
12222            if T::ProtoRequest::stop_previous_requests()
12223                || buffer_version.changed_since(&existing_queries.0)
12224            {
12225                existing_queries.1.clear();
12226            }
12227            existing_queries.1.insert(
12228                lsp_request_id,
12229                cx.spawn(async move |lsp_store, cx| {
12230                    let response = request_task.await;
12231                    lsp_store
12232                        .update(cx, |lsp_store, cx| {
12233                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12234                            {
12235                                let response = response
12236                                    .into_iter()
12237                                    .map(|(server_id, response)| {
12238                                        (
12239                                            server_id.to_proto(),
12240                                            T::response_to_proto(
12241                                                response,
12242                                                lsp_store,
12243                                                sender_id,
12244                                                &buffer_version,
12245                                                cx,
12246                                            )
12247                                            .into(),
12248                                        )
12249                                    })
12250                                    .collect::<HashMap<_, _>>();
12251                                match client.send_lsp_response::<T::ProtoRequest>(
12252                                    project_id,
12253                                    lsp_request_id,
12254                                    response,
12255                                ) {
12256                                    Ok(()) => {}
12257                                    Err(e) => {
12258                                        log::error!("Failed to send LSP response: {e:#}",)
12259                                    }
12260                                }
12261                            }
12262                        })
12263                        .ok();
12264                }),
12265            );
12266        })?;
12267        Ok(())
12268    }
12269
12270    fn take_text_document_sync_options(
12271        capabilities: &mut lsp::ServerCapabilities,
12272    ) -> lsp::TextDocumentSyncOptions {
12273        match capabilities.text_document_sync.take() {
12274            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12275            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12276                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12277                sync_options.change = Some(sync_kind);
12278                sync_options
12279            }
12280            None => lsp::TextDocumentSyncOptions::default(),
12281        }
12282    }
12283
12284    #[cfg(any(test, feature = "test-support"))]
12285    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12286        let data = self.lsp_code_lens.get_mut(&buffer_id)?;
12287        Some(data.update.take()?.1)
12288    }
12289
12290    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12291        self.downstream_client.clone()
12292    }
12293
12294    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12295        self.worktree_store.clone()
12296    }
12297}
12298
12299// Registration with registerOptions as null, should fallback to true.
12300// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12301fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12302    reg: lsp::Registration,
12303) -> Result<OneOf<bool, T>> {
12304    Ok(match reg.register_options {
12305        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12306        None => OneOf::Left(true),
12307    })
12308}
12309
12310fn subscribe_to_binary_statuses(
12311    languages: &Arc<LanguageRegistry>,
12312    cx: &mut Context<'_, LspStore>,
12313) -> Task<()> {
12314    let mut server_statuses = languages.language_server_binary_statuses();
12315    cx.spawn(async move |lsp_store, cx| {
12316        while let Some((server_name, binary_status)) = server_statuses.next().await {
12317            if lsp_store
12318                .update(cx, |_, cx| {
12319                    let mut message = None;
12320                    let binary_status = match binary_status {
12321                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12322                        BinaryStatus::CheckingForUpdate => {
12323                            proto::ServerBinaryStatus::CheckingForUpdate
12324                        }
12325                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12326                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12327                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12328                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12329                        BinaryStatus::Failed { error } => {
12330                            message = Some(error);
12331                            proto::ServerBinaryStatus::Failed
12332                        }
12333                    };
12334                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12335                        // Binary updates are about the binary that might not have any language server id at that point.
12336                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12337                        language_server_id: LanguageServerId(0),
12338                        name: Some(server_name),
12339                        message: proto::update_language_server::Variant::StatusUpdate(
12340                            proto::StatusUpdate {
12341                                message,
12342                                status: Some(proto::status_update::Status::Binary(
12343                                    binary_status as i32,
12344                                )),
12345                            },
12346                        ),
12347                    });
12348                })
12349                .is_err()
12350            {
12351                break;
12352            }
12353        }
12354    })
12355}
12356
12357fn lsp_workspace_diagnostics_refresh(
12358    server: Arc<LanguageServer>,
12359    cx: &mut Context<'_, LspStore>,
12360) -> Option<WorkspaceRefreshTask> {
12361    let identifier = match server.capabilities().diagnostic_provider? {
12362        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12363            if !diagnostic_options.workspace_diagnostics {
12364                return None;
12365            }
12366            diagnostic_options.identifier
12367        }
12368        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12369            let diagnostic_options = registration_options.diagnostic_options;
12370            if !diagnostic_options.workspace_diagnostics {
12371                return None;
12372            }
12373            diagnostic_options.identifier
12374        }
12375    };
12376
12377    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12378    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12379    refresh_tx.try_send(()).ok();
12380
12381    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12382        let mut attempts = 0;
12383        let max_attempts = 50;
12384        let mut requests = 0;
12385
12386        loop {
12387            let Some(()) = refresh_rx.recv().await else {
12388                return;
12389            };
12390
12391            'request: loop {
12392                requests += 1;
12393                if attempts > max_attempts {
12394                    log::error!(
12395                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12396                    );
12397                    return;
12398                }
12399                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12400                cx.background_executor()
12401                    .timer(Duration::from_millis(backoff_millis))
12402                    .await;
12403                attempts += 1;
12404
12405                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12406                    lsp_store
12407                        .all_result_ids(server.server_id())
12408                        .into_iter()
12409                        .filter_map(|(abs_path, result_id)| {
12410                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12411                            Some(lsp::PreviousResultId {
12412                                uri,
12413                                value: result_id,
12414                            })
12415                        })
12416                        .collect()
12417                }) else {
12418                    return;
12419                };
12420
12421                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
12422
12423                progress_rx.try_recv().ok();
12424                let timer =
12425                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12426                let progress = pin!(progress_rx.recv().fuse());
12427                let response_result = server
12428                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12429                        lsp::WorkspaceDiagnosticParams {
12430                            previous_result_ids,
12431                            identifier: identifier.clone(),
12432                            work_done_progress_params: Default::default(),
12433                            partial_result_params: lsp::PartialResultParams {
12434                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12435                            },
12436                        },
12437                        select(timer, progress).then(|either| match either {
12438                            Either::Left((message, ..)) => ready(message).left_future(),
12439                            Either::Right(..) => pending::<String>().right_future(),
12440                        }),
12441                    )
12442                    .await;
12443
12444                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12445                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12446                match response_result {
12447                    ConnectionResult::Timeout => {
12448                        log::error!("Timeout during workspace diagnostics pull");
12449                        continue 'request;
12450                    }
12451                    ConnectionResult::ConnectionReset => {
12452                        log::error!("Server closed a workspace diagnostics pull request");
12453                        continue 'request;
12454                    }
12455                    ConnectionResult::Result(Err(e)) => {
12456                        log::error!("Error during workspace diagnostics pull: {e:#}");
12457                        break 'request;
12458                    }
12459                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12460                        attempts = 0;
12461                        if lsp_store
12462                            .update(cx, |lsp_store, cx| {
12463                                lsp_store.apply_workspace_diagnostic_report(
12464                                    server.server_id(),
12465                                    pulled_diagnostics,
12466                                    cx,
12467                                )
12468                            })
12469                            .is_err()
12470                        {
12471                            return;
12472                        }
12473                        break 'request;
12474                    }
12475                }
12476            }
12477        }
12478    });
12479
12480    Some(WorkspaceRefreshTask {
12481        refresh_tx,
12482        progress_tx,
12483        task: workspace_query_language_server,
12484    })
12485}
12486
12487fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12488    let CompletionSource::BufferWord {
12489        word_range,
12490        resolved,
12491    } = &mut completion.source
12492    else {
12493        return;
12494    };
12495    if *resolved {
12496        return;
12497    }
12498
12499    if completion.new_text
12500        != snapshot
12501            .text_for_range(word_range.clone())
12502            .collect::<String>()
12503    {
12504        return;
12505    }
12506
12507    let mut offset = 0;
12508    for chunk in snapshot.chunks(word_range.clone(), true) {
12509        let end_offset = offset + chunk.text.len();
12510        if let Some(highlight_id) = chunk.syntax_highlight_id {
12511            completion
12512                .label
12513                .runs
12514                .push((offset..end_offset, highlight_id));
12515        }
12516        offset = end_offset;
12517    }
12518    *resolved = true;
12519}
12520
12521impl EventEmitter<LspStoreEvent> for LspStore {}
12522
12523fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12524    hover
12525        .contents
12526        .retain(|hover_block| !hover_block.text.trim().is_empty());
12527    if hover.contents.is_empty() {
12528        None
12529    } else {
12530        Some(hover)
12531    }
12532}
12533
12534async fn populate_labels_for_completions(
12535    new_completions: Vec<CoreCompletion>,
12536    language: Option<Arc<Language>>,
12537    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12538) -> Vec<Completion> {
12539    let lsp_completions = new_completions
12540        .iter()
12541        .filter_map(|new_completion| {
12542            new_completion
12543                .source
12544                .lsp_completion(true)
12545                .map(|lsp_completion| lsp_completion.into_owned())
12546        })
12547        .collect::<Vec<_>>();
12548
12549    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12550        lsp_adapter
12551            .labels_for_completions(&lsp_completions, language)
12552            .await
12553            .log_err()
12554            .unwrap_or_default()
12555    } else {
12556        Vec::new()
12557    }
12558    .into_iter()
12559    .fuse();
12560
12561    let mut completions = Vec::new();
12562    for completion in new_completions {
12563        match completion.source.lsp_completion(true) {
12564            Some(lsp_completion) => {
12565                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12566
12567                let mut label = labels.next().flatten().unwrap_or_else(|| {
12568                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12569                });
12570                ensure_uniform_list_compatible_label(&mut label);
12571                completions.push(Completion {
12572                    label,
12573                    documentation,
12574                    replace_range: completion.replace_range,
12575                    new_text: completion.new_text,
12576                    insert_text_mode: lsp_completion.insert_text_mode,
12577                    source: completion.source,
12578                    icon_path: None,
12579                    confirm: None,
12580                });
12581            }
12582            None => {
12583                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12584                ensure_uniform_list_compatible_label(&mut label);
12585                completions.push(Completion {
12586                    label,
12587                    documentation: None,
12588                    replace_range: completion.replace_range,
12589                    new_text: completion.new_text,
12590                    source: completion.source,
12591                    insert_text_mode: None,
12592                    icon_path: None,
12593                    confirm: None,
12594                });
12595            }
12596        }
12597    }
12598    completions
12599}
12600
12601#[derive(Debug)]
12602pub enum LanguageServerToQuery {
12603    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12604    FirstCapable,
12605    /// Query a specific language server.
12606    Other(LanguageServerId),
12607}
12608
12609#[derive(Default)]
12610struct RenamePathsWatchedForServer {
12611    did_rename: Vec<RenameActionPredicate>,
12612    will_rename: Vec<RenameActionPredicate>,
12613}
12614
12615impl RenamePathsWatchedForServer {
12616    fn with_did_rename_patterns(
12617        mut self,
12618        did_rename: Option<&FileOperationRegistrationOptions>,
12619    ) -> Self {
12620        if let Some(did_rename) = did_rename {
12621            self.did_rename = did_rename
12622                .filters
12623                .iter()
12624                .filter_map(|filter| filter.try_into().log_err())
12625                .collect();
12626        }
12627        self
12628    }
12629    fn with_will_rename_patterns(
12630        mut self,
12631        will_rename: Option<&FileOperationRegistrationOptions>,
12632    ) -> Self {
12633        if let Some(will_rename) = will_rename {
12634            self.will_rename = will_rename
12635                .filters
12636                .iter()
12637                .filter_map(|filter| filter.try_into().log_err())
12638                .collect();
12639        }
12640        self
12641    }
12642
12643    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12644        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12645    }
12646    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12647        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12648    }
12649}
12650
12651impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12652    type Error = globset::Error;
12653    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12654        Ok(Self {
12655            kind: ops.pattern.matches.clone(),
12656            glob: GlobBuilder::new(&ops.pattern.glob)
12657                .case_insensitive(
12658                    ops.pattern
12659                        .options
12660                        .as_ref()
12661                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12662                )
12663                .build()?
12664                .compile_matcher(),
12665        })
12666    }
12667}
12668struct RenameActionPredicate {
12669    glob: GlobMatcher,
12670    kind: Option<FileOperationPatternKind>,
12671}
12672
12673impl RenameActionPredicate {
12674    // Returns true if language server should be notified
12675    fn eval(&self, path: &str, is_dir: bool) -> bool {
12676        self.kind.as_ref().is_none_or(|kind| {
12677            let expected_kind = if is_dir {
12678                FileOperationPatternKind::Folder
12679            } else {
12680                FileOperationPatternKind::File
12681            };
12682            kind == &expected_kind
12683        }) && self.glob.is_match(path)
12684    }
12685}
12686
12687#[derive(Default)]
12688struct LanguageServerWatchedPaths {
12689    worktree_paths: HashMap<WorktreeId, GlobSet>,
12690    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12691}
12692
12693#[derive(Default)]
12694struct LanguageServerWatchedPathsBuilder {
12695    worktree_paths: HashMap<WorktreeId, GlobSet>,
12696    abs_paths: HashMap<Arc<Path>, GlobSet>,
12697}
12698
12699impl LanguageServerWatchedPathsBuilder {
12700    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12701        self.worktree_paths.insert(worktree_id, glob_set);
12702    }
12703    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12704        self.abs_paths.insert(path, glob_set);
12705    }
12706    fn build(
12707        self,
12708        fs: Arc<dyn Fs>,
12709        language_server_id: LanguageServerId,
12710        cx: &mut Context<LspStore>,
12711    ) -> LanguageServerWatchedPaths {
12712        let project = cx.weak_entity();
12713
12714        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12715        let abs_paths = self
12716            .abs_paths
12717            .into_iter()
12718            .map(|(abs_path, globset)| {
12719                let task = cx.spawn({
12720                    let abs_path = abs_path.clone();
12721                    let fs = fs.clone();
12722
12723                    let lsp_store = project.clone();
12724                    async move |_, cx| {
12725                        maybe!(async move {
12726                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12727                            while let Some(update) = push_updates.0.next().await {
12728                                let action = lsp_store
12729                                    .update(cx, |this, _| {
12730                                        let Some(local) = this.as_local() else {
12731                                            return ControlFlow::Break(());
12732                                        };
12733                                        let Some(watcher) = local
12734                                            .language_server_watched_paths
12735                                            .get(&language_server_id)
12736                                        else {
12737                                            return ControlFlow::Break(());
12738                                        };
12739                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12740                                            "Watched abs path is not registered with a watcher",
12741                                        );
12742                                        let matching_entries = update
12743                                            .into_iter()
12744                                            .filter(|event| globs.is_match(&event.path))
12745                                            .collect::<Vec<_>>();
12746                                        this.lsp_notify_abs_paths_changed(
12747                                            language_server_id,
12748                                            matching_entries,
12749                                        );
12750                                        ControlFlow::Continue(())
12751                                    })
12752                                    .ok()?;
12753
12754                                if action.is_break() {
12755                                    break;
12756                                }
12757                            }
12758                            Some(())
12759                        })
12760                        .await;
12761                    }
12762                });
12763                (abs_path, (globset, task))
12764            })
12765            .collect();
12766        LanguageServerWatchedPaths {
12767            worktree_paths: self.worktree_paths,
12768            abs_paths,
12769        }
12770    }
12771}
12772
12773struct LspBufferSnapshot {
12774    version: i32,
12775    snapshot: TextBufferSnapshot,
12776}
12777
12778/// A prompt requested by LSP server.
12779#[derive(Clone, Debug)]
12780pub struct LanguageServerPromptRequest {
12781    pub level: PromptLevel,
12782    pub message: String,
12783    pub actions: Vec<MessageActionItem>,
12784    pub lsp_name: String,
12785    pub(crate) response_channel: Sender<MessageActionItem>,
12786}
12787
12788impl LanguageServerPromptRequest {
12789    pub async fn respond(self, index: usize) -> Option<()> {
12790        if let Some(response) = self.actions.into_iter().nth(index) {
12791            self.response_channel.send(response).await.ok()
12792        } else {
12793            None
12794        }
12795    }
12796}
12797impl PartialEq for LanguageServerPromptRequest {
12798    fn eq(&self, other: &Self) -> bool {
12799        self.message == other.message && self.actions == other.actions
12800    }
12801}
12802
12803#[derive(Clone, Debug, PartialEq)]
12804pub enum LanguageServerLogType {
12805    Log(MessageType),
12806    Trace { verbose_info: Option<String> },
12807    Rpc { received: bool },
12808}
12809
12810impl LanguageServerLogType {
12811    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12812        match self {
12813            Self::Log(log_type) => {
12814                use proto::log_message::LogLevel;
12815                let level = match *log_type {
12816                    MessageType::ERROR => LogLevel::Error,
12817                    MessageType::WARNING => LogLevel::Warning,
12818                    MessageType::INFO => LogLevel::Info,
12819                    MessageType::LOG => LogLevel::Log,
12820                    other => {
12821                        log::warn!("Unknown lsp log message type: {other:?}");
12822                        LogLevel::Log
12823                    }
12824                };
12825                proto::language_server_log::LogType::Log(proto::LogMessage {
12826                    level: level as i32,
12827                })
12828            }
12829            Self::Trace { verbose_info } => {
12830                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12831                    verbose_info: verbose_info.to_owned(),
12832                })
12833            }
12834            Self::Rpc { received } => {
12835                let kind = if *received {
12836                    proto::rpc_message::Kind::Received
12837                } else {
12838                    proto::rpc_message::Kind::Sent
12839                };
12840                let kind = kind as i32;
12841                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12842            }
12843        }
12844    }
12845
12846    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12847        use proto::log_message::LogLevel;
12848        use proto::rpc_message;
12849        match log_type {
12850            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12851                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12852                    LogLevel::Error => MessageType::ERROR,
12853                    LogLevel::Warning => MessageType::WARNING,
12854                    LogLevel::Info => MessageType::INFO,
12855                    LogLevel::Log => MessageType::LOG,
12856                },
12857            ),
12858            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12859                verbose_info: trace_message.verbose_info,
12860            },
12861            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12862                received: match rpc_message::Kind::from_i32(message.kind)
12863                    .unwrap_or(rpc_message::Kind::Received)
12864                {
12865                    rpc_message::Kind::Received => true,
12866                    rpc_message::Kind::Sent => false,
12867                },
12868            },
12869        }
12870    }
12871}
12872
12873pub struct WorkspaceRefreshTask {
12874    refresh_tx: mpsc::Sender<()>,
12875    progress_tx: mpsc::Sender<()>,
12876    #[allow(dead_code)]
12877    task: Task<()>,
12878}
12879
12880pub enum LanguageServerState {
12881    Starting {
12882        startup: Task<Option<Arc<LanguageServer>>>,
12883        /// List of language servers that will be added to the workspace once it's initialization completes.
12884        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
12885    },
12886
12887    Running {
12888        adapter: Arc<CachedLspAdapter>,
12889        server: Arc<LanguageServer>,
12890        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12891        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12892    },
12893}
12894
12895impl LanguageServerState {
12896    fn add_workspace_folder(&self, uri: Uri) {
12897        match self {
12898            LanguageServerState::Starting {
12899                pending_workspace_folders,
12900                ..
12901            } => {
12902                pending_workspace_folders.lock().insert(uri);
12903            }
12904            LanguageServerState::Running { server, .. } => {
12905                server.add_workspace_folder(uri);
12906            }
12907        }
12908    }
12909    fn _remove_workspace_folder(&self, uri: Uri) {
12910        match self {
12911            LanguageServerState::Starting {
12912                pending_workspace_folders,
12913                ..
12914            } => {
12915                pending_workspace_folders.lock().remove(&uri);
12916            }
12917            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12918        }
12919    }
12920}
12921
12922impl std::fmt::Debug for LanguageServerState {
12923    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12924        match self {
12925            LanguageServerState::Starting { .. } => {
12926                f.debug_struct("LanguageServerState::Starting").finish()
12927            }
12928            LanguageServerState::Running { .. } => {
12929                f.debug_struct("LanguageServerState::Running").finish()
12930            }
12931        }
12932    }
12933}
12934
12935#[derive(Clone, Debug, Serialize)]
12936pub struct LanguageServerProgress {
12937    pub is_disk_based_diagnostics_progress: bool,
12938    pub is_cancellable: bool,
12939    pub title: Option<String>,
12940    pub message: Option<String>,
12941    pub percentage: Option<usize>,
12942    #[serde(skip_serializing)]
12943    pub last_update_at: Instant,
12944}
12945
12946#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12947pub struct DiagnosticSummary {
12948    pub error_count: usize,
12949    pub warning_count: usize,
12950}
12951
12952impl DiagnosticSummary {
12953    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12954        let mut this = Self {
12955            error_count: 0,
12956            warning_count: 0,
12957        };
12958
12959        for entry in diagnostics {
12960            if entry.diagnostic.is_primary {
12961                match entry.diagnostic.severity {
12962                    DiagnosticSeverity::ERROR => this.error_count += 1,
12963                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12964                    _ => {}
12965                }
12966            }
12967        }
12968
12969        this
12970    }
12971
12972    pub fn is_empty(&self) -> bool {
12973        self.error_count == 0 && self.warning_count == 0
12974    }
12975
12976    pub fn to_proto(
12977        self,
12978        language_server_id: LanguageServerId,
12979        path: &Path,
12980    ) -> proto::DiagnosticSummary {
12981        proto::DiagnosticSummary {
12982            path: path.to_proto(),
12983            language_server_id: language_server_id.0 as u64,
12984            error_count: self.error_count as u32,
12985            warning_count: self.warning_count as u32,
12986        }
12987    }
12988}
12989
12990#[derive(Clone, Debug)]
12991pub enum CompletionDocumentation {
12992    /// There is no documentation for this completion.
12993    Undocumented,
12994    /// A single line of documentation.
12995    SingleLine(SharedString),
12996    /// Multiple lines of plain text documentation.
12997    MultiLinePlainText(SharedString),
12998    /// Markdown documentation.
12999    MultiLineMarkdown(SharedString),
13000    /// Both single line and multiple lines of plain text documentation.
13001    SingleLineAndMultiLinePlainText {
13002        single_line: SharedString,
13003        plain_text: Option<SharedString>,
13004    },
13005}
13006
13007impl CompletionDocumentation {
13008    #[cfg(any(test, feature = "test-support"))]
13009    pub fn text(&self) -> SharedString {
13010        match self {
13011            CompletionDocumentation::Undocumented => "".into(),
13012            CompletionDocumentation::SingleLine(s) => s.clone(),
13013            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13014            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13015            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13016                single_line.clone()
13017            }
13018        }
13019    }
13020}
13021
13022impl From<lsp::Documentation> for CompletionDocumentation {
13023    fn from(docs: lsp::Documentation) -> Self {
13024        match docs {
13025            lsp::Documentation::String(text) => {
13026                if text.lines().count() <= 1 {
13027                    CompletionDocumentation::SingleLine(text.into())
13028                } else {
13029                    CompletionDocumentation::MultiLinePlainText(text.into())
13030                }
13031            }
13032
13033            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13034                lsp::MarkupKind::PlainText => {
13035                    if value.lines().count() <= 1 {
13036                        CompletionDocumentation::SingleLine(value.into())
13037                    } else {
13038                        CompletionDocumentation::MultiLinePlainText(value.into())
13039                    }
13040                }
13041
13042                lsp::MarkupKind::Markdown => {
13043                    CompletionDocumentation::MultiLineMarkdown(value.into())
13044                }
13045            },
13046        }
13047    }
13048}
13049
13050fn glob_literal_prefix(glob: &Path) -> PathBuf {
13051    glob.components()
13052        .take_while(|component| match component {
13053            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13054            _ => true,
13055        })
13056        .collect()
13057}
13058
13059pub struct SshLspAdapter {
13060    name: LanguageServerName,
13061    binary: LanguageServerBinary,
13062    initialization_options: Option<String>,
13063    code_action_kinds: Option<Vec<CodeActionKind>>,
13064}
13065
13066impl SshLspAdapter {
13067    pub fn new(
13068        name: LanguageServerName,
13069        binary: LanguageServerBinary,
13070        initialization_options: Option<String>,
13071        code_action_kinds: Option<String>,
13072    ) -> Self {
13073        Self {
13074            name,
13075            binary,
13076            initialization_options,
13077            code_action_kinds: code_action_kinds
13078                .as_ref()
13079                .and_then(|c| serde_json::from_str(c).ok()),
13080        }
13081    }
13082}
13083
13084#[async_trait(?Send)]
13085impl LspAdapter for SshLspAdapter {
13086    fn name(&self) -> LanguageServerName {
13087        self.name.clone()
13088    }
13089
13090    async fn initialization_options(
13091        self: Arc<Self>,
13092        _: &dyn Fs,
13093        _: &Arc<dyn LspAdapterDelegate>,
13094    ) -> Result<Option<serde_json::Value>> {
13095        let Some(options) = &self.initialization_options else {
13096            return Ok(None);
13097        };
13098        let result = serde_json::from_str(options)?;
13099        Ok(result)
13100    }
13101
13102    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13103        self.code_action_kinds.clone()
13104    }
13105
13106    async fn check_if_user_installed(
13107        &self,
13108        _: &dyn LspAdapterDelegate,
13109        _: Option<Toolchain>,
13110        _: &AsyncApp,
13111    ) -> Option<LanguageServerBinary> {
13112        Some(self.binary.clone())
13113    }
13114
13115    async fn cached_server_binary(
13116        &self,
13117        _: PathBuf,
13118        _: &dyn LspAdapterDelegate,
13119    ) -> Option<LanguageServerBinary> {
13120        None
13121    }
13122
13123    async fn fetch_latest_server_version(
13124        &self,
13125        _: &dyn LspAdapterDelegate,
13126        _: &AsyncApp,
13127    ) -> Result<Box<dyn 'static + Send + Any>> {
13128        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13129    }
13130
13131    async fn fetch_server_binary(
13132        &self,
13133        _: Box<dyn 'static + Send + Any>,
13134        _: PathBuf,
13135        _: &dyn LspAdapterDelegate,
13136    ) -> Result<LanguageServerBinary> {
13137        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13138    }
13139}
13140
13141pub fn language_server_settings<'a>(
13142    delegate: &'a dyn LspAdapterDelegate,
13143    language: &LanguageServerName,
13144    cx: &'a App,
13145) -> Option<&'a LspSettings> {
13146    language_server_settings_for(
13147        SettingsLocation {
13148            worktree_id: delegate.worktree_id(),
13149            path: delegate.worktree_root_path(),
13150        },
13151        language,
13152        cx,
13153    )
13154}
13155
13156pub(crate) fn language_server_settings_for<'a>(
13157    location: SettingsLocation<'a>,
13158    language: &LanguageServerName,
13159    cx: &'a App,
13160) -> Option<&'a LspSettings> {
13161    ProjectSettings::get(Some(location), cx).lsp.get(language)
13162}
13163
13164pub struct LocalLspAdapterDelegate {
13165    lsp_store: WeakEntity<LspStore>,
13166    worktree: worktree::Snapshot,
13167    fs: Arc<dyn Fs>,
13168    http_client: Arc<dyn HttpClient>,
13169    language_registry: Arc<LanguageRegistry>,
13170    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13171}
13172
13173impl LocalLspAdapterDelegate {
13174    pub fn new(
13175        language_registry: Arc<LanguageRegistry>,
13176        environment: &Entity<ProjectEnvironment>,
13177        lsp_store: WeakEntity<LspStore>,
13178        worktree: &Entity<Worktree>,
13179        http_client: Arc<dyn HttpClient>,
13180        fs: Arc<dyn Fs>,
13181        cx: &mut App,
13182    ) -> Arc<Self> {
13183        let load_shell_env_task = environment.update(cx, |env, cx| {
13184            env.get_worktree_environment(worktree.clone(), cx)
13185        });
13186
13187        Arc::new(Self {
13188            lsp_store,
13189            worktree: worktree.read(cx).snapshot(),
13190            fs,
13191            http_client,
13192            language_registry,
13193            load_shell_env_task,
13194        })
13195    }
13196
13197    fn from_local_lsp(
13198        local: &LocalLspStore,
13199        worktree: &Entity<Worktree>,
13200        cx: &mut App,
13201    ) -> Arc<Self> {
13202        Self::new(
13203            local.languages.clone(),
13204            &local.environment,
13205            local.weak.clone(),
13206            worktree,
13207            local.http_client.clone(),
13208            local.fs.clone(),
13209            cx,
13210        )
13211    }
13212}
13213
13214#[async_trait]
13215impl LspAdapterDelegate for LocalLspAdapterDelegate {
13216    fn show_notification(&self, message: &str, cx: &mut App) {
13217        self.lsp_store
13218            .update(cx, |_, cx| {
13219                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13220            })
13221            .ok();
13222    }
13223
13224    fn http_client(&self) -> Arc<dyn HttpClient> {
13225        self.http_client.clone()
13226    }
13227
13228    fn worktree_id(&self) -> WorktreeId {
13229        self.worktree.id()
13230    }
13231
13232    fn worktree_root_path(&self) -> &Path {
13233        self.worktree.abs_path().as_ref()
13234    }
13235
13236    async fn shell_env(&self) -> HashMap<String, String> {
13237        let task = self.load_shell_env_task.clone();
13238        task.await.unwrap_or_default()
13239    }
13240
13241    async fn npm_package_installed_version(
13242        &self,
13243        package_name: &str,
13244    ) -> Result<Option<(PathBuf, String)>> {
13245        let local_package_directory = self.worktree_root_path();
13246        let node_modules_directory = local_package_directory.join("node_modules");
13247
13248        if let Some(version) =
13249            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13250        {
13251            return Ok(Some((node_modules_directory, version)));
13252        }
13253        let Some(npm) = self.which("npm".as_ref()).await else {
13254            log::warn!(
13255                "Failed to find npm executable for {:?}",
13256                local_package_directory
13257            );
13258            return Ok(None);
13259        };
13260
13261        let env = self.shell_env().await;
13262        let output = util::command::new_smol_command(&npm)
13263            .args(["root", "-g"])
13264            .envs(env)
13265            .current_dir(local_package_directory)
13266            .output()
13267            .await?;
13268        let global_node_modules =
13269            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13270
13271        if let Some(version) =
13272            read_package_installed_version(global_node_modules.clone(), package_name).await?
13273        {
13274            return Ok(Some((global_node_modules, version)));
13275        }
13276        return Ok(None);
13277    }
13278
13279    #[cfg(not(target_os = "windows"))]
13280    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13281        let worktree_abs_path = self.worktree.abs_path();
13282        let shell_path = self.shell_env().await.get("PATH").cloned();
13283        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13284    }
13285
13286    #[cfg(target_os = "windows")]
13287    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13288        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
13289        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
13290        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
13291        which::which(command).ok()
13292    }
13293
13294    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13295        let working_dir = self.worktree_root_path();
13296        let output = util::command::new_smol_command(&command.path)
13297            .args(command.arguments)
13298            .envs(command.env.clone().unwrap_or_default())
13299            .current_dir(working_dir)
13300            .output()
13301            .await?;
13302
13303        anyhow::ensure!(
13304            output.status.success(),
13305            "{}, stdout: {:?}, stderr: {:?}",
13306            output.status,
13307            String::from_utf8_lossy(&output.stdout),
13308            String::from_utf8_lossy(&output.stderr)
13309        );
13310        Ok(())
13311    }
13312
13313    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13314        self.language_registry
13315            .update_lsp_binary_status(server_name, status);
13316    }
13317
13318    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13319        self.language_registry
13320            .all_lsp_adapters()
13321            .into_iter()
13322            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13323            .collect()
13324    }
13325
13326    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13327        let dir = self.language_registry.language_server_download_dir(name)?;
13328
13329        if !dir.exists() {
13330            smol::fs::create_dir_all(&dir)
13331                .await
13332                .context("failed to create container directory")
13333                .log_err()?;
13334        }
13335
13336        Some(dir)
13337    }
13338
13339    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
13340        let entry = self
13341            .worktree
13342            .entry_for_path(&path)
13343            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13344        let abs_path = self
13345            .worktree
13346            .absolutize(&entry.path)
13347            .with_context(|| format!("cannot absolutize path {path:?}"))?;
13348
13349        self.fs.load(&abs_path).await
13350    }
13351}
13352
13353async fn populate_labels_for_symbols(
13354    symbols: Vec<CoreSymbol>,
13355    language_registry: &Arc<LanguageRegistry>,
13356    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13357    output: &mut Vec<Symbol>,
13358) {
13359    #[allow(clippy::mutable_key_type)]
13360    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13361
13362    let mut unknown_paths = BTreeSet::new();
13363    for symbol in symbols {
13364        let language = language_registry
13365            .language_for_file_path(&symbol.path.path)
13366            .await
13367            .ok()
13368            .or_else(|| {
13369                unknown_paths.insert(symbol.path.path.clone());
13370                None
13371            });
13372        symbols_by_language
13373            .entry(language)
13374            .or_default()
13375            .push(symbol);
13376    }
13377
13378    for unknown_path in unknown_paths {
13379        log::info!(
13380            "no language found for symbol path {}",
13381            unknown_path.display()
13382        );
13383    }
13384
13385    let mut label_params = Vec::new();
13386    for (language, mut symbols) in symbols_by_language {
13387        label_params.clear();
13388        label_params.extend(
13389            symbols
13390                .iter_mut()
13391                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13392        );
13393
13394        let mut labels = Vec::new();
13395        if let Some(language) = language {
13396            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13397                language_registry
13398                    .lsp_adapters(&language.name())
13399                    .first()
13400                    .cloned()
13401            });
13402            if let Some(lsp_adapter) = lsp_adapter {
13403                labels = lsp_adapter
13404                    .labels_for_symbols(&label_params, &language)
13405                    .await
13406                    .log_err()
13407                    .unwrap_or_default();
13408            }
13409        }
13410
13411        for ((symbol, (name, _)), label) in symbols
13412            .into_iter()
13413            .zip(label_params.drain(..))
13414            .zip(labels.into_iter().chain(iter::repeat(None)))
13415        {
13416            output.push(Symbol {
13417                language_server_name: symbol.language_server_name,
13418                source_worktree_id: symbol.source_worktree_id,
13419                source_language_server_id: symbol.source_language_server_id,
13420                path: symbol.path,
13421                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13422                name,
13423                kind: symbol.kind,
13424                range: symbol.range,
13425                signature: symbol.signature,
13426            });
13427        }
13428    }
13429}
13430
13431fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13432    match server.capabilities().text_document_sync.as_ref()? {
13433        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13434            // Server wants didSave but didn't specify includeText.
13435            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13436            // Server doesn't want didSave at all.
13437            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13438            // Server provided SaveOptions.
13439            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13440                Some(save_options.include_text.unwrap_or(false))
13441            }
13442        },
13443        // We do not have any save info. Kind affects didChange only.
13444        lsp::TextDocumentSyncCapability::Kind(_) => None,
13445    }
13446}
13447
13448/// Completion items are displayed in a `UniformList`.
13449/// Usually, those items are single-line strings, but in LSP responses,
13450/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13451/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13452/// 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,
13453/// breaking the completions menu presentation.
13454///
13455/// 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.
13456fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13457    let mut new_text = String::with_capacity(label.text.len());
13458    let mut offset_map = vec![0; label.text.len() + 1];
13459    let mut last_char_was_space = false;
13460    let mut new_idx = 0;
13461    let chars = label.text.char_indices().fuse();
13462    let mut newlines_removed = false;
13463
13464    for (idx, c) in chars {
13465        offset_map[idx] = new_idx;
13466
13467        match c {
13468            '\n' if last_char_was_space => {
13469                newlines_removed = true;
13470            }
13471            '\t' | ' ' if last_char_was_space => {}
13472            '\n' if !last_char_was_space => {
13473                new_text.push(' ');
13474                new_idx += 1;
13475                last_char_was_space = true;
13476                newlines_removed = true;
13477            }
13478            ' ' | '\t' => {
13479                new_text.push(' ');
13480                new_idx += 1;
13481                last_char_was_space = true;
13482            }
13483            _ => {
13484                new_text.push(c);
13485                new_idx += c.len_utf8();
13486                last_char_was_space = false;
13487            }
13488        }
13489    }
13490    offset_map[label.text.len()] = new_idx;
13491
13492    // Only modify the label if newlines were removed.
13493    if !newlines_removed {
13494        return;
13495    }
13496
13497    let last_index = new_idx;
13498    let mut run_ranges_errors = Vec::new();
13499    label.runs.retain_mut(|(range, _)| {
13500        match offset_map.get(range.start) {
13501            Some(&start) => range.start = start,
13502            None => {
13503                run_ranges_errors.push(range.clone());
13504                return false;
13505            }
13506        }
13507
13508        match offset_map.get(range.end) {
13509            Some(&end) => range.end = end,
13510            None => {
13511                run_ranges_errors.push(range.clone());
13512                range.end = last_index;
13513            }
13514        }
13515        true
13516    });
13517    if !run_ranges_errors.is_empty() {
13518        log::error!(
13519            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13520            label.text
13521        );
13522    }
13523
13524    let mut wrong_filter_range = None;
13525    if label.filter_range == (0..label.text.len()) {
13526        label.filter_range = 0..new_text.len();
13527    } else {
13528        let mut original_filter_range = Some(label.filter_range.clone());
13529        match offset_map.get(label.filter_range.start) {
13530            Some(&start) => label.filter_range.start = start,
13531            None => {
13532                wrong_filter_range = original_filter_range.take();
13533                label.filter_range.start = last_index;
13534            }
13535        }
13536
13537        match offset_map.get(label.filter_range.end) {
13538            Some(&end) => label.filter_range.end = end,
13539            None => {
13540                wrong_filter_range = original_filter_range.take();
13541                label.filter_range.end = last_index;
13542            }
13543        }
13544    }
13545    if let Some(wrong_filter_range) = wrong_filter_range {
13546        log::error!(
13547            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13548            label.text
13549        );
13550    }
13551
13552    label.text = new_text;
13553}
13554
13555#[cfg(test)]
13556mod tests {
13557    use language::HighlightId;
13558
13559    use super::*;
13560
13561    #[test]
13562    fn test_glob_literal_prefix() {
13563        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13564        assert_eq!(
13565            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13566            Path::new("node_modules")
13567        );
13568        assert_eq!(
13569            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13570            Path::new("foo")
13571        );
13572        assert_eq!(
13573            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13574            Path::new("foo/bar/baz.js")
13575        );
13576
13577        #[cfg(target_os = "windows")]
13578        {
13579            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13580            assert_eq!(
13581                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13582                Path::new("node_modules")
13583            );
13584            assert_eq!(
13585                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13586                Path::new("foo")
13587            );
13588            assert_eq!(
13589                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13590                Path::new("foo/bar/baz.js")
13591            );
13592        }
13593    }
13594
13595    #[test]
13596    fn test_multi_len_chars_normalization() {
13597        let mut label = CodeLabel {
13598            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13599            runs: vec![(0..6, HighlightId(1))],
13600            filter_range: 0..6,
13601        };
13602        ensure_uniform_list_compatible_label(&mut label);
13603        assert_eq!(
13604            label,
13605            CodeLabel {
13606                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13607                runs: vec![(0..6, HighlightId(1))],
13608                filter_range: 0..6,
13609            }
13610        );
13611    }
13612}