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