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    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   37    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   38    yarn::YarnPathStore,
   39};
   40use anyhow::{Context as _, Result, anyhow};
   41use async_trait::async_trait;
   42use client::{TypedEnvelope, proto};
   43use clock::Global;
   44use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   45use futures::{
   46    AsyncWriteExt, Future, FutureExt, StreamExt,
   47    future::{Either, Shared, join_all, pending, select},
   48    select, select_biased,
   49    stream::FuturesUnordered,
   50};
   51use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   52use gpui::{
   53    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   54    WeakEntity,
   55};
   56use http_client::HttpClient;
   57use itertools::Itertools as _;
   58use language::{
   59    Bias, BinaryStatus, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   60    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   61    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   62    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   63    Transaction, Unclipped,
   64    language_settings::{
   65        FormatOnSave, Formatter, LanguageSettings, SelectedFormatter, language_settings,
   66    },
   67    point_to_lsp,
   68    proto::{
   69        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   70        serialize_lsp_edit, serialize_version,
   71    },
   72    range_from_lsp, range_to_lsp,
   73};
   74use lsp::{
   75    AdapterServerCapabilities, CodeActionKind, CompletionContext, DiagnosticSeverity,
   76    DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter,
   77    FileOperationPatternKind, FileOperationRegistrationOptions, FileRename, FileSystemWatcher,
   78    LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions,
   79    LanguageServerId, LanguageServerName, LanguageServerSelector, LspRequestFuture,
   80    MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind,
   81    TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles, WorkDoneProgressCancelParams,
   82    WorkspaceFolder, notification::DidRenameFiles,
   83};
   84use node_runtime::read_package_installed_version;
   85use parking_lot::Mutex;
   86use postage::{mpsc, sink::Sink, stream::Stream, watch};
   87use rand::prelude::*;
   88use rpc::{
   89    AnyProtoClient,
   90    proto::{LspRequestId, LspRequestMessage as _},
   91};
   92use serde::Serialize;
   93use settings::{Settings, SettingsLocation, SettingsStore};
   94use sha2::{Digest, Sha256};
   95use smol::channel::Sender;
   96use snippet::Snippet;
   97use std::{
   98    any::TypeId,
   99    borrow::Cow,
  100    cell::RefCell,
  101    cmp::{Ordering, Reverse},
  102    convert::TryInto,
  103    ffi::OsStr,
  104    future::ready,
  105    iter, mem,
  106    ops::{ControlFlow, Range},
  107    path::{self, Path, PathBuf},
  108    pin::pin,
  109    rc::Rc,
  110    sync::Arc,
  111    time::{Duration, Instant},
  112};
  113use sum_tree::Dimensions;
  114use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  115
  116use util::{
  117    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  118    paths::{PathStyle, SanitizedPath},
  119    post_inc,
  120    rel_path::RelPath,
  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<RelPath>>,
  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<RelPath>,
  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
  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                        &delegate,
  376                        toolchain,
  377                        cx,
  378                    )
  379                    .await?;
  380
  381                    let mut initialization_options = Self::initialization_options_for_adapter(
  382                        adapter.adapter.clone(),
  383                        &delegate,
  384                    )
  385                    .await?;
  386
  387                    match (&mut initialization_options, override_options) {
  388                        (Some(initialization_options), Some(override_options)) => {
  389                            merge_json_value_into(override_options, initialization_options);
  390                        }
  391                        (None, override_options) => initialization_options = override_options,
  392                        _ => {}
  393                    }
  394
  395                    let initialization_params = cx.update(|cx| {
  396                        let mut params =
  397                            language_server.default_initialize_params(pull_diagnostics, cx);
  398                        params.initialization_options = initialization_options;
  399                        adapter.adapter.prepare_initialize_params(params, cx)
  400                    })??;
  401
  402                    Self::setup_lsp_messages(
  403                        lsp_store.clone(),
  404                        &language_server,
  405                        delegate.clone(),
  406                        adapter.clone(),
  407                    );
  408
  409                    let did_change_configuration_params =
  410                        Arc::new(lsp::DidChangeConfigurationParams {
  411                            settings: workspace_config,
  412                        });
  413                    let language_server = cx
  414                        .update(|cx| {
  415                            language_server.initialize(
  416                                initialization_params,
  417                                did_change_configuration_params.clone(),
  418                                cx,
  419                            )
  420                        })?
  421                        .await
  422                        .inspect_err(|_| {
  423                            if let Some(lsp_store) = lsp_store.upgrade() {
  424                                lsp_store
  425                                    .update(cx, |lsp_store, cx| {
  426                                        lsp_store.cleanup_lsp_data(server_id);
  427                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  428                                    })
  429                                    .ok();
  430                            }
  431                        })?;
  432
  433                    language_server
  434                        .notify::<lsp::notification::DidChangeConfiguration>(
  435                            &did_change_configuration_params,
  436                        )
  437                        .ok();
  438
  439                    anyhow::Ok(language_server)
  440                }
  441                .await;
  442
  443                match result {
  444                    Ok(server) => {
  445                        lsp_store
  446                            .update(cx, |lsp_store, cx| {
  447                                lsp_store.insert_newly_running_language_server(
  448                                    adapter,
  449                                    server.clone(),
  450                                    server_id,
  451                                    key,
  452                                    pending_workspace_folders,
  453                                    cx,
  454                                );
  455                            })
  456                            .ok();
  457                        stderr_capture.lock().take();
  458                        Some(server)
  459                    }
  460
  461                    Err(err) => {
  462                        let log = stderr_capture.lock().take().unwrap_or_default();
  463                        delegate.update_status(
  464                            adapter.name(),
  465                            BinaryStatus::Failed {
  466                                error: if log.is_empty() {
  467                                    format!("{err:#}")
  468                                } else {
  469                                    format!("{err:#}\n-- stderr --\n{log}")
  470                                },
  471                            },
  472                        );
  473                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  474                        if !log.is_empty() {
  475                            log::error!("server stderr: {log}");
  476                        }
  477                        None
  478                    }
  479                }
  480            })
  481        };
  482        let state = LanguageServerState::Starting {
  483            startup,
  484            pending_workspace_folders,
  485        };
  486
  487        self.languages
  488            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  489
  490        self.language_servers.insert(server_id, state);
  491        self.language_server_ids
  492            .entry(key)
  493            .or_insert(UnifiedLanguageServer {
  494                id: server_id,
  495                project_roots: Default::default(),
  496            });
  497        server_id
  498    }
  499
  500    fn get_language_server_binary(
  501        &self,
  502        adapter: Arc<CachedLspAdapter>,
  503        settings: Arc<LspSettings>,
  504        toolchain: Option<Toolchain>,
  505        delegate: Arc<dyn LspAdapterDelegate>,
  506        allow_binary_download: bool,
  507        cx: &mut App,
  508    ) -> Task<Result<LanguageServerBinary>> {
  509        if let Some(settings) = settings.binary.as_ref()
  510            && settings.path.is_some()
  511        {
  512            let settings = settings.clone();
  513
  514            return cx.background_spawn(async move {
  515                let mut env = delegate.shell_env().await;
  516                env.extend(settings.env.unwrap_or_default());
  517
  518                Ok(LanguageServerBinary {
  519                    path: PathBuf::from(&settings.path.unwrap()),
  520                    env: Some(env),
  521                    arguments: settings
  522                        .arguments
  523                        .unwrap_or_default()
  524                        .iter()
  525                        .map(Into::into)
  526                        .collect(),
  527                })
  528            });
  529        }
  530        let lsp_binary_options = LanguageServerBinaryOptions {
  531            allow_path_lookup: !settings
  532                .binary
  533                .as_ref()
  534                .and_then(|b| b.ignore_system_version)
  535                .unwrap_or_default(),
  536            allow_binary_download,
  537            pre_release: settings
  538                .fetch
  539                .as_ref()
  540                .and_then(|f| f.pre_release)
  541                .unwrap_or(false),
  542        };
  543
  544        cx.spawn(async move |cx| {
  545            let binary_result = adapter
  546                .clone()
  547                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  548                .await;
  549
  550            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  551
  552            let mut binary = binary_result?;
  553            let mut shell_env = delegate.shell_env().await;
  554
  555            shell_env.extend(binary.env.unwrap_or_default());
  556
  557            if let Some(settings) = settings.binary.as_ref() {
  558                if let Some(arguments) = &settings.arguments {
  559                    binary.arguments = arguments.iter().map(Into::into).collect();
  560                }
  561                if let Some(env) = &settings.env {
  562                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  563                }
  564            }
  565
  566            binary.env = Some(shell_env);
  567            Ok(binary)
  568        })
  569    }
  570
  571    fn setup_lsp_messages(
  572        this: WeakEntity<LspStore>,
  573
  574        language_server: &LanguageServer,
  575        delegate: Arc<dyn LspAdapterDelegate>,
  576        adapter: Arc<CachedLspAdapter>,
  577    ) {
  578        let name = language_server.name();
  579        let server_id = language_server.server_id();
  580        language_server
  581            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  582                let adapter = adapter.clone();
  583                let this = this.clone();
  584                move |mut params, cx| {
  585                    let adapter = adapter.clone();
  586                    if let Some(this) = this.upgrade() {
  587                        this.update(cx, |this, cx| {
  588                            {
  589                                let buffer = params
  590                                    .uri
  591                                    .to_file_path()
  592                                    .map(|file_path| this.get_buffer(&file_path, cx))
  593                                    .ok()
  594                                    .flatten();
  595                                adapter.process_diagnostics(&mut params, server_id, buffer);
  596                            }
  597
  598                            this.merge_lsp_diagnostics(
  599                                DiagnosticSourceKind::Pushed,
  600                                vec![DocumentDiagnosticsUpdate {
  601                                    server_id,
  602                                    diagnostics: params,
  603                                    result_id: None,
  604                                    disk_based_sources: Cow::Borrowed(
  605                                        &adapter.disk_based_diagnostic_sources,
  606                                    ),
  607                                }],
  608                                |_, diagnostic, cx| match diagnostic.source_kind {
  609                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  610                                        adapter.retain_old_diagnostic(diagnostic, cx)
  611                                    }
  612                                    DiagnosticSourceKind::Pulled => true,
  613                                },
  614                                cx,
  615                            )
  616                            .log_err();
  617                        })
  618                        .ok();
  619                    }
  620                }
  621            })
  622            .detach();
  623        language_server
  624            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  625                let adapter = adapter.adapter.clone();
  626                let delegate = delegate.clone();
  627                let this = this.clone();
  628
  629                move |params, cx| {
  630                    let adapter = adapter.clone();
  631                    let delegate = delegate.clone();
  632                    let this = this.clone();
  633                    let mut cx = cx.clone();
  634                    async move {
  635                        let toolchain_for_id = this
  636                            .update(&mut cx, |this, _| {
  637                                this.as_local()?.language_server_ids.iter().find_map(
  638                                    |(seed, value)| {
  639                                        (value.id == server_id).then(|| seed.toolchain.clone())
  640                                    },
  641                                )
  642                            })?
  643                            .context("Expected the LSP store to be in a local mode")?;
  644                        let workspace_config = Self::workspace_configuration_for_adapter(
  645                            adapter.clone(),
  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<RelPath> = 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 mut extra_buffers = String::new();
 1846                                for buffer in project_transaction_command.0.keys() {
 1847                                    buffer
 1848                                        .read_with(cx, |b, cx| {
 1849                                            if let Some(path) = b.project_path(cx) {
 1850                                                if !extra_buffers.is_empty() {
 1851                                                    extra_buffers.push_str(", ");
 1852                                                }
 1853                                                extra_buffers.push_str(path.path.as_str());
 1854                                            }
 1855                                        })
 1856                                        .ok();
 1857                                }
 1858                                zlog::warn!(
 1859                                    logger =>
 1860                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1861                                    &command.command,
 1862                                    extra_buffers,
 1863                                );
 1864                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1865                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1866                                // add it so it's included, and merge it into the format transaction when its created later
 1867                            }
 1868                        }
 1869                    }
 1870                }
 1871            }
 1872        }
 1873
 1874        Ok(())
 1875    }
 1876
 1877    pub async fn format_ranges_via_lsp(
 1878        this: &WeakEntity<LspStore>,
 1879        buffer_handle: &Entity<Buffer>,
 1880        ranges: &[Range<Anchor>],
 1881        abs_path: &Path,
 1882        language_server: &Arc<LanguageServer>,
 1883        settings: &LanguageSettings,
 1884        cx: &mut AsyncApp,
 1885    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1886        let capabilities = &language_server.capabilities();
 1887        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1888        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1889            anyhow::bail!(
 1890                "{} language server does not support range formatting",
 1891                language_server.name()
 1892            );
 1893        }
 1894
 1895        let uri = file_path_to_lsp_url(abs_path)?;
 1896        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1897
 1898        let lsp_edits = {
 1899            let mut lsp_ranges = Vec::new();
 1900            this.update(cx, |_this, cx| {
 1901                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1902                // not have been sent to the language server. This seems like a fairly systemic
 1903                // issue, though, the resolution probably is not specific to formatting.
 1904                //
 1905                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1906                // LSP.
 1907                let snapshot = buffer_handle.read(cx).snapshot();
 1908                for range in ranges {
 1909                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1910                }
 1911                anyhow::Ok(())
 1912            })??;
 1913
 1914            let mut edits = None;
 1915            for range in lsp_ranges {
 1916                if let Some(mut edit) = language_server
 1917                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1918                        text_document: text_document.clone(),
 1919                        range,
 1920                        options: lsp_command::lsp_formatting_options(settings),
 1921                        work_done_progress_params: Default::default(),
 1922                    })
 1923                    .await
 1924                    .into_response()?
 1925                {
 1926                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 1927                }
 1928            }
 1929            edits
 1930        };
 1931
 1932        if let Some(lsp_edits) = lsp_edits {
 1933            this.update(cx, |this, cx| {
 1934                this.as_local_mut().unwrap().edits_from_lsp(
 1935                    buffer_handle,
 1936                    lsp_edits,
 1937                    language_server.server_id(),
 1938                    None,
 1939                    cx,
 1940                )
 1941            })?
 1942            .await
 1943        } else {
 1944            Ok(Vec::with_capacity(0))
 1945        }
 1946    }
 1947
 1948    async fn format_via_lsp(
 1949        this: &WeakEntity<LspStore>,
 1950        buffer: &Entity<Buffer>,
 1951        abs_path: &Path,
 1952        language_server: &Arc<LanguageServer>,
 1953        settings: &LanguageSettings,
 1954        cx: &mut AsyncApp,
 1955    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1956        let logger = zlog::scoped!("lsp_format");
 1957        zlog::info!(logger => "Formatting via LSP");
 1958
 1959        let uri = file_path_to_lsp_url(abs_path)?;
 1960        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1961        let capabilities = &language_server.capabilities();
 1962
 1963        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 1964        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1965
 1966        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1967            let _timer = zlog::time!(logger => "format-full");
 1968            language_server
 1969                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 1970                    text_document,
 1971                    options: lsp_command::lsp_formatting_options(settings),
 1972                    work_done_progress_params: Default::default(),
 1973                })
 1974                .await
 1975                .into_response()?
 1976        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1977            let _timer = zlog::time!(logger => "format-range");
 1978            let buffer_start = lsp::Position::new(0, 0);
 1979            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 1980            language_server
 1981                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1982                    text_document: text_document.clone(),
 1983                    range: lsp::Range::new(buffer_start, buffer_end),
 1984                    options: lsp_command::lsp_formatting_options(settings),
 1985                    work_done_progress_params: Default::default(),
 1986                })
 1987                .await
 1988                .into_response()?
 1989        } else {
 1990            None
 1991        };
 1992
 1993        if let Some(lsp_edits) = lsp_edits {
 1994            this.update(cx, |this, cx| {
 1995                this.as_local_mut().unwrap().edits_from_lsp(
 1996                    buffer,
 1997                    lsp_edits,
 1998                    language_server.server_id(),
 1999                    None,
 2000                    cx,
 2001                )
 2002            })?
 2003            .await
 2004        } else {
 2005            Ok(Vec::with_capacity(0))
 2006        }
 2007    }
 2008
 2009    async fn format_via_external_command(
 2010        buffer: &FormattableBuffer,
 2011        command: &str,
 2012        arguments: Option<&[String]>,
 2013        cx: &mut AsyncApp,
 2014    ) -> Result<Option<Diff>> {
 2015        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2016            let file = File::from_dyn(buffer.file())?;
 2017            let worktree = file.worktree.read(cx);
 2018            let mut worktree_path = worktree.abs_path().to_path_buf();
 2019            if worktree.root_entry()?.is_file() {
 2020                worktree_path.pop();
 2021            }
 2022            Some(worktree_path)
 2023        })?;
 2024
 2025        let mut child = util::command::new_smol_command(command);
 2026
 2027        if let Some(buffer_env) = buffer.env.as_ref() {
 2028            child.envs(buffer_env);
 2029        }
 2030
 2031        if let Some(working_dir_path) = working_dir_path {
 2032            child.current_dir(working_dir_path);
 2033        }
 2034
 2035        if let Some(arguments) = arguments {
 2036            child.args(arguments.iter().map(|arg| {
 2037                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2038                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2039                } else {
 2040                    arg.replace("{buffer_path}", "Untitled")
 2041                }
 2042            }));
 2043        }
 2044
 2045        let mut child = child
 2046            .stdin(smol::process::Stdio::piped())
 2047            .stdout(smol::process::Stdio::piped())
 2048            .stderr(smol::process::Stdio::piped())
 2049            .spawn()?;
 2050
 2051        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2052        let text = buffer
 2053            .handle
 2054            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2055        for chunk in text.chunks() {
 2056            stdin.write_all(chunk.as_bytes()).await?;
 2057        }
 2058        stdin.flush().await?;
 2059
 2060        let output = child.output().await?;
 2061        anyhow::ensure!(
 2062            output.status.success(),
 2063            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2064            output.status.code(),
 2065            String::from_utf8_lossy(&output.stdout),
 2066            String::from_utf8_lossy(&output.stderr),
 2067        );
 2068
 2069        let stdout = String::from_utf8(output.stdout)?;
 2070        Ok(Some(
 2071            buffer
 2072                .handle
 2073                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2074                .await,
 2075        ))
 2076    }
 2077
 2078    async fn try_resolve_code_action(
 2079        lang_server: &LanguageServer,
 2080        action: &mut CodeAction,
 2081    ) -> anyhow::Result<()> {
 2082        match &mut action.lsp_action {
 2083            LspAction::Action(lsp_action) => {
 2084                if !action.resolved
 2085                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2086                    && lsp_action.data.is_some()
 2087                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2088                {
 2089                    *lsp_action = Box::new(
 2090                        lang_server
 2091                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2092                            .await
 2093                            .into_response()?,
 2094                    );
 2095                }
 2096            }
 2097            LspAction::CodeLens(lens) => {
 2098                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2099                    *lens = lang_server
 2100                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2101                        .await
 2102                        .into_response()?;
 2103                }
 2104            }
 2105            LspAction::Command(_) => {}
 2106        }
 2107
 2108        action.resolved = true;
 2109        anyhow::Ok(())
 2110    }
 2111
 2112    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2113        let buffer = buffer_handle.read(cx);
 2114
 2115        let file = buffer.file().cloned();
 2116
 2117        let Some(file) = File::from_dyn(file.as_ref()) else {
 2118            return;
 2119        };
 2120        if !file.is_local() {
 2121            return;
 2122        }
 2123        let path = ProjectPath::from_file(file, cx);
 2124        let worktree_id = file.worktree_id(cx);
 2125        let language = buffer.language().cloned();
 2126
 2127        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2128            for (server_id, diagnostics) in
 2129                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2130            {
 2131                self.update_buffer_diagnostics(
 2132                    buffer_handle,
 2133                    server_id,
 2134                    None,
 2135                    None,
 2136                    diagnostics,
 2137                    Vec::new(),
 2138                    cx,
 2139                )
 2140                .log_err();
 2141            }
 2142        }
 2143        let Some(language) = language else {
 2144            return;
 2145        };
 2146        let Some(snapshot) = self
 2147            .worktree_store
 2148            .read(cx)
 2149            .worktree_for_id(worktree_id, cx)
 2150            .map(|worktree| worktree.read(cx).snapshot())
 2151        else {
 2152            return;
 2153        };
 2154        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2155
 2156        for server_id in
 2157            self.lsp_tree
 2158                .get(path, language.name(), language.manifest(), &delegate, cx)
 2159        {
 2160            let server = self
 2161                .language_servers
 2162                .get(&server_id)
 2163                .and_then(|server_state| {
 2164                    if let LanguageServerState::Running { server, .. } = server_state {
 2165                        Some(server.clone())
 2166                    } else {
 2167                        None
 2168                    }
 2169                });
 2170            let server = match server {
 2171                Some(server) => server,
 2172                None => continue,
 2173            };
 2174
 2175            buffer_handle.update(cx, |buffer, cx| {
 2176                buffer.set_completion_triggers(
 2177                    server.server_id(),
 2178                    server
 2179                        .capabilities()
 2180                        .completion_provider
 2181                        .as_ref()
 2182                        .and_then(|provider| {
 2183                            provider
 2184                                .trigger_characters
 2185                                .as_ref()
 2186                                .map(|characters| characters.iter().cloned().collect())
 2187                        })
 2188                        .unwrap_or_default(),
 2189                    cx,
 2190                );
 2191            });
 2192        }
 2193    }
 2194
 2195    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2196        buffer.update(cx, |buffer, cx| {
 2197            let Some(language) = buffer.language() else {
 2198                return;
 2199            };
 2200            let path = ProjectPath {
 2201                worktree_id: old_file.worktree_id(cx),
 2202                path: old_file.path.clone(),
 2203            };
 2204            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2205                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2206                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2207            }
 2208        });
 2209    }
 2210
 2211    fn update_buffer_diagnostics(
 2212        &mut self,
 2213        buffer: &Entity<Buffer>,
 2214        server_id: LanguageServerId,
 2215        result_id: Option<String>,
 2216        version: Option<i32>,
 2217        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2218        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2219        cx: &mut Context<LspStore>,
 2220    ) -> Result<()> {
 2221        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2222            Ordering::Equal
 2223                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2224                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2225                .then_with(|| a.severity.cmp(&b.severity))
 2226                .then_with(|| a.message.cmp(&b.message))
 2227        }
 2228
 2229        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2230        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2231        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2232
 2233        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2234            Ordering::Equal
 2235                .then_with(|| a.range.start.cmp(&b.range.start))
 2236                .then_with(|| b.range.end.cmp(&a.range.end))
 2237                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2238        });
 2239
 2240        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2241
 2242        let edits_since_save = std::cell::LazyCell::new(|| {
 2243            let saved_version = buffer.read(cx).saved_version();
 2244            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2245        });
 2246
 2247        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2248
 2249        for (new_diagnostic, entry) in diagnostics {
 2250            let start;
 2251            let end;
 2252            if new_diagnostic && entry.diagnostic.is_disk_based {
 2253                // Some diagnostics are based on files on disk instead of buffers'
 2254                // current contents. Adjust these diagnostics' ranges to reflect
 2255                // any unsaved edits.
 2256                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2257                // and were properly adjusted on reuse.
 2258                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2259                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2260            } else {
 2261                start = entry.range.start;
 2262                end = entry.range.end;
 2263            }
 2264
 2265            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2266                ..snapshot.clip_point_utf16(end, Bias::Right);
 2267
 2268            // Expand empty ranges by one codepoint
 2269            if range.start == range.end {
 2270                // This will be go to the next boundary when being clipped
 2271                range.end.column += 1;
 2272                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2273                if range.start == range.end && range.end.column > 0 {
 2274                    range.start.column -= 1;
 2275                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2276                }
 2277            }
 2278
 2279            sanitized_diagnostics.push(DiagnosticEntry {
 2280                range,
 2281                diagnostic: entry.diagnostic,
 2282            });
 2283        }
 2284        drop(edits_since_save);
 2285
 2286        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2287        buffer.update(cx, |buffer, cx| {
 2288            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2289                self.buffer_pull_diagnostics_result_ids
 2290                    .entry(server_id)
 2291                    .or_default()
 2292                    .insert(abs_path, result_id);
 2293            }
 2294
 2295            buffer.update_diagnostics(server_id, set, cx)
 2296        });
 2297
 2298        Ok(())
 2299    }
 2300
 2301    fn register_language_server_for_invisible_worktree(
 2302        &mut self,
 2303        worktree: &Entity<Worktree>,
 2304        language_server_id: LanguageServerId,
 2305        cx: &mut App,
 2306    ) {
 2307        let worktree = worktree.read(cx);
 2308        let worktree_id = worktree.id();
 2309        debug_assert!(!worktree.is_visible());
 2310        let Some(mut origin_seed) = self
 2311            .language_server_ids
 2312            .iter()
 2313            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2314        else {
 2315            return;
 2316        };
 2317        origin_seed.worktree_id = worktree_id;
 2318        self.language_server_ids
 2319            .entry(origin_seed)
 2320            .or_insert_with(|| UnifiedLanguageServer {
 2321                id: language_server_id,
 2322                project_roots: Default::default(),
 2323            });
 2324    }
 2325
 2326    fn register_buffer_with_language_servers(
 2327        &mut self,
 2328        buffer_handle: &Entity<Buffer>,
 2329        only_register_servers: HashSet<LanguageServerSelector>,
 2330        cx: &mut Context<LspStore>,
 2331    ) {
 2332        let buffer = buffer_handle.read(cx);
 2333        let buffer_id = buffer.remote_id();
 2334
 2335        let Some(file) = File::from_dyn(buffer.file()) else {
 2336            return;
 2337        };
 2338        if !file.is_local() {
 2339            return;
 2340        }
 2341
 2342        let abs_path = file.abs_path(cx);
 2343        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2344            return;
 2345        };
 2346        let initial_snapshot = buffer.text_snapshot();
 2347        let worktree_id = file.worktree_id(cx);
 2348
 2349        let Some(language) = buffer.language().cloned() else {
 2350            return;
 2351        };
 2352        let path: Arc<RelPath> = file
 2353            .path()
 2354            .parent()
 2355            .map(Arc::from)
 2356            .unwrap_or_else(|| file.path().clone());
 2357        let Some(worktree) = self
 2358            .worktree_store
 2359            .read(cx)
 2360            .worktree_for_id(worktree_id, cx)
 2361        else {
 2362            return;
 2363        };
 2364        let language_name = language.name();
 2365        let (reused, delegate, servers) = self
 2366            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2367            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2368            .unwrap_or_else(|| {
 2369                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2370                let delegate: Arc<dyn ManifestDelegate> =
 2371                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2372
 2373                let servers = self
 2374                    .lsp_tree
 2375                    .walk(
 2376                        ProjectPath { worktree_id, path },
 2377                        language.name(),
 2378                        language.manifest(),
 2379                        &delegate,
 2380                        cx,
 2381                    )
 2382                    .collect::<Vec<_>>();
 2383                (false, lsp_delegate, servers)
 2384            });
 2385        let servers_and_adapters = servers
 2386            .into_iter()
 2387            .filter_map(|server_node| {
 2388                if reused && server_node.server_id().is_none() {
 2389                    return None;
 2390                }
 2391                if !only_register_servers.is_empty() {
 2392                    if let Some(server_id) = server_node.server_id()
 2393                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2394                    {
 2395                        return None;
 2396                    }
 2397                    if let Some(name) = server_node.name()
 2398                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2399                    {
 2400                        return None;
 2401                    }
 2402                }
 2403
 2404                let server_id = server_node.server_id_or_init(|disposition| {
 2405                    let path = &disposition.path;
 2406
 2407                    {
 2408                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2409
 2410                        let server_id = self.get_or_insert_language_server(
 2411                            &worktree,
 2412                            delegate.clone(),
 2413                            disposition,
 2414                            &language_name,
 2415                            cx,
 2416                        );
 2417
 2418                        if let Some(state) = self.language_servers.get(&server_id)
 2419                            && let Ok(uri) = uri
 2420                        {
 2421                            state.add_workspace_folder(uri);
 2422                        };
 2423                        server_id
 2424                    }
 2425                })?;
 2426                let server_state = self.language_servers.get(&server_id)?;
 2427                if let LanguageServerState::Running {
 2428                    server, adapter, ..
 2429                } = server_state
 2430                {
 2431                    Some((server.clone(), adapter.clone()))
 2432                } else {
 2433                    None
 2434                }
 2435            })
 2436            .collect::<Vec<_>>();
 2437        for (server, adapter) in servers_and_adapters {
 2438            buffer_handle.update(cx, |buffer, cx| {
 2439                buffer.set_completion_triggers(
 2440                    server.server_id(),
 2441                    server
 2442                        .capabilities()
 2443                        .completion_provider
 2444                        .as_ref()
 2445                        .and_then(|provider| {
 2446                            provider
 2447                                .trigger_characters
 2448                                .as_ref()
 2449                                .map(|characters| characters.iter().cloned().collect())
 2450                        })
 2451                        .unwrap_or_default(),
 2452                    cx,
 2453                );
 2454            });
 2455
 2456            let snapshot = LspBufferSnapshot {
 2457                version: 0,
 2458                snapshot: initial_snapshot.clone(),
 2459            };
 2460
 2461            let mut registered = false;
 2462            self.buffer_snapshots
 2463                .entry(buffer_id)
 2464                .or_default()
 2465                .entry(server.server_id())
 2466                .or_insert_with(|| {
 2467                    registered = true;
 2468                    server.register_buffer(
 2469                        uri.clone(),
 2470                        adapter.language_id(&language.name()),
 2471                        0,
 2472                        initial_snapshot.text(),
 2473                    );
 2474
 2475                    vec![snapshot]
 2476                });
 2477
 2478            self.buffers_opened_in_servers
 2479                .entry(buffer_id)
 2480                .or_default()
 2481                .insert(server.server_id());
 2482            if registered {
 2483                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2484                    language_server_id: server.server_id(),
 2485                    name: None,
 2486                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2487                        proto::RegisteredForBuffer {
 2488                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 2489                            buffer_id: buffer_id.to_proto(),
 2490                        },
 2491                    ),
 2492                });
 2493            }
 2494        }
 2495    }
 2496
 2497    fn reuse_existing_language_server<'lang_name>(
 2498        &self,
 2499        server_tree: &LanguageServerTree,
 2500        worktree: &Entity<Worktree>,
 2501        language_name: &'lang_name LanguageName,
 2502        cx: &mut App,
 2503    ) -> Option<(
 2504        Arc<LocalLspAdapterDelegate>,
 2505        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2506    )> {
 2507        if worktree.read(cx).is_visible() {
 2508            return None;
 2509        }
 2510
 2511        let worktree_store = self.worktree_store.read(cx);
 2512        let servers = server_tree
 2513            .instances
 2514            .iter()
 2515            .filter(|(worktree_id, _)| {
 2516                worktree_store
 2517                    .worktree_for_id(**worktree_id, cx)
 2518                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2519            })
 2520            .flat_map(|(worktree_id, servers)| {
 2521                servers
 2522                    .roots
 2523                    .iter()
 2524                    .flat_map(|(_, language_servers)| language_servers)
 2525                    .map(move |(_, (server_node, server_languages))| {
 2526                        (worktree_id, server_node, server_languages)
 2527                    })
 2528                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2529                    .map(|(worktree_id, server_node, _)| {
 2530                        (
 2531                            *worktree_id,
 2532                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2533                        )
 2534                    })
 2535            })
 2536            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2537                acc.entry(worktree_id)
 2538                    .or_insert_with(Vec::new)
 2539                    .push(server_node);
 2540                acc
 2541            })
 2542            .into_values()
 2543            .max_by_key(|servers| servers.len())?;
 2544
 2545        let worktree_id = worktree.read(cx).id();
 2546        let apply = move |tree: &mut LanguageServerTree| {
 2547            for server_node in &servers {
 2548                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2549            }
 2550            servers
 2551        };
 2552
 2553        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2554        Some((delegate, apply))
 2555    }
 2556
 2557    pub(crate) fn unregister_old_buffer_from_language_servers(
 2558        &mut self,
 2559        buffer: &Entity<Buffer>,
 2560        old_file: &File,
 2561        cx: &mut App,
 2562    ) {
 2563        let old_path = match old_file.as_local() {
 2564            Some(local) => local.abs_path(cx),
 2565            None => return,
 2566        };
 2567
 2568        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2569            debug_panic!("{old_path:?} is not parseable as an URI");
 2570            return;
 2571        };
 2572        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2573    }
 2574
 2575    pub(crate) fn unregister_buffer_from_language_servers(
 2576        &mut self,
 2577        buffer: &Entity<Buffer>,
 2578        file_url: &lsp::Uri,
 2579        cx: &mut App,
 2580    ) {
 2581        buffer.update(cx, |buffer, cx| {
 2582            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2583
 2584            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2585                language_server.unregister_buffer(file_url.clone());
 2586            }
 2587        });
 2588    }
 2589
 2590    fn buffer_snapshot_for_lsp_version(
 2591        &mut self,
 2592        buffer: &Entity<Buffer>,
 2593        server_id: LanguageServerId,
 2594        version: Option<i32>,
 2595        cx: &App,
 2596    ) -> Result<TextBufferSnapshot> {
 2597        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2598
 2599        if let Some(version) = version {
 2600            let buffer_id = buffer.read(cx).remote_id();
 2601            let snapshots = if let Some(snapshots) = self
 2602                .buffer_snapshots
 2603                .get_mut(&buffer_id)
 2604                .and_then(|m| m.get_mut(&server_id))
 2605            {
 2606                snapshots
 2607            } else if version == 0 {
 2608                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2609                // We detect this case and treat it as if the version was `None`.
 2610                return Ok(buffer.read(cx).text_snapshot());
 2611            } else {
 2612                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2613            };
 2614
 2615            let found_snapshot = snapshots
 2616                    .binary_search_by_key(&version, |e| e.version)
 2617                    .map(|ix| snapshots[ix].snapshot.clone())
 2618                    .map_err(|_| {
 2619                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2620                    })?;
 2621
 2622            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2623            Ok(found_snapshot)
 2624        } else {
 2625            Ok((buffer.read(cx)).text_snapshot())
 2626        }
 2627    }
 2628
 2629    async fn get_server_code_actions_from_action_kinds(
 2630        lsp_store: &WeakEntity<LspStore>,
 2631        language_server_id: LanguageServerId,
 2632        code_action_kinds: Vec<lsp::CodeActionKind>,
 2633        buffer: &Entity<Buffer>,
 2634        cx: &mut AsyncApp,
 2635    ) -> Result<Vec<CodeAction>> {
 2636        let actions = lsp_store
 2637            .update(cx, move |this, cx| {
 2638                let request = GetCodeActions {
 2639                    range: text::Anchor::MIN..text::Anchor::MAX,
 2640                    kinds: Some(code_action_kinds),
 2641                };
 2642                let server = LanguageServerToQuery::Other(language_server_id);
 2643                this.request_lsp(buffer.clone(), server, request, cx)
 2644            })?
 2645            .await?;
 2646        Ok(actions)
 2647    }
 2648
 2649    pub async fn execute_code_actions_on_server(
 2650        lsp_store: &WeakEntity<LspStore>,
 2651        language_server: &Arc<LanguageServer>,
 2652
 2653        actions: Vec<CodeAction>,
 2654        push_to_history: bool,
 2655        project_transaction: &mut ProjectTransaction,
 2656        cx: &mut AsyncApp,
 2657    ) -> anyhow::Result<()> {
 2658        for mut action in actions {
 2659            Self::try_resolve_code_action(language_server, &mut action)
 2660                .await
 2661                .context("resolving a formatting code action")?;
 2662
 2663            if let Some(edit) = action.lsp_action.edit() {
 2664                if edit.changes.is_none() && edit.document_changes.is_none() {
 2665                    continue;
 2666                }
 2667
 2668                let new = Self::deserialize_workspace_edit(
 2669                    lsp_store.upgrade().context("project dropped")?,
 2670                    edit.clone(),
 2671                    push_to_history,
 2672                    language_server.clone(),
 2673                    cx,
 2674                )
 2675                .await?;
 2676                project_transaction.0.extend(new.0);
 2677            }
 2678
 2679            if let Some(command) = action.lsp_action.command() {
 2680                let server_capabilities = language_server.capabilities();
 2681                let available_commands = server_capabilities
 2682                    .execute_command_provider
 2683                    .as_ref()
 2684                    .map(|options| options.commands.as_slice())
 2685                    .unwrap_or_default();
 2686                if available_commands.contains(&command.command) {
 2687                    lsp_store.update(cx, |lsp_store, _| {
 2688                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2689                            mode.last_workspace_edits_by_language_server
 2690                                .remove(&language_server.server_id());
 2691                        }
 2692                    })?;
 2693
 2694                    language_server
 2695                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2696                            command: command.command.clone(),
 2697                            arguments: command.arguments.clone().unwrap_or_default(),
 2698                            ..Default::default()
 2699                        })
 2700                        .await
 2701                        .into_response()
 2702                        .context("execute command")?;
 2703
 2704                    lsp_store.update(cx, |this, _| {
 2705                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2706                            project_transaction.0.extend(
 2707                                mode.last_workspace_edits_by_language_server
 2708                                    .remove(&language_server.server_id())
 2709                                    .unwrap_or_default()
 2710                                    .0,
 2711                            )
 2712                        }
 2713                    })?;
 2714                } else {
 2715                    log::warn!(
 2716                        "Cannot execute a command {} not listed in the language server capabilities",
 2717                        command.command
 2718                    )
 2719                }
 2720            }
 2721        }
 2722        Ok(())
 2723    }
 2724
 2725    pub async fn deserialize_text_edits(
 2726        this: Entity<LspStore>,
 2727        buffer_to_edit: Entity<Buffer>,
 2728        edits: Vec<lsp::TextEdit>,
 2729        push_to_history: bool,
 2730        _: Arc<CachedLspAdapter>,
 2731        language_server: Arc<LanguageServer>,
 2732        cx: &mut AsyncApp,
 2733    ) -> Result<Option<Transaction>> {
 2734        let edits = this
 2735            .update(cx, |this, cx| {
 2736                this.as_local_mut().unwrap().edits_from_lsp(
 2737                    &buffer_to_edit,
 2738                    edits,
 2739                    language_server.server_id(),
 2740                    None,
 2741                    cx,
 2742                )
 2743            })?
 2744            .await?;
 2745
 2746        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2747            buffer.finalize_last_transaction();
 2748            buffer.start_transaction();
 2749            for (range, text) in edits {
 2750                buffer.edit([(range, text)], None, cx);
 2751            }
 2752
 2753            if buffer.end_transaction(cx).is_some() {
 2754                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2755                if !push_to_history {
 2756                    buffer.forget_transaction(transaction.id);
 2757                }
 2758                Some(transaction)
 2759            } else {
 2760                None
 2761            }
 2762        })?;
 2763
 2764        Ok(transaction)
 2765    }
 2766
 2767    #[allow(clippy::type_complexity)]
 2768    pub(crate) fn edits_from_lsp(
 2769        &mut self,
 2770        buffer: &Entity<Buffer>,
 2771        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2772        server_id: LanguageServerId,
 2773        version: Option<i32>,
 2774        cx: &mut Context<LspStore>,
 2775    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2776        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2777        cx.background_spawn(async move {
 2778            let snapshot = snapshot?;
 2779            let mut lsp_edits = lsp_edits
 2780                .into_iter()
 2781                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2782                .collect::<Vec<_>>();
 2783
 2784            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2785
 2786            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2787            let mut edits = Vec::new();
 2788            while let Some((range, mut new_text)) = lsp_edits.next() {
 2789                // Clip invalid ranges provided by the language server.
 2790                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2791                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2792
 2793                // Combine any LSP edits that are adjacent.
 2794                //
 2795                // Also, combine LSP edits that are separated from each other by only
 2796                // a newline. This is important because for some code actions,
 2797                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2798                // are separated by unchanged newline characters.
 2799                //
 2800                // In order for the diffing logic below to work properly, any edits that
 2801                // cancel each other out must be combined into one.
 2802                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2803                    if next_range.start.0 > range.end {
 2804                        if next_range.start.0.row > range.end.row + 1
 2805                            || next_range.start.0.column > 0
 2806                            || snapshot.clip_point_utf16(
 2807                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2808                                Bias::Left,
 2809                            ) > range.end
 2810                        {
 2811                            break;
 2812                        }
 2813                        new_text.push('\n');
 2814                    }
 2815                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2816                    new_text.push_str(next_text);
 2817                    lsp_edits.next();
 2818                }
 2819
 2820                // For multiline edits, perform a diff of the old and new text so that
 2821                // we can identify the changes more precisely, preserving the locations
 2822                // of any anchors positioned in the unchanged regions.
 2823                if range.end.row > range.start.row {
 2824                    let offset = range.start.to_offset(&snapshot);
 2825                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2826                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2827                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2828                        (
 2829                            snapshot.anchor_after(offset + range.start)
 2830                                ..snapshot.anchor_before(offset + range.end),
 2831                            replacement,
 2832                        )
 2833                    }));
 2834                } else if range.end == range.start {
 2835                    let anchor = snapshot.anchor_after(range.start);
 2836                    edits.push((anchor..anchor, new_text.into()));
 2837                } else {
 2838                    let edit_start = snapshot.anchor_after(range.start);
 2839                    let edit_end = snapshot.anchor_before(range.end);
 2840                    edits.push((edit_start..edit_end, new_text.into()));
 2841                }
 2842            }
 2843
 2844            Ok(edits)
 2845        })
 2846    }
 2847
 2848    pub(crate) async fn deserialize_workspace_edit(
 2849        this: Entity<LspStore>,
 2850        edit: lsp::WorkspaceEdit,
 2851        push_to_history: bool,
 2852        language_server: Arc<LanguageServer>,
 2853        cx: &mut AsyncApp,
 2854    ) -> Result<ProjectTransaction> {
 2855        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2856
 2857        let mut operations = Vec::new();
 2858        if let Some(document_changes) = edit.document_changes {
 2859            match document_changes {
 2860                lsp::DocumentChanges::Edits(edits) => {
 2861                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2862                }
 2863                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2864            }
 2865        } else if let Some(changes) = edit.changes {
 2866            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2867                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2868                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2869                        uri,
 2870                        version: None,
 2871                    },
 2872                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2873                })
 2874            }));
 2875        }
 2876
 2877        let mut project_transaction = ProjectTransaction::default();
 2878        for operation in operations {
 2879            match operation {
 2880                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2881                    let abs_path = op
 2882                        .uri
 2883                        .to_file_path()
 2884                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2885
 2886                    if let Some(parent_path) = abs_path.parent() {
 2887                        fs.create_dir(parent_path).await?;
 2888                    }
 2889                    if abs_path.ends_with("/") {
 2890                        fs.create_dir(&abs_path).await?;
 2891                    } else {
 2892                        fs.create_file(
 2893                            &abs_path,
 2894                            op.options
 2895                                .map(|options| fs::CreateOptions {
 2896                                    overwrite: options.overwrite.unwrap_or(false),
 2897                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2898                                })
 2899                                .unwrap_or_default(),
 2900                        )
 2901                        .await?;
 2902                    }
 2903                }
 2904
 2905                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2906                    let source_abs_path = op
 2907                        .old_uri
 2908                        .to_file_path()
 2909                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2910                    let target_abs_path = op
 2911                        .new_uri
 2912                        .to_file_path()
 2913                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2914                    fs.rename(
 2915                        &source_abs_path,
 2916                        &target_abs_path,
 2917                        op.options
 2918                            .map(|options| fs::RenameOptions {
 2919                                overwrite: options.overwrite.unwrap_or(false),
 2920                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2921                            })
 2922                            .unwrap_or_default(),
 2923                    )
 2924                    .await?;
 2925                }
 2926
 2927                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 2928                    let abs_path = op
 2929                        .uri
 2930                        .to_file_path()
 2931                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2932                    let options = op
 2933                        .options
 2934                        .map(|options| fs::RemoveOptions {
 2935                            recursive: options.recursive.unwrap_or(false),
 2936                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 2937                        })
 2938                        .unwrap_or_default();
 2939                    if abs_path.ends_with("/") {
 2940                        fs.remove_dir(&abs_path, options).await?;
 2941                    } else {
 2942                        fs.remove_file(&abs_path, options).await?;
 2943                    }
 2944                }
 2945
 2946                lsp::DocumentChangeOperation::Edit(op) => {
 2947                    let buffer_to_edit = this
 2948                        .update(cx, |this, cx| {
 2949                            this.open_local_buffer_via_lsp(
 2950                                op.text_document.uri.clone(),
 2951                                language_server.server_id(),
 2952                                cx,
 2953                            )
 2954                        })?
 2955                        .await?;
 2956
 2957                    let edits = this
 2958                        .update(cx, |this, cx| {
 2959                            let path = buffer_to_edit.read(cx).project_path(cx);
 2960                            let active_entry = this.active_entry;
 2961                            let is_active_entry = path.is_some_and(|project_path| {
 2962                                this.worktree_store
 2963                                    .read(cx)
 2964                                    .entry_for_path(&project_path, cx)
 2965                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 2966                            });
 2967                            let local = this.as_local_mut().unwrap();
 2968
 2969                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 2970                            for edit in op.edits {
 2971                                match edit {
 2972                                    Edit::Plain(edit) => {
 2973                                        if !edits.contains(&edit) {
 2974                                            edits.push(edit)
 2975                                        }
 2976                                    }
 2977                                    Edit::Annotated(edit) => {
 2978                                        if !edits.contains(&edit.text_edit) {
 2979                                            edits.push(edit.text_edit)
 2980                                        }
 2981                                    }
 2982                                    Edit::Snippet(edit) => {
 2983                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 2984                                        else {
 2985                                            continue;
 2986                                        };
 2987
 2988                                        if is_active_entry {
 2989                                            snippet_edits.push((edit.range, snippet));
 2990                                        } else {
 2991                                            // Since this buffer is not focused, apply a normal edit.
 2992                                            let new_edit = TextEdit {
 2993                                                range: edit.range,
 2994                                                new_text: snippet.text,
 2995                                            };
 2996                                            if !edits.contains(&new_edit) {
 2997                                                edits.push(new_edit);
 2998                                            }
 2999                                        }
 3000                                    }
 3001                                }
 3002                            }
 3003                            if !snippet_edits.is_empty() {
 3004                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3005                                let version = if let Some(buffer_version) = op.text_document.version
 3006                                {
 3007                                    local
 3008                                        .buffer_snapshot_for_lsp_version(
 3009                                            &buffer_to_edit,
 3010                                            language_server.server_id(),
 3011                                            Some(buffer_version),
 3012                                            cx,
 3013                                        )
 3014                                        .ok()
 3015                                        .map(|snapshot| snapshot.version)
 3016                                } else {
 3017                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3018                                };
 3019
 3020                                let most_recent_edit = version.and_then(|version| {
 3021                                    version.iter().max_by_key(|timestamp| timestamp.value)
 3022                                });
 3023                                // Check if the edit that triggered that edit has been made by this participant.
 3024
 3025                                if let Some(most_recent_edit) = most_recent_edit {
 3026                                    cx.emit(LspStoreEvent::SnippetEdit {
 3027                                        buffer_id,
 3028                                        edits: snippet_edits,
 3029                                        most_recent_edit,
 3030                                    });
 3031                                }
 3032                            }
 3033
 3034                            local.edits_from_lsp(
 3035                                &buffer_to_edit,
 3036                                edits,
 3037                                language_server.server_id(),
 3038                                op.text_document.version,
 3039                                cx,
 3040                            )
 3041                        })?
 3042                        .await?;
 3043
 3044                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3045                        buffer.finalize_last_transaction();
 3046                        buffer.start_transaction();
 3047                        for (range, text) in edits {
 3048                            buffer.edit([(range, text)], None, cx);
 3049                        }
 3050
 3051                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3052                            if push_to_history {
 3053                                buffer.finalize_last_transaction();
 3054                                buffer.get_transaction(transaction_id).cloned()
 3055                            } else {
 3056                                buffer.forget_transaction(transaction_id)
 3057                            }
 3058                        })
 3059                    })?;
 3060                    if let Some(transaction) = transaction {
 3061                        project_transaction.0.insert(buffer_to_edit, transaction);
 3062                    }
 3063                }
 3064            }
 3065        }
 3066
 3067        Ok(project_transaction)
 3068    }
 3069
 3070    async fn on_lsp_workspace_edit(
 3071        this: WeakEntity<LspStore>,
 3072        params: lsp::ApplyWorkspaceEditParams,
 3073        server_id: LanguageServerId,
 3074        cx: &mut AsyncApp,
 3075    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3076        let this = this.upgrade().context("project project closed")?;
 3077        let language_server = this
 3078            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3079            .context("language server not found")?;
 3080        let transaction = Self::deserialize_workspace_edit(
 3081            this.clone(),
 3082            params.edit,
 3083            true,
 3084            language_server.clone(),
 3085            cx,
 3086        )
 3087        .await
 3088        .log_err();
 3089        this.update(cx, |this, _| {
 3090            if let Some(transaction) = transaction {
 3091                this.as_local_mut()
 3092                    .unwrap()
 3093                    .last_workspace_edits_by_language_server
 3094                    .insert(server_id, transaction);
 3095            }
 3096        })?;
 3097        Ok(lsp::ApplyWorkspaceEditResponse {
 3098            applied: true,
 3099            failed_change: None,
 3100            failure_reason: None,
 3101        })
 3102    }
 3103
 3104    fn remove_worktree(
 3105        &mut self,
 3106        id_to_remove: WorktreeId,
 3107        cx: &mut Context<LspStore>,
 3108    ) -> Vec<LanguageServerId> {
 3109        self.diagnostics.remove(&id_to_remove);
 3110        self.prettier_store.update(cx, |prettier_store, cx| {
 3111            prettier_store.remove_worktree(id_to_remove, cx);
 3112        });
 3113
 3114        let mut servers_to_remove = BTreeSet::default();
 3115        let mut servers_to_preserve = HashSet::default();
 3116        for (seed, state) in &self.language_server_ids {
 3117            if seed.worktree_id == id_to_remove {
 3118                servers_to_remove.insert(state.id);
 3119            } else {
 3120                servers_to_preserve.insert(state.id);
 3121            }
 3122        }
 3123        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3124        self.language_server_ids
 3125            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3126        for server_id_to_remove in &servers_to_remove {
 3127            self.language_server_watched_paths
 3128                .remove(server_id_to_remove);
 3129            self.language_server_paths_watched_for_rename
 3130                .remove(server_id_to_remove);
 3131            self.last_workspace_edits_by_language_server
 3132                .remove(server_id_to_remove);
 3133            self.language_servers.remove(server_id_to_remove);
 3134            self.buffer_pull_diagnostics_result_ids
 3135                .remove(server_id_to_remove);
 3136            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3137                buffer_servers.remove(server_id_to_remove);
 3138            }
 3139            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3140        }
 3141        servers_to_remove.into_iter().collect()
 3142    }
 3143
 3144    fn rebuild_watched_paths_inner<'a>(
 3145        &'a self,
 3146        language_server_id: LanguageServerId,
 3147        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3148        cx: &mut Context<LspStore>,
 3149    ) -> LanguageServerWatchedPathsBuilder {
 3150        let worktrees = self
 3151            .worktree_store
 3152            .read(cx)
 3153            .worktrees()
 3154            .filter_map(|worktree| {
 3155                self.language_servers_for_worktree(worktree.read(cx).id())
 3156                    .find(|server| server.server_id() == language_server_id)
 3157                    .map(|_| worktree)
 3158            })
 3159            .collect::<Vec<_>>();
 3160
 3161        let mut worktree_globs = HashMap::default();
 3162        let mut abs_globs = HashMap::default();
 3163        log::trace!(
 3164            "Processing new watcher paths for language server with id {}",
 3165            language_server_id
 3166        );
 3167
 3168        for watcher in watchers {
 3169            if let Some((worktree, literal_prefix, pattern)) =
 3170                self.worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3171            {
 3172                worktree.update(cx, |worktree, _| {
 3173                    if let Some((tree, glob)) =
 3174                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3175                    {
 3176                        tree.add_path_prefix_to_scan(literal_prefix);
 3177                        worktree_globs
 3178                            .entry(tree.id())
 3179                            .or_insert_with(GlobSetBuilder::new)
 3180                            .add(glob);
 3181                    }
 3182                });
 3183            } else {
 3184                let (path, pattern) = match &watcher.glob_pattern {
 3185                    lsp::GlobPattern::String(s) => {
 3186                        let watcher_path = SanitizedPath::new(s);
 3187                        let path = glob_literal_prefix(watcher_path.as_path());
 3188                        let pattern = watcher_path
 3189                            .as_path()
 3190                            .strip_prefix(&path)
 3191                            .map(|p| p.to_string_lossy().to_string())
 3192                            .unwrap_or_else(|e| {
 3193                                debug_panic!(
 3194                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3195                                    s,
 3196                                    path.display(),
 3197                                    e
 3198                                );
 3199                                watcher_path.as_path().to_string_lossy().to_string()
 3200                            });
 3201                        (path, pattern)
 3202                    }
 3203                    lsp::GlobPattern::Relative(rp) => {
 3204                        let Ok(mut base_uri) = match &rp.base_uri {
 3205                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3206                            lsp::OneOf::Right(base_uri) => base_uri,
 3207                        }
 3208                        .to_file_path() else {
 3209                            continue;
 3210                        };
 3211
 3212                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3213                        let pattern = Path::new(&rp.pattern)
 3214                            .strip_prefix(&path)
 3215                            .map(|p| p.to_string_lossy().to_string())
 3216                            .unwrap_or_else(|e| {
 3217                                debug_panic!(
 3218                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3219                                    rp.pattern,
 3220                                    path.display(),
 3221                                    e
 3222                                );
 3223                                rp.pattern.clone()
 3224                            });
 3225                        base_uri.push(path);
 3226                        (base_uri, pattern)
 3227                    }
 3228                };
 3229
 3230                if let Some(glob) = Glob::new(&pattern).log_err() {
 3231                    if !path
 3232                        .components()
 3233                        .any(|c| matches!(c, path::Component::Normal(_)))
 3234                    {
 3235                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3236                        // rather than adding a new watcher for `/`.
 3237                        for worktree in &worktrees {
 3238                            worktree_globs
 3239                                .entry(worktree.read(cx).id())
 3240                                .or_insert_with(GlobSetBuilder::new)
 3241                                .add(glob.clone());
 3242                        }
 3243                    } else {
 3244                        abs_globs
 3245                            .entry(path.into())
 3246                            .or_insert_with(GlobSetBuilder::new)
 3247                            .add(glob);
 3248                    }
 3249                }
 3250            }
 3251        }
 3252
 3253        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3254        for (worktree_id, builder) in worktree_globs {
 3255            if let Ok(globset) = builder.build() {
 3256                watch_builder.watch_worktree(worktree_id, globset);
 3257            }
 3258        }
 3259        for (abs_path, builder) in abs_globs {
 3260            if let Ok(globset) = builder.build() {
 3261                watch_builder.watch_abs_path(abs_path, globset);
 3262            }
 3263        }
 3264        watch_builder
 3265    }
 3266
 3267    fn worktree_and_path_for_file_watcher(
 3268        &self,
 3269        worktrees: &[Entity<Worktree>],
 3270        watcher: &FileSystemWatcher,
 3271        cx: &App,
 3272    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3273        worktrees.iter().find_map(|worktree| {
 3274            let tree = worktree.read(cx);
 3275            let worktree_root_path = tree.abs_path();
 3276            let path_style = tree.path_style();
 3277            match &watcher.glob_pattern {
 3278                lsp::GlobPattern::String(s) => {
 3279                    let watcher_path = SanitizedPath::new(s);
 3280                    let relative = watcher_path
 3281                        .as_path()
 3282                        .strip_prefix(&worktree_root_path)
 3283                        .ok()?;
 3284                    let literal_prefix = glob_literal_prefix(relative);
 3285                    Some((
 3286                        worktree.clone(),
 3287                        RelPath::from_std_path(&literal_prefix, path_style).ok()?,
 3288                        relative.to_string_lossy().to_string(),
 3289                    ))
 3290                }
 3291                lsp::GlobPattern::Relative(rp) => {
 3292                    let base_uri = match &rp.base_uri {
 3293                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3294                        lsp::OneOf::Right(base_uri) => base_uri,
 3295                    }
 3296                    .to_file_path()
 3297                    .ok()?;
 3298                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3299                    let mut literal_prefix = relative.to_owned();
 3300                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3301                    Some((
 3302                        worktree.clone(),
 3303                        RelPath::from_std_path(&literal_prefix, path_style).ok()?,
 3304                        rp.pattern.clone(),
 3305                    ))
 3306                }
 3307            }
 3308        })
 3309    }
 3310
 3311    fn rebuild_watched_paths(
 3312        &mut self,
 3313        language_server_id: LanguageServerId,
 3314        cx: &mut Context<LspStore>,
 3315    ) {
 3316        let Some(watchers) = self
 3317            .language_server_watcher_registrations
 3318            .get(&language_server_id)
 3319        else {
 3320            return;
 3321        };
 3322
 3323        let watch_builder =
 3324            self.rebuild_watched_paths_inner(language_server_id, watchers.values().flatten(), cx);
 3325        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3326        self.language_server_watched_paths
 3327            .insert(language_server_id, watcher);
 3328
 3329        cx.notify();
 3330    }
 3331
 3332    fn on_lsp_did_change_watched_files(
 3333        &mut self,
 3334        language_server_id: LanguageServerId,
 3335        registration_id: &str,
 3336        params: DidChangeWatchedFilesRegistrationOptions,
 3337        cx: &mut Context<LspStore>,
 3338    ) {
 3339        let registrations = self
 3340            .language_server_watcher_registrations
 3341            .entry(language_server_id)
 3342            .or_default();
 3343
 3344        registrations.insert(registration_id.to_string(), params.watchers);
 3345
 3346        self.rebuild_watched_paths(language_server_id, cx);
 3347    }
 3348
 3349    fn on_lsp_unregister_did_change_watched_files(
 3350        &mut self,
 3351        language_server_id: LanguageServerId,
 3352        registration_id: &str,
 3353        cx: &mut Context<LspStore>,
 3354    ) {
 3355        let registrations = self
 3356            .language_server_watcher_registrations
 3357            .entry(language_server_id)
 3358            .or_default();
 3359
 3360        if registrations.remove(registration_id).is_some() {
 3361            log::info!(
 3362                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3363                language_server_id,
 3364                registration_id
 3365            );
 3366        } else {
 3367            log::warn!(
 3368                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3369                language_server_id,
 3370                registration_id
 3371            );
 3372        }
 3373
 3374        self.rebuild_watched_paths(language_server_id, cx);
 3375    }
 3376
 3377    async fn initialization_options_for_adapter(
 3378        adapter: Arc<dyn LspAdapter>,
 3379        delegate: &Arc<dyn LspAdapterDelegate>,
 3380    ) -> Result<Option<serde_json::Value>> {
 3381        let Some(mut initialization_config) =
 3382            adapter.clone().initialization_options(delegate).await?
 3383        else {
 3384            return Ok(None);
 3385        };
 3386
 3387        for other_adapter in delegate.registered_lsp_adapters() {
 3388            if other_adapter.name() == adapter.name() {
 3389                continue;
 3390            }
 3391            if let Ok(Some(target_config)) = other_adapter
 3392                .clone()
 3393                .additional_initialization_options(adapter.name(), delegate)
 3394                .await
 3395            {
 3396                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3397            }
 3398        }
 3399
 3400        Ok(Some(initialization_config))
 3401    }
 3402
 3403    async fn workspace_configuration_for_adapter(
 3404        adapter: Arc<dyn LspAdapter>,
 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(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(), 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<RelPath>, 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: SymbolLocation,
 3579    pub name: String,
 3580    pub kind: lsp::SymbolKind,
 3581    pub range: Range<Unclipped<PointUtf16>>,
 3582}
 3583
 3584#[derive(Clone, Debug, PartialEq, Eq)]
 3585pub enum SymbolLocation {
 3586    InProject(ProjectPath),
 3587    OutsideProject {
 3588        abs_path: Arc<Path>,
 3589        signature: [u8; 32],
 3590    },
 3591}
 3592
 3593impl SymbolLocation {
 3594    fn file_name(&self) -> Option<&str> {
 3595        match self {
 3596            Self::InProject(path) => path.path.file_name(),
 3597            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3598        }
 3599    }
 3600}
 3601
 3602impl LspStore {
 3603    pub fn init(client: &AnyProtoClient) {
 3604        client.add_entity_request_handler(Self::handle_lsp_query);
 3605        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3606        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3607        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3608        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3609        client.add_entity_message_handler(Self::handle_start_language_server);
 3610        client.add_entity_message_handler(Self::handle_update_language_server);
 3611        client.add_entity_message_handler(Self::handle_language_server_log);
 3612        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3613        client.add_entity_request_handler(Self::handle_format_buffers);
 3614        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3615        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3616        client.add_entity_request_handler(Self::handle_apply_code_action);
 3617        client.add_entity_request_handler(Self::handle_inlay_hints);
 3618        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3619        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3620        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3621        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3622        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3623        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3624        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3625        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3626        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3627        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3628        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3629        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3630        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3631        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3632        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3633        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3634        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3635
 3636        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3637        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3638        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3639        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3640        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3641        client.add_entity_request_handler(
 3642            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3643        );
 3644        client.add_entity_request_handler(
 3645            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3646        );
 3647        client.add_entity_request_handler(
 3648            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3649        );
 3650    }
 3651
 3652    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3653        match &self.mode {
 3654            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3655            _ => None,
 3656        }
 3657    }
 3658
 3659    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3660        match &self.mode {
 3661            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3662            _ => None,
 3663        }
 3664    }
 3665
 3666    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3667        match &mut self.mode {
 3668            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3669            _ => None,
 3670        }
 3671    }
 3672
 3673    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3674        match &self.mode {
 3675            LspStoreMode::Remote(RemoteLspStore {
 3676                upstream_client: Some(upstream_client),
 3677                upstream_project_id,
 3678                ..
 3679            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3680
 3681            LspStoreMode::Remote(RemoteLspStore {
 3682                upstream_client: None,
 3683                ..
 3684            }) => None,
 3685            LspStoreMode::Local(_) => None,
 3686        }
 3687    }
 3688
 3689    pub fn new_local(
 3690        buffer_store: Entity<BufferStore>,
 3691        worktree_store: Entity<WorktreeStore>,
 3692        prettier_store: Entity<PrettierStore>,
 3693        toolchain_store: Entity<LocalToolchainStore>,
 3694        environment: Entity<ProjectEnvironment>,
 3695        manifest_tree: Entity<ManifestTree>,
 3696        languages: Arc<LanguageRegistry>,
 3697        http_client: Arc<dyn HttpClient>,
 3698        fs: Arc<dyn Fs>,
 3699        cx: &mut Context<Self>,
 3700    ) -> Self {
 3701        let yarn = YarnPathStore::new(fs.clone(), cx);
 3702        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3703            .detach();
 3704        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3705            .detach();
 3706        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3707            .detach();
 3708        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3709            .detach();
 3710        if let Some(extension_events) = extension::ExtensionEvents::try_global(cx).as_ref() {
 3711            cx.subscribe(
 3712                extension_events,
 3713                Self::reload_zed_json_schemas_on_extensions_changed,
 3714            )
 3715            .detach();
 3716        } else {
 3717            log::debug!("No extension events global found. Skipping JSON schema auto-reload setup");
 3718        }
 3719        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3720            .detach();
 3721        subscribe_to_binary_statuses(&languages, cx).detach();
 3722
 3723        let _maintain_workspace_config = {
 3724            let (sender, receiver) = watch::channel();
 3725            (Self::maintain_workspace_config(receiver, cx), sender)
 3726        };
 3727
 3728        Self {
 3729            mode: LspStoreMode::Local(LocalLspStore {
 3730                weak: cx.weak_entity(),
 3731                worktree_store: worktree_store.clone(),
 3732
 3733                supplementary_language_servers: Default::default(),
 3734                languages: languages.clone(),
 3735                language_server_ids: Default::default(),
 3736                language_servers: Default::default(),
 3737                last_workspace_edits_by_language_server: Default::default(),
 3738                language_server_watched_paths: Default::default(),
 3739                language_server_paths_watched_for_rename: Default::default(),
 3740                language_server_watcher_registrations: Default::default(),
 3741                buffers_being_formatted: Default::default(),
 3742                buffer_snapshots: Default::default(),
 3743                prettier_store,
 3744                environment,
 3745                http_client,
 3746                fs,
 3747                yarn,
 3748                next_diagnostic_group_id: Default::default(),
 3749                diagnostics: Default::default(),
 3750                _subscription: cx.on_app_quit(|this, cx| {
 3751                    this.as_local_mut()
 3752                        .unwrap()
 3753                        .shutdown_language_servers_on_quit(cx)
 3754                }),
 3755                lsp_tree: LanguageServerTree::new(
 3756                    manifest_tree,
 3757                    languages.clone(),
 3758                    toolchain_store.clone(),
 3759                ),
 3760                toolchain_store,
 3761                registered_buffers: HashMap::default(),
 3762                buffers_opened_in_servers: HashMap::default(),
 3763                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3764                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3765                    .manifest_file_names(),
 3766            }),
 3767            last_formatting_failure: None,
 3768            downstream_client: None,
 3769            buffer_store,
 3770            worktree_store,
 3771            languages: languages.clone(),
 3772            language_server_statuses: Default::default(),
 3773            nonce: StdRng::from_os_rng().random(),
 3774            diagnostic_summaries: HashMap::default(),
 3775            lsp_server_capabilities: HashMap::default(),
 3776            lsp_document_colors: HashMap::default(),
 3777            lsp_code_lens: HashMap::default(),
 3778            running_lsp_requests: HashMap::default(),
 3779            active_entry: None,
 3780            _maintain_workspace_config,
 3781            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3782        }
 3783    }
 3784
 3785    fn send_lsp_proto_request<R: LspCommand>(
 3786        &self,
 3787        buffer: Entity<Buffer>,
 3788        client: AnyProtoClient,
 3789        upstream_project_id: u64,
 3790        request: R,
 3791        cx: &mut Context<LspStore>,
 3792    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3793        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3794            return Task::ready(Ok(R::Response::default()));
 3795        }
 3796        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3797        cx.spawn(async move |this, cx| {
 3798            let response = client.request(message).await?;
 3799            let this = this.upgrade().context("project dropped")?;
 3800            request
 3801                .response_from_proto(response, this, buffer, cx.clone())
 3802                .await
 3803        })
 3804    }
 3805
 3806    pub(super) fn new_remote(
 3807        buffer_store: Entity<BufferStore>,
 3808        worktree_store: Entity<WorktreeStore>,
 3809        languages: Arc<LanguageRegistry>,
 3810        upstream_client: AnyProtoClient,
 3811        project_id: u64,
 3812        cx: &mut Context<Self>,
 3813    ) -> Self {
 3814        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3815            .detach();
 3816        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3817            .detach();
 3818        subscribe_to_binary_statuses(&languages, cx).detach();
 3819        let _maintain_workspace_config = {
 3820            let (sender, receiver) = watch::channel();
 3821            (Self::maintain_workspace_config(receiver, cx), sender)
 3822        };
 3823        Self {
 3824            mode: LspStoreMode::Remote(RemoteLspStore {
 3825                upstream_client: Some(upstream_client),
 3826                upstream_project_id: project_id,
 3827            }),
 3828            downstream_client: None,
 3829            last_formatting_failure: None,
 3830            buffer_store,
 3831            worktree_store,
 3832            languages: languages.clone(),
 3833            language_server_statuses: Default::default(),
 3834            nonce: StdRng::from_os_rng().random(),
 3835            diagnostic_summaries: HashMap::default(),
 3836            lsp_server_capabilities: HashMap::default(),
 3837            lsp_document_colors: HashMap::default(),
 3838            lsp_code_lens: HashMap::default(),
 3839            running_lsp_requests: HashMap::default(),
 3840            active_entry: None,
 3841
 3842            _maintain_workspace_config,
 3843            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3844        }
 3845    }
 3846
 3847    fn on_buffer_store_event(
 3848        &mut self,
 3849        _: Entity<BufferStore>,
 3850        event: &BufferStoreEvent,
 3851        cx: &mut Context<Self>,
 3852    ) {
 3853        match event {
 3854            BufferStoreEvent::BufferAdded(buffer) => {
 3855                self.on_buffer_added(buffer, cx).log_err();
 3856            }
 3857            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3858                let buffer_id = buffer.read(cx).remote_id();
 3859                if let Some(local) = self.as_local_mut()
 3860                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3861                {
 3862                    local.reset_buffer(buffer, old_file, cx);
 3863
 3864                    if local.registered_buffers.contains_key(&buffer_id) {
 3865                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3866                    }
 3867                }
 3868
 3869                self.detect_language_for_buffer(buffer, cx);
 3870                if let Some(local) = self.as_local_mut() {
 3871                    local.initialize_buffer(buffer, cx);
 3872                    if local.registered_buffers.contains_key(&buffer_id) {
 3873                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3874                    }
 3875                }
 3876            }
 3877            _ => {}
 3878        }
 3879    }
 3880
 3881    fn on_worktree_store_event(
 3882        &mut self,
 3883        _: Entity<WorktreeStore>,
 3884        event: &WorktreeStoreEvent,
 3885        cx: &mut Context<Self>,
 3886    ) {
 3887        match event {
 3888            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3889                if !worktree.read(cx).is_local() {
 3890                    return;
 3891                }
 3892                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3893                    worktree::Event::UpdatedEntries(changes) => {
 3894                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 3895                    }
 3896                    worktree::Event::UpdatedGitRepositories(_)
 3897                    | worktree::Event::DeletedEntry(_) => {}
 3898                })
 3899                .detach()
 3900            }
 3901            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 3902            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 3903                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 3904            }
 3905            WorktreeStoreEvent::WorktreeReleased(..)
 3906            | WorktreeStoreEvent::WorktreeOrderChanged
 3907            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 3908            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 3909            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 3910        }
 3911    }
 3912
 3913    fn on_prettier_store_event(
 3914        &mut self,
 3915        _: Entity<PrettierStore>,
 3916        event: &PrettierStoreEvent,
 3917        cx: &mut Context<Self>,
 3918    ) {
 3919        match event {
 3920            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 3921                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 3922            }
 3923            PrettierStoreEvent::LanguageServerAdded {
 3924                new_server_id,
 3925                name,
 3926                prettier_server,
 3927            } => {
 3928                self.register_supplementary_language_server(
 3929                    *new_server_id,
 3930                    name.clone(),
 3931                    prettier_server.clone(),
 3932                    cx,
 3933                );
 3934            }
 3935        }
 3936    }
 3937
 3938    fn on_toolchain_store_event(
 3939        &mut self,
 3940        _: Entity<LocalToolchainStore>,
 3941        event: &ToolchainStoreEvent,
 3942        _: &mut Context<Self>,
 3943    ) {
 3944        if let ToolchainStoreEvent::ToolchainActivated = event {
 3945            self.request_workspace_config_refresh()
 3946        }
 3947    }
 3948
 3949    fn request_workspace_config_refresh(&mut self) {
 3950        *self._maintain_workspace_config.1.borrow_mut() = ();
 3951    }
 3952
 3953    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 3954        self.as_local().map(|local| local.prettier_store.clone())
 3955    }
 3956
 3957    fn on_buffer_event(
 3958        &mut self,
 3959        buffer: Entity<Buffer>,
 3960        event: &language::BufferEvent,
 3961        cx: &mut Context<Self>,
 3962    ) {
 3963        match event {
 3964            language::BufferEvent::Edited => {
 3965                self.on_buffer_edited(buffer, cx);
 3966            }
 3967
 3968            language::BufferEvent::Saved => {
 3969                self.on_buffer_saved(buffer, cx);
 3970            }
 3971
 3972            _ => {}
 3973        }
 3974    }
 3975
 3976    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 3977        buffer
 3978            .read(cx)
 3979            .set_language_registry(self.languages.clone());
 3980
 3981        cx.subscribe(buffer, |this, buffer, event, cx| {
 3982            this.on_buffer_event(buffer, event, cx);
 3983        })
 3984        .detach();
 3985
 3986        self.detect_language_for_buffer(buffer, cx);
 3987        if let Some(local) = self.as_local_mut() {
 3988            local.initialize_buffer(buffer, cx);
 3989        }
 3990
 3991        Ok(())
 3992    }
 3993
 3994    pub fn reload_zed_json_schemas_on_extensions_changed(
 3995        &mut self,
 3996        _: Entity<extension::ExtensionEvents>,
 3997        evt: &extension::Event,
 3998        cx: &mut Context<Self>,
 3999    ) {
 4000        match evt {
 4001            extension::Event::ExtensionInstalled(_)
 4002            | extension::Event::ExtensionUninstalled(_)
 4003            | extension::Event::ConfigureExtensionRequested(_) => return,
 4004            extension::Event::ExtensionsInstalledChanged => {}
 4005        }
 4006        if self.as_local().is_none() {
 4007            return;
 4008        }
 4009        cx.spawn(async move |this, cx| {
 4010            let weak_ref = this.clone();
 4011
 4012            let servers = this
 4013                .update(cx, |this, cx| {
 4014                    let local = this.as_local()?;
 4015
 4016                    let mut servers = Vec::new();
 4017                    for (seed, state) in &local.language_server_ids {
 4018
 4019                            let Some(states) = local.language_servers.get(&state.id) else {
 4020                                continue;
 4021                            };
 4022                            let (json_adapter, json_server) = match states {
 4023                                LanguageServerState::Running {
 4024                                    adapter, server, ..
 4025                                } if adapter.adapter.is_primary_zed_json_schema_adapter() => {
 4026                                    (adapter.adapter.clone(), server.clone())
 4027                                }
 4028                                _ => continue,
 4029                            };
 4030
 4031                            let Some(worktree) = this
 4032                                .worktree_store
 4033                                .read(cx)
 4034                                .worktree_for_id(seed.worktree_id, cx)
 4035                            else {
 4036                                continue;
 4037                            };
 4038                            let json_delegate: Arc<dyn LspAdapterDelegate> =
 4039                                LocalLspAdapterDelegate::new(
 4040                                    local.languages.clone(),
 4041                                    &local.environment,
 4042                                    weak_ref.clone(),
 4043                                    &worktree,
 4044                                    local.http_client.clone(),
 4045                                    local.fs.clone(),
 4046                                    cx,
 4047                                );
 4048
 4049                            servers.push((json_adapter, json_server, json_delegate));
 4050
 4051                    }
 4052                    Some(servers)
 4053                })
 4054                .ok()
 4055                .flatten();
 4056
 4057            let Some(servers) = servers else {
 4058                return;
 4059            };
 4060
 4061            for (adapter, server, delegate) in servers {
 4062                adapter.clear_zed_json_schema_cache().await;
 4063
 4064                let Some(json_workspace_config) = LocalLspStore::workspace_configuration_for_adapter(
 4065                        adapter,
 4066                        &delegate,
 4067                        None,
 4068                        cx,
 4069                    )
 4070                    .await
 4071                    .context("generate new workspace configuration for JSON language server while trying to refresh JSON Schemas")
 4072                    .ok()
 4073                else {
 4074                    continue;
 4075                };
 4076                server
 4077                    .notify::<lsp::notification::DidChangeConfiguration>(
 4078                        &lsp::DidChangeConfigurationParams {
 4079                            settings: json_workspace_config,
 4080                        },
 4081                    )
 4082                    .ok();
 4083            }
 4084        })
 4085        .detach();
 4086    }
 4087
 4088    pub(crate) fn register_buffer_with_language_servers(
 4089        &mut self,
 4090        buffer: &Entity<Buffer>,
 4091        only_register_servers: HashSet<LanguageServerSelector>,
 4092        ignore_refcounts: bool,
 4093        cx: &mut Context<Self>,
 4094    ) -> OpenLspBufferHandle {
 4095        let buffer_id = buffer.read(cx).remote_id();
 4096        let handle = cx.new(|_| buffer.clone());
 4097        if let Some(local) = self.as_local_mut() {
 4098            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4099            if !ignore_refcounts {
 4100                *refcount += 1;
 4101            }
 4102
 4103            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4104            // 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
 4105            // 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
 4106            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4107            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4108                return handle;
 4109            };
 4110            if !file.is_local() {
 4111                return handle;
 4112            }
 4113
 4114            if ignore_refcounts || *refcount == 1 {
 4115                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4116            }
 4117            if !ignore_refcounts {
 4118                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4119                    let refcount = {
 4120                        let local = lsp_store.as_local_mut().unwrap();
 4121                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4122                            debug_panic!("bad refcounting");
 4123                            return;
 4124                        };
 4125
 4126                        *refcount -= 1;
 4127                        *refcount
 4128                    };
 4129                    if refcount == 0 {
 4130                        lsp_store.lsp_document_colors.remove(&buffer_id);
 4131                        lsp_store.lsp_code_lens.remove(&buffer_id);
 4132                        let local = lsp_store.as_local_mut().unwrap();
 4133                        local.registered_buffers.remove(&buffer_id);
 4134                        local.buffers_opened_in_servers.remove(&buffer_id);
 4135                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4136                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4137                        }
 4138                    }
 4139                })
 4140                .detach();
 4141            }
 4142        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4143            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4144            cx.background_spawn(async move {
 4145                upstream_client
 4146                    .request(proto::RegisterBufferWithLanguageServers {
 4147                        project_id: upstream_project_id,
 4148                        buffer_id,
 4149                        only_servers: only_register_servers
 4150                            .into_iter()
 4151                            .map(|selector| {
 4152                                let selector = match selector {
 4153                                    LanguageServerSelector::Id(language_server_id) => {
 4154                                        proto::language_server_selector::Selector::ServerId(
 4155                                            language_server_id.to_proto(),
 4156                                        )
 4157                                    }
 4158                                    LanguageServerSelector::Name(language_server_name) => {
 4159                                        proto::language_server_selector::Selector::Name(
 4160                                            language_server_name.to_string(),
 4161                                        )
 4162                                    }
 4163                                };
 4164                                proto::LanguageServerSelector {
 4165                                    selector: Some(selector),
 4166                                }
 4167                            })
 4168                            .collect(),
 4169                    })
 4170                    .await
 4171            })
 4172            .detach();
 4173        } else {
 4174            panic!("oops!");
 4175        }
 4176        handle
 4177    }
 4178
 4179    fn maintain_buffer_languages(
 4180        languages: Arc<LanguageRegistry>,
 4181        cx: &mut Context<Self>,
 4182    ) -> Task<()> {
 4183        let mut subscription = languages.subscribe();
 4184        let mut prev_reload_count = languages.reload_count();
 4185        cx.spawn(async move |this, cx| {
 4186            while let Some(()) = subscription.next().await {
 4187                if let Some(this) = this.upgrade() {
 4188                    // If the language registry has been reloaded, then remove and
 4189                    // re-assign the languages on all open buffers.
 4190                    let reload_count = languages.reload_count();
 4191                    if reload_count > prev_reload_count {
 4192                        prev_reload_count = reload_count;
 4193                        this.update(cx, |this, cx| {
 4194                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4195                                for buffer in buffer_store.buffers() {
 4196                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4197                                    {
 4198                                        buffer
 4199                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4200                                        if let Some(local) = this.as_local_mut() {
 4201                                            local.reset_buffer(&buffer, &f, cx);
 4202
 4203                                            if local
 4204                                                .registered_buffers
 4205                                                .contains_key(&buffer.read(cx).remote_id())
 4206                                                && let Some(file_url) =
 4207                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4208                                            {
 4209                                                local.unregister_buffer_from_language_servers(
 4210                                                    &buffer, &file_url, cx,
 4211                                                );
 4212                                            }
 4213                                        }
 4214                                    }
 4215                                }
 4216                            });
 4217                        })
 4218                        .ok();
 4219                    }
 4220
 4221                    this.update(cx, |this, cx| {
 4222                        let mut plain_text_buffers = Vec::new();
 4223                        let mut buffers_with_unknown_injections = Vec::new();
 4224                        for handle in this.buffer_store.read(cx).buffers() {
 4225                            let buffer = handle.read(cx);
 4226                            if buffer.language().is_none()
 4227                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4228                            {
 4229                                plain_text_buffers.push(handle);
 4230                            } else if buffer.contains_unknown_injections() {
 4231                                buffers_with_unknown_injections.push(handle);
 4232                            }
 4233                        }
 4234
 4235                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4236                        // and reused later in the invisible worktrees.
 4237                        plain_text_buffers.sort_by_key(|buffer| {
 4238                            Reverse(
 4239                                File::from_dyn(buffer.read(cx).file())
 4240                                    .map(|file| file.worktree.read(cx).is_visible()),
 4241                            )
 4242                        });
 4243
 4244                        for buffer in plain_text_buffers {
 4245                            this.detect_language_for_buffer(&buffer, cx);
 4246                            if let Some(local) = this.as_local_mut() {
 4247                                local.initialize_buffer(&buffer, cx);
 4248                                if local
 4249                                    .registered_buffers
 4250                                    .contains_key(&buffer.read(cx).remote_id())
 4251                                {
 4252                                    local.register_buffer_with_language_servers(
 4253                                        &buffer,
 4254                                        HashSet::default(),
 4255                                        cx,
 4256                                    );
 4257                                }
 4258                            }
 4259                        }
 4260
 4261                        for buffer in buffers_with_unknown_injections {
 4262                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4263                        }
 4264                    })
 4265                    .ok();
 4266                }
 4267            }
 4268        })
 4269    }
 4270
 4271    fn detect_language_for_buffer(
 4272        &mut self,
 4273        buffer_handle: &Entity<Buffer>,
 4274        cx: &mut Context<Self>,
 4275    ) -> Option<language::AvailableLanguage> {
 4276        // If the buffer has a language, set it and start the language server if we haven't already.
 4277        let buffer = buffer_handle.read(cx);
 4278        let file = buffer.file()?;
 4279
 4280        let content = buffer.as_rope();
 4281        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4282        if let Some(available_language) = &available_language {
 4283            if let Some(Ok(Ok(new_language))) = self
 4284                .languages
 4285                .load_language(available_language)
 4286                .now_or_never()
 4287            {
 4288                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4289            }
 4290        } else {
 4291            cx.emit(LspStoreEvent::LanguageDetected {
 4292                buffer: buffer_handle.clone(),
 4293                new_language: None,
 4294            });
 4295        }
 4296
 4297        available_language
 4298    }
 4299
 4300    pub(crate) fn set_language_for_buffer(
 4301        &mut self,
 4302        buffer_entity: &Entity<Buffer>,
 4303        new_language: Arc<Language>,
 4304        cx: &mut Context<Self>,
 4305    ) {
 4306        let buffer = buffer_entity.read(cx);
 4307        let buffer_file = buffer.file().cloned();
 4308        let buffer_id = buffer.remote_id();
 4309        if let Some(local_store) = self.as_local_mut()
 4310            && local_store.registered_buffers.contains_key(&buffer_id)
 4311            && let Some(abs_path) =
 4312                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4313            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4314        {
 4315            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4316        }
 4317        buffer_entity.update(cx, |buffer, cx| {
 4318            if buffer
 4319                .language()
 4320                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4321            {
 4322                buffer.set_language(Some(new_language.clone()), cx);
 4323            }
 4324        });
 4325
 4326        let settings =
 4327            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4328        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4329
 4330        let worktree_id = if let Some(file) = buffer_file {
 4331            let worktree = file.worktree.clone();
 4332
 4333            if let Some(local) = self.as_local_mut()
 4334                && local.registered_buffers.contains_key(&buffer_id)
 4335            {
 4336                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4337            }
 4338            Some(worktree.read(cx).id())
 4339        } else {
 4340            None
 4341        };
 4342
 4343        if settings.prettier.allowed
 4344            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4345        {
 4346            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4347            if let Some(prettier_store) = prettier_store {
 4348                prettier_store.update(cx, |prettier_store, cx| {
 4349                    prettier_store.install_default_prettier(
 4350                        worktree_id,
 4351                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4352                        cx,
 4353                    )
 4354                })
 4355            }
 4356        }
 4357
 4358        cx.emit(LspStoreEvent::LanguageDetected {
 4359            buffer: buffer_entity.clone(),
 4360            new_language: Some(new_language),
 4361        })
 4362    }
 4363
 4364    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4365        self.buffer_store.clone()
 4366    }
 4367
 4368    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4369        self.active_entry = active_entry;
 4370    }
 4371
 4372    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4373        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4374            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4375        {
 4376            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4377                summaries
 4378                    .iter()
 4379                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4380            });
 4381            if let Some(summary) = summaries.next() {
 4382                client
 4383                    .send(proto::UpdateDiagnosticSummary {
 4384                        project_id: downstream_project_id,
 4385                        worktree_id: worktree.id().to_proto(),
 4386                        summary: Some(summary),
 4387                        more_summaries: summaries.collect(),
 4388                    })
 4389                    .log_err();
 4390            }
 4391        }
 4392    }
 4393
 4394    fn is_capable_for_proto_request<R>(
 4395        &self,
 4396        buffer: &Entity<Buffer>,
 4397        request: &R,
 4398        cx: &Context<Self>,
 4399    ) -> bool
 4400    where
 4401        R: LspCommand,
 4402    {
 4403        self.check_if_capable_for_proto_request(
 4404            buffer,
 4405            |capabilities| {
 4406                request.check_capabilities(AdapterServerCapabilities {
 4407                    server_capabilities: capabilities.clone(),
 4408                    code_action_kinds: None,
 4409                })
 4410            },
 4411            cx,
 4412        )
 4413    }
 4414
 4415    fn check_if_capable_for_proto_request<F>(
 4416        &self,
 4417        buffer: &Entity<Buffer>,
 4418        check: F,
 4419        cx: &Context<Self>,
 4420    ) -> bool
 4421    where
 4422        F: Fn(&lsp::ServerCapabilities) -> bool,
 4423    {
 4424        let Some(language) = buffer.read(cx).language().cloned() else {
 4425            return false;
 4426        };
 4427        let relevant_language_servers = self
 4428            .languages
 4429            .lsp_adapters(&language.name())
 4430            .into_iter()
 4431            .map(|lsp_adapter| lsp_adapter.name())
 4432            .collect::<HashSet<_>>();
 4433        self.language_server_statuses
 4434            .iter()
 4435            .filter_map(|(server_id, server_status)| {
 4436                relevant_language_servers
 4437                    .contains(&server_status.name)
 4438                    .then_some(server_id)
 4439            })
 4440            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4441            .any(check)
 4442    }
 4443
 4444    pub fn request_lsp<R>(
 4445        &mut self,
 4446        buffer: Entity<Buffer>,
 4447        server: LanguageServerToQuery,
 4448        request: R,
 4449        cx: &mut Context<Self>,
 4450    ) -> Task<Result<R::Response>>
 4451    where
 4452        R: LspCommand,
 4453        <R::LspRequest as lsp::request::Request>::Result: Send,
 4454        <R::LspRequest as lsp::request::Request>::Params: Send,
 4455    {
 4456        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4457            return self.send_lsp_proto_request(
 4458                buffer,
 4459                upstream_client,
 4460                upstream_project_id,
 4461                request,
 4462                cx,
 4463            );
 4464        }
 4465
 4466        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4467            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4468                local
 4469                    .language_servers_for_buffer(buffer, cx)
 4470                    .find(|(_, server)| {
 4471                        request.check_capabilities(server.adapter_server_capabilities())
 4472                    })
 4473                    .map(|(_, server)| server.clone())
 4474            }),
 4475            LanguageServerToQuery::Other(id) => self
 4476                .language_server_for_local_buffer(buffer, id, cx)
 4477                .and_then(|(_, server)| {
 4478                    request
 4479                        .check_capabilities(server.adapter_server_capabilities())
 4480                        .then(|| Arc::clone(server))
 4481                }),
 4482        }) else {
 4483            return Task::ready(Ok(Default::default()));
 4484        };
 4485
 4486        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4487
 4488        let Some(file) = file else {
 4489            return Task::ready(Ok(Default::default()));
 4490        };
 4491
 4492        let lsp_params = match request.to_lsp_params_or_response(
 4493            &file.abs_path(cx),
 4494            buffer.read(cx),
 4495            &language_server,
 4496            cx,
 4497        ) {
 4498            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4499            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4500
 4501            Err(err) => {
 4502                let message = format!(
 4503                    "{} via {} failed: {}",
 4504                    request.display_name(),
 4505                    language_server.name(),
 4506                    err
 4507                );
 4508                log::warn!("{message}");
 4509                return Task::ready(Err(anyhow!(message)));
 4510            }
 4511        };
 4512
 4513        let status = request.status();
 4514        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4515            return Task::ready(Ok(Default::default()));
 4516        }
 4517        cx.spawn(async move |this, cx| {
 4518            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4519
 4520            let id = lsp_request.id();
 4521            let _cleanup = if status.is_some() {
 4522                cx.update(|cx| {
 4523                    this.update(cx, |this, cx| {
 4524                        this.on_lsp_work_start(
 4525                            language_server.server_id(),
 4526                            id.to_string(),
 4527                            LanguageServerProgress {
 4528                                is_disk_based_diagnostics_progress: false,
 4529                                is_cancellable: false,
 4530                                title: None,
 4531                                message: status.clone(),
 4532                                percentage: None,
 4533                                last_update_at: cx.background_executor().now(),
 4534                            },
 4535                            cx,
 4536                        );
 4537                    })
 4538                })
 4539                .log_err();
 4540
 4541                Some(defer(|| {
 4542                    cx.update(|cx| {
 4543                        this.update(cx, |this, cx| {
 4544                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
 4545                        })
 4546                    })
 4547                    .log_err();
 4548                }))
 4549            } else {
 4550                None
 4551            };
 4552
 4553            let result = lsp_request.await.into_response();
 4554
 4555            let response = result.map_err(|err| {
 4556                let message = format!(
 4557                    "{} via {} failed: {}",
 4558                    request.display_name(),
 4559                    language_server.name(),
 4560                    err
 4561                );
 4562                log::warn!("{message}");
 4563                anyhow::anyhow!(message)
 4564            })?;
 4565
 4566            request
 4567                .response_from_lsp(
 4568                    response,
 4569                    this.upgrade().context("no app context")?,
 4570                    buffer,
 4571                    language_server.server_id(),
 4572                    cx.clone(),
 4573                )
 4574                .await
 4575        })
 4576    }
 4577
 4578    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4579        let mut language_formatters_to_check = Vec::new();
 4580        for buffer in self.buffer_store.read(cx).buffers() {
 4581            let buffer = buffer.read(cx);
 4582            let buffer_file = File::from_dyn(buffer.file());
 4583            let buffer_language = buffer.language();
 4584            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4585            if buffer_language.is_some() {
 4586                language_formatters_to_check.push((
 4587                    buffer_file.map(|f| f.worktree_id(cx)),
 4588                    settings.into_owned(),
 4589                ));
 4590            }
 4591        }
 4592
 4593        self.request_workspace_config_refresh();
 4594
 4595        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4596            prettier_store.update(cx, |prettier_store, cx| {
 4597                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4598            })
 4599        }
 4600
 4601        cx.notify();
 4602    }
 4603
 4604    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4605        let buffer_store = self.buffer_store.clone();
 4606        let Some(local) = self.as_local_mut() else {
 4607            return;
 4608        };
 4609        let mut adapters = BTreeMap::default();
 4610        let get_adapter = {
 4611            let languages = local.languages.clone();
 4612            let environment = local.environment.clone();
 4613            let weak = local.weak.clone();
 4614            let worktree_store = local.worktree_store.clone();
 4615            let http_client = local.http_client.clone();
 4616            let fs = local.fs.clone();
 4617            move |worktree_id, cx: &mut App| {
 4618                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4619                Some(LocalLspAdapterDelegate::new(
 4620                    languages.clone(),
 4621                    &environment,
 4622                    weak.clone(),
 4623                    &worktree,
 4624                    http_client.clone(),
 4625                    fs.clone(),
 4626                    cx,
 4627                ))
 4628            }
 4629        };
 4630
 4631        let mut messages_to_report = Vec::new();
 4632        let (new_tree, to_stop) = {
 4633            let mut rebase = local.lsp_tree.rebase();
 4634            let buffers = buffer_store
 4635                .read(cx)
 4636                .buffers()
 4637                .filter_map(|buffer| {
 4638                    let raw_buffer = buffer.read(cx);
 4639                    if !local
 4640                        .registered_buffers
 4641                        .contains_key(&raw_buffer.remote_id())
 4642                    {
 4643                        return None;
 4644                    }
 4645                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4646                    let language = raw_buffer.language().cloned()?;
 4647                    Some((file, language, raw_buffer.remote_id()))
 4648                })
 4649                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4650            for (file, language, buffer_id) in buffers {
 4651                let worktree_id = file.worktree_id(cx);
 4652                let Some(worktree) = local
 4653                    .worktree_store
 4654                    .read(cx)
 4655                    .worktree_for_id(worktree_id, cx)
 4656                else {
 4657                    continue;
 4658                };
 4659
 4660                if let Some((_, apply)) = local.reuse_existing_language_server(
 4661                    rebase.server_tree(),
 4662                    &worktree,
 4663                    &language.name(),
 4664                    cx,
 4665                ) {
 4666                    (apply)(rebase.server_tree());
 4667                } else if let Some(lsp_delegate) = adapters
 4668                    .entry(worktree_id)
 4669                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4670                    .clone()
 4671                {
 4672                    let delegate =
 4673                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4674                    let path = file
 4675                        .path()
 4676                        .parent()
 4677                        .map(Arc::from)
 4678                        .unwrap_or_else(|| file.path().clone());
 4679                    let worktree_path = ProjectPath { worktree_id, path };
 4680                    let abs_path = file.abs_path(cx);
 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.read(cx).absolutize(&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            .clone();
 5843            if !completion_settings.lsp {
 5844                return Task::ready(Ok(Vec::new()));
 5845            }
 5846
 5847            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5848                local
 5849                    .language_servers_for_buffer(buffer, cx)
 5850                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5851                    .filter(|(adapter, _)| {
 5852                        scope
 5853                            .as_ref()
 5854                            .map(|scope| scope.language_allowed(&adapter.name))
 5855                            .unwrap_or(true)
 5856                    })
 5857                    .map(|(_, server)| server.server_id())
 5858                    .collect()
 5859            });
 5860
 5861            let buffer = buffer.clone();
 5862            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5863            let lsp_timeout = if lsp_timeout > 0 {
 5864                Some(Duration::from_millis(lsp_timeout))
 5865            } else {
 5866                None
 5867            };
 5868            cx.spawn(async move |this,  cx| {
 5869                let mut tasks = Vec::with_capacity(server_ids.len());
 5870                this.update(cx, |lsp_store, cx| {
 5871                    for server_id in server_ids {
 5872                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5873                        let lsp_timeout = lsp_timeout
 5874                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5875                        let mut timeout = cx.background_spawn(async move {
 5876                            match lsp_timeout {
 5877                                Some(lsp_timeout) => {
 5878                                    lsp_timeout.await;
 5879                                    true
 5880                                },
 5881                                None => false,
 5882                            }
 5883                        }).fuse();
 5884                        let mut lsp_request = lsp_store.request_lsp(
 5885                            buffer.clone(),
 5886                            LanguageServerToQuery::Other(server_id),
 5887                            GetCompletions {
 5888                                position,
 5889                                context: context.clone(),
 5890                            },
 5891                            cx,
 5892                        ).fuse();
 5893                        let new_task = cx.background_spawn(async move {
 5894                            select_biased! {
 5895                                response = lsp_request => anyhow::Ok(Some(response?)),
 5896                                timeout_happened = timeout => {
 5897                                    if timeout_happened {
 5898                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5899                                        Ok(None)
 5900                                    } else {
 5901                                        let completions = lsp_request.await?;
 5902                                        Ok(Some(completions))
 5903                                    }
 5904                                },
 5905                            }
 5906                        });
 5907                        tasks.push((lsp_adapter, new_task));
 5908                    }
 5909                })?;
 5910
 5911                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5912                    let completion_response = task.await.ok()??;
 5913                    let completions = populate_labels_for_completions(
 5914                            completion_response.completions,
 5915                            language.clone(),
 5916                            lsp_adapter,
 5917                        )
 5918                        .await;
 5919                    Some(CompletionResponse {
 5920                        completions,
 5921                        display_options: CompletionDisplayOptions::default(),
 5922                        is_incomplete: completion_response.is_incomplete,
 5923                    })
 5924                });
 5925
 5926                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 5927
 5928                Ok(responses.into_iter().flatten().collect())
 5929            })
 5930        } else {
 5931            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5932        }
 5933    }
 5934
 5935    pub fn resolve_completions(
 5936        &self,
 5937        buffer: Entity<Buffer>,
 5938        completion_indices: Vec<usize>,
 5939        completions: Rc<RefCell<Box<[Completion]>>>,
 5940        cx: &mut Context<Self>,
 5941    ) -> Task<Result<bool>> {
 5942        let client = self.upstream_client();
 5943        let buffer_id = buffer.read(cx).remote_id();
 5944        let buffer_snapshot = buffer.read(cx).snapshot();
 5945
 5946        if !self.check_if_capable_for_proto_request(
 5947            &buffer,
 5948            GetCompletions::can_resolve_completions,
 5949            cx,
 5950        ) {
 5951            return Task::ready(Ok(false));
 5952        }
 5953        cx.spawn(async move |lsp_store, cx| {
 5954            let mut did_resolve = false;
 5955            if let Some((client, project_id)) = client {
 5956                for completion_index in completion_indices {
 5957                    let server_id = {
 5958                        let completion = &completions.borrow()[completion_index];
 5959                        completion.source.server_id()
 5960                    };
 5961                    if let Some(server_id) = server_id {
 5962                        if Self::resolve_completion_remote(
 5963                            project_id,
 5964                            server_id,
 5965                            buffer_id,
 5966                            completions.clone(),
 5967                            completion_index,
 5968                            client.clone(),
 5969                        )
 5970                        .await
 5971                        .log_err()
 5972                        .is_some()
 5973                        {
 5974                            did_resolve = true;
 5975                        }
 5976                    } else {
 5977                        resolve_word_completion(
 5978                            &buffer_snapshot,
 5979                            &mut completions.borrow_mut()[completion_index],
 5980                        );
 5981                    }
 5982                }
 5983            } else {
 5984                for completion_index in completion_indices {
 5985                    let server_id = {
 5986                        let completion = &completions.borrow()[completion_index];
 5987                        completion.source.server_id()
 5988                    };
 5989                    if let Some(server_id) = server_id {
 5990                        let server_and_adapter = lsp_store
 5991                            .read_with(cx, |lsp_store, _| {
 5992                                let server = lsp_store.language_server_for_id(server_id)?;
 5993                                let adapter =
 5994                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 5995                                Some((server, adapter))
 5996                            })
 5997                            .ok()
 5998                            .flatten();
 5999                        let Some((server, adapter)) = server_and_adapter else {
 6000                            continue;
 6001                        };
 6002
 6003                        let resolved = Self::resolve_completion_local(
 6004                            server,
 6005                            completions.clone(),
 6006                            completion_index,
 6007                        )
 6008                        .await
 6009                        .log_err()
 6010                        .is_some();
 6011                        if resolved {
 6012                            Self::regenerate_completion_labels(
 6013                                adapter,
 6014                                &buffer_snapshot,
 6015                                completions.clone(),
 6016                                completion_index,
 6017                            )
 6018                            .await
 6019                            .log_err();
 6020                            did_resolve = true;
 6021                        }
 6022                    } else {
 6023                        resolve_word_completion(
 6024                            &buffer_snapshot,
 6025                            &mut completions.borrow_mut()[completion_index],
 6026                        );
 6027                    }
 6028                }
 6029            }
 6030
 6031            Ok(did_resolve)
 6032        })
 6033    }
 6034
 6035    async fn resolve_completion_local(
 6036        server: Arc<lsp::LanguageServer>,
 6037        completions: Rc<RefCell<Box<[Completion]>>>,
 6038        completion_index: usize,
 6039    ) -> Result<()> {
 6040        let server_id = server.server_id();
 6041        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6042            return Ok(());
 6043        }
 6044
 6045        let request = {
 6046            let completion = &completions.borrow()[completion_index];
 6047            match &completion.source {
 6048                CompletionSource::Lsp {
 6049                    lsp_completion,
 6050                    resolved,
 6051                    server_id: completion_server_id,
 6052                    ..
 6053                } => {
 6054                    if *resolved {
 6055                        return Ok(());
 6056                    }
 6057                    anyhow::ensure!(
 6058                        server_id == *completion_server_id,
 6059                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6060                    );
 6061                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6062                }
 6063                CompletionSource::BufferWord { .. }
 6064                | CompletionSource::Dap { .. }
 6065                | CompletionSource::Custom => {
 6066                    return Ok(());
 6067                }
 6068            }
 6069        };
 6070        let resolved_completion = request
 6071            .await
 6072            .into_response()
 6073            .context("resolve completion")?;
 6074
 6075        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6076        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6077
 6078        let mut completions = completions.borrow_mut();
 6079        let completion = &mut completions[completion_index];
 6080        if let CompletionSource::Lsp {
 6081            lsp_completion,
 6082            resolved,
 6083            server_id: completion_server_id,
 6084            ..
 6085        } = &mut completion.source
 6086        {
 6087            if *resolved {
 6088                return Ok(());
 6089            }
 6090            anyhow::ensure!(
 6091                server_id == *completion_server_id,
 6092                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6093            );
 6094            *lsp_completion = Box::new(resolved_completion);
 6095            *resolved = true;
 6096        }
 6097        Ok(())
 6098    }
 6099
 6100    async fn regenerate_completion_labels(
 6101        adapter: Arc<CachedLspAdapter>,
 6102        snapshot: &BufferSnapshot,
 6103        completions: Rc<RefCell<Box<[Completion]>>>,
 6104        completion_index: usize,
 6105    ) -> Result<()> {
 6106        let completion_item = completions.borrow()[completion_index]
 6107            .source
 6108            .lsp_completion(true)
 6109            .map(Cow::into_owned);
 6110        if let Some(lsp_documentation) = completion_item
 6111            .as_ref()
 6112            .and_then(|completion_item| completion_item.documentation.clone())
 6113        {
 6114            let mut completions = completions.borrow_mut();
 6115            let completion = &mut completions[completion_index];
 6116            completion.documentation = Some(lsp_documentation.into());
 6117        } else {
 6118            let mut completions = completions.borrow_mut();
 6119            let completion = &mut completions[completion_index];
 6120            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6121        }
 6122
 6123        let mut new_label = match completion_item {
 6124            Some(completion_item) => {
 6125                // 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
 6126                // So we have to update the label here anyway...
 6127                let language = snapshot.language();
 6128                match language {
 6129                    Some(language) => {
 6130                        adapter
 6131                            .labels_for_completions(
 6132                                std::slice::from_ref(&completion_item),
 6133                                language,
 6134                            )
 6135                            .await?
 6136                    }
 6137                    None => Vec::new(),
 6138                }
 6139                .pop()
 6140                .flatten()
 6141                .unwrap_or_else(|| {
 6142                    CodeLabel::fallback_for_completion(
 6143                        &completion_item,
 6144                        language.map(|language| language.as_ref()),
 6145                    )
 6146                })
 6147            }
 6148            None => CodeLabel::plain(
 6149                completions.borrow()[completion_index].new_text.clone(),
 6150                None,
 6151            ),
 6152        };
 6153        ensure_uniform_list_compatible_label(&mut new_label);
 6154
 6155        let mut completions = completions.borrow_mut();
 6156        let completion = &mut completions[completion_index];
 6157        if completion.label.filter_text() == new_label.filter_text() {
 6158            completion.label = new_label;
 6159        } else {
 6160            log::error!(
 6161                "Resolved completion changed display label from {} to {}. \
 6162                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6163                completion.label.text(),
 6164                new_label.text(),
 6165                completion.label.filter_text(),
 6166                new_label.filter_text()
 6167            );
 6168        }
 6169
 6170        Ok(())
 6171    }
 6172
 6173    async fn resolve_completion_remote(
 6174        project_id: u64,
 6175        server_id: LanguageServerId,
 6176        buffer_id: BufferId,
 6177        completions: Rc<RefCell<Box<[Completion]>>>,
 6178        completion_index: usize,
 6179        client: AnyProtoClient,
 6180    ) -> Result<()> {
 6181        let lsp_completion = {
 6182            let completion = &completions.borrow()[completion_index];
 6183            match &completion.source {
 6184                CompletionSource::Lsp {
 6185                    lsp_completion,
 6186                    resolved,
 6187                    server_id: completion_server_id,
 6188                    ..
 6189                } => {
 6190                    anyhow::ensure!(
 6191                        server_id == *completion_server_id,
 6192                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6193                    );
 6194                    if *resolved {
 6195                        return Ok(());
 6196                    }
 6197                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6198                }
 6199                CompletionSource::Custom
 6200                | CompletionSource::Dap { .. }
 6201                | CompletionSource::BufferWord { .. } => {
 6202                    return Ok(());
 6203                }
 6204            }
 6205        };
 6206        let request = proto::ResolveCompletionDocumentation {
 6207            project_id,
 6208            language_server_id: server_id.0 as u64,
 6209            lsp_completion,
 6210            buffer_id: buffer_id.into(),
 6211        };
 6212
 6213        let response = client
 6214            .request(request)
 6215            .await
 6216            .context("completion documentation resolve proto request")?;
 6217        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6218
 6219        let documentation = if response.documentation.is_empty() {
 6220            CompletionDocumentation::Undocumented
 6221        } else if response.documentation_is_markdown {
 6222            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6223        } else if response.documentation.lines().count() <= 1 {
 6224            CompletionDocumentation::SingleLine(response.documentation.into())
 6225        } else {
 6226            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6227        };
 6228
 6229        let mut completions = completions.borrow_mut();
 6230        let completion = &mut completions[completion_index];
 6231        completion.documentation = Some(documentation);
 6232        if let CompletionSource::Lsp {
 6233            insert_range,
 6234            lsp_completion,
 6235            resolved,
 6236            server_id: completion_server_id,
 6237            lsp_defaults: _,
 6238        } = &mut completion.source
 6239        {
 6240            let completion_insert_range = response
 6241                .old_insert_start
 6242                .and_then(deserialize_anchor)
 6243                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6244            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6245
 6246            if *resolved {
 6247                return Ok(());
 6248            }
 6249            anyhow::ensure!(
 6250                server_id == *completion_server_id,
 6251                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6252            );
 6253            *lsp_completion = Box::new(resolved_lsp_completion);
 6254            *resolved = true;
 6255        }
 6256
 6257        let replace_range = response
 6258            .old_replace_start
 6259            .and_then(deserialize_anchor)
 6260            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6261        if let Some((old_replace_start, old_replace_end)) = replace_range
 6262            && !response.new_text.is_empty()
 6263        {
 6264            completion.new_text = response.new_text;
 6265            completion.replace_range = old_replace_start..old_replace_end;
 6266        }
 6267
 6268        Ok(())
 6269    }
 6270
 6271    pub fn apply_additional_edits_for_completion(
 6272        &self,
 6273        buffer_handle: Entity<Buffer>,
 6274        completions: Rc<RefCell<Box<[Completion]>>>,
 6275        completion_index: usize,
 6276        push_to_history: bool,
 6277        cx: &mut Context<Self>,
 6278    ) -> Task<Result<Option<Transaction>>> {
 6279        if let Some((client, project_id)) = self.upstream_client() {
 6280            let buffer = buffer_handle.read(cx);
 6281            let buffer_id = buffer.remote_id();
 6282            cx.spawn(async move |_, cx| {
 6283                let request = {
 6284                    let completion = completions.borrow()[completion_index].clone();
 6285                    proto::ApplyCompletionAdditionalEdits {
 6286                        project_id,
 6287                        buffer_id: buffer_id.into(),
 6288                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6289                            replace_range: completion.replace_range,
 6290                            new_text: completion.new_text,
 6291                            source: completion.source,
 6292                        })),
 6293                    }
 6294                };
 6295
 6296                if let Some(transaction) = client.request(request).await?.transaction {
 6297                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6298                    buffer_handle
 6299                        .update(cx, |buffer, _| {
 6300                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6301                        })?
 6302                        .await?;
 6303                    if push_to_history {
 6304                        buffer_handle.update(cx, |buffer, _| {
 6305                            buffer.push_transaction(transaction.clone(), Instant::now());
 6306                            buffer.finalize_last_transaction();
 6307                        })?;
 6308                    }
 6309                    Ok(Some(transaction))
 6310                } else {
 6311                    Ok(None)
 6312                }
 6313            })
 6314        } else {
 6315            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6316                let completion = &completions.borrow()[completion_index];
 6317                let server_id = completion.source.server_id()?;
 6318                Some(
 6319                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6320                        .1
 6321                        .clone(),
 6322                )
 6323            }) else {
 6324                return Task::ready(Ok(None));
 6325            };
 6326
 6327            cx.spawn(async move |this, cx| {
 6328                Self::resolve_completion_local(
 6329                    server.clone(),
 6330                    completions.clone(),
 6331                    completion_index,
 6332                )
 6333                .await
 6334                .context("resolving completion")?;
 6335                let completion = completions.borrow()[completion_index].clone();
 6336                let additional_text_edits = completion
 6337                    .source
 6338                    .lsp_completion(true)
 6339                    .as_ref()
 6340                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6341                if let Some(edits) = additional_text_edits {
 6342                    let edits = this
 6343                        .update(cx, |this, cx| {
 6344                            this.as_local_mut().unwrap().edits_from_lsp(
 6345                                &buffer_handle,
 6346                                edits,
 6347                                server.server_id(),
 6348                                None,
 6349                                cx,
 6350                            )
 6351                        })?
 6352                        .await?;
 6353
 6354                    buffer_handle.update(cx, |buffer, cx| {
 6355                        buffer.finalize_last_transaction();
 6356                        buffer.start_transaction();
 6357
 6358                        for (range, text) in edits {
 6359                            let primary = &completion.replace_range;
 6360
 6361                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6362                            // and the primary completion is just an insertion (empty range), then this is likely
 6363                            // an auto-import scenario and should not be considered overlapping
 6364                            // https://github.com/zed-industries/zed/issues/26136
 6365                            let is_file_start_auto_import = {
 6366                                let snapshot = buffer.snapshot();
 6367                                let primary_start_point = primary.start.to_point(&snapshot);
 6368                                let range_start_point = range.start.to_point(&snapshot);
 6369
 6370                                let result = primary_start_point.row == 0
 6371                                    && primary_start_point.column == 0
 6372                                    && range_start_point.row == 0
 6373                                    && range_start_point.column == 0;
 6374
 6375                                result
 6376                            };
 6377
 6378                            let has_overlap = if is_file_start_auto_import {
 6379                                false
 6380                            } else {
 6381                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6382                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6383                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6384                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6385                                let result = start_within || end_within;
 6386                                result
 6387                            };
 6388
 6389                            //Skip additional edits which overlap with the primary completion edit
 6390                            //https://github.com/zed-industries/zed/pull/1871
 6391                            if !has_overlap {
 6392                                buffer.edit([(range, text)], None, cx);
 6393                            }
 6394                        }
 6395
 6396                        let transaction = if buffer.end_transaction(cx).is_some() {
 6397                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6398                            if !push_to_history {
 6399                                buffer.forget_transaction(transaction.id);
 6400                            }
 6401                            Some(transaction)
 6402                        } else {
 6403                            None
 6404                        };
 6405                        Ok(transaction)
 6406                    })?
 6407                } else {
 6408                    Ok(None)
 6409                }
 6410            })
 6411        }
 6412    }
 6413
 6414    pub fn pull_diagnostics(
 6415        &mut self,
 6416        buffer: Entity<Buffer>,
 6417        cx: &mut Context<Self>,
 6418    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6419        let buffer_id = buffer.read(cx).remote_id();
 6420
 6421        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6422            let request = GetDocumentDiagnostics {
 6423                previous_result_id: None,
 6424            };
 6425            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6426                return Task::ready(Ok(None));
 6427            }
 6428            let request_task = client.request_lsp(
 6429                upstream_project_id,
 6430                LSP_REQUEST_TIMEOUT,
 6431                cx.background_executor().clone(),
 6432                request.to_proto(upstream_project_id, buffer.read(cx)),
 6433            );
 6434            cx.background_spawn(async move {
 6435                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6436                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6437                // Do not attempt to further process the dummy responses here.
 6438                let _response = request_task.await?;
 6439                Ok(None)
 6440            })
 6441        } else {
 6442            let server_ids = buffer.update(cx, |buffer, cx| {
 6443                self.language_servers_for_local_buffer(buffer, cx)
 6444                    .map(|(_, server)| server.server_id())
 6445                    .collect::<Vec<_>>()
 6446            });
 6447            let pull_diagnostics = server_ids
 6448                .into_iter()
 6449                .map(|server_id| {
 6450                    let result_id = self.result_id(server_id, buffer_id, cx);
 6451                    self.request_lsp(
 6452                        buffer.clone(),
 6453                        LanguageServerToQuery::Other(server_id),
 6454                        GetDocumentDiagnostics {
 6455                            previous_result_id: result_id,
 6456                        },
 6457                        cx,
 6458                    )
 6459                })
 6460                .collect::<Vec<_>>();
 6461
 6462            cx.background_spawn(async move {
 6463                let mut responses = Vec::new();
 6464                for diagnostics in join_all(pull_diagnostics).await {
 6465                    responses.extend(diagnostics?);
 6466                }
 6467                Ok(Some(responses))
 6468            })
 6469        }
 6470    }
 6471
 6472    pub fn inlay_hints(
 6473        &mut self,
 6474        buffer: Entity<Buffer>,
 6475        range: Range<Anchor>,
 6476        cx: &mut Context<Self>,
 6477    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
 6478        let range_start = range.start;
 6479        let range_end = range.end;
 6480        let buffer_id = buffer.read(cx).remote_id().into();
 6481        let request = InlayHints { range };
 6482
 6483        if let Some((client, project_id)) = self.upstream_client() {
 6484            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6485                return Task::ready(Ok(Vec::new()));
 6486            }
 6487            let proto_request = proto::InlayHints {
 6488                project_id,
 6489                buffer_id,
 6490                start: Some(serialize_anchor(&range_start)),
 6491                end: Some(serialize_anchor(&range_end)),
 6492                version: serialize_version(&buffer.read(cx).version()),
 6493            };
 6494            cx.spawn(async move |project, cx| {
 6495                let response = client
 6496                    .request(proto_request)
 6497                    .await
 6498                    .context("inlay hints proto request")?;
 6499                LspCommand::response_from_proto(
 6500                    request,
 6501                    response,
 6502                    project.upgrade().context("No project")?,
 6503                    buffer.clone(),
 6504                    cx.clone(),
 6505                )
 6506                .await
 6507                .context("inlay hints proto response conversion")
 6508            })
 6509        } else {
 6510            let lsp_request_task = self.request_lsp(
 6511                buffer.clone(),
 6512                LanguageServerToQuery::FirstCapable,
 6513                request,
 6514                cx,
 6515            );
 6516            cx.spawn(async move |_, cx| {
 6517                buffer
 6518                    .update(cx, |buffer, _| {
 6519                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
 6520                    })?
 6521                    .await
 6522                    .context("waiting for inlay hint request range edits")?;
 6523                lsp_request_task.await.context("inlay hints LSP request")
 6524            })
 6525        }
 6526    }
 6527
 6528    pub fn pull_diagnostics_for_buffer(
 6529        &mut self,
 6530        buffer: Entity<Buffer>,
 6531        cx: &mut Context<Self>,
 6532    ) -> Task<anyhow::Result<()>> {
 6533        let diagnostics = self.pull_diagnostics(buffer, cx);
 6534        cx.spawn(async move |lsp_store, cx| {
 6535            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6536                return Ok(());
 6537            };
 6538            lsp_store.update(cx, |lsp_store, cx| {
 6539                if lsp_store.as_local().is_none() {
 6540                    return;
 6541                }
 6542
 6543                let mut unchanged_buffers = HashSet::default();
 6544                let mut changed_buffers = HashSet::default();
 6545                let server_diagnostics_updates = diagnostics
 6546                    .into_iter()
 6547                    .filter_map(|diagnostics_set| match diagnostics_set {
 6548                        LspPullDiagnostics::Response {
 6549                            server_id,
 6550                            uri,
 6551                            diagnostics,
 6552                        } => Some((server_id, uri, diagnostics)),
 6553                        LspPullDiagnostics::Default => None,
 6554                    })
 6555                    .fold(
 6556                        HashMap::default(),
 6557                        |mut acc, (server_id, uri, diagnostics)| {
 6558                            let (result_id, diagnostics) = match diagnostics {
 6559                                PulledDiagnostics::Unchanged { result_id } => {
 6560                                    unchanged_buffers.insert(uri.clone());
 6561                                    (Some(result_id), Vec::new())
 6562                                }
 6563                                PulledDiagnostics::Changed {
 6564                                    result_id,
 6565                                    diagnostics,
 6566                                } => {
 6567                                    changed_buffers.insert(uri.clone());
 6568                                    (result_id, diagnostics)
 6569                                }
 6570                            };
 6571                            let disk_based_sources = Cow::Owned(
 6572                                lsp_store
 6573                                    .language_server_adapter_for_id(server_id)
 6574                                    .as_ref()
 6575                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6576                                    .unwrap_or(&[])
 6577                                    .to_vec(),
 6578                            );
 6579                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6580                                DocumentDiagnosticsUpdate {
 6581                                    server_id,
 6582                                    diagnostics: lsp::PublishDiagnosticsParams {
 6583                                        uri,
 6584                                        diagnostics,
 6585                                        version: None,
 6586                                    },
 6587                                    result_id,
 6588                                    disk_based_sources,
 6589                                },
 6590                            );
 6591                            acc
 6592                        },
 6593                    );
 6594
 6595                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6596                    lsp_store
 6597                        .merge_lsp_diagnostics(
 6598                            DiagnosticSourceKind::Pulled,
 6599                            diagnostic_updates,
 6600                            |buffer, old_diagnostic, cx| {
 6601                                File::from_dyn(buffer.file())
 6602                                    .and_then(|file| {
 6603                                        let abs_path = file.as_local()?.abs_path(cx);
 6604                                        lsp::Uri::from_file_path(abs_path).ok()
 6605                                    })
 6606                                    .is_none_or(|buffer_uri| {
 6607                                        unchanged_buffers.contains(&buffer_uri)
 6608                                            || match old_diagnostic.source_kind {
 6609                                                DiagnosticSourceKind::Pulled => {
 6610                                                    !changed_buffers.contains(&buffer_uri)
 6611                                                }
 6612                                                DiagnosticSourceKind::Other
 6613                                                | DiagnosticSourceKind::Pushed => true,
 6614                                            }
 6615                                    })
 6616                            },
 6617                            cx,
 6618                        )
 6619                        .log_err();
 6620                }
 6621            })
 6622        })
 6623    }
 6624
 6625    pub fn document_colors(
 6626        &mut self,
 6627        fetch_strategy: LspFetchStrategy,
 6628        buffer: Entity<Buffer>,
 6629        cx: &mut Context<Self>,
 6630    ) -> Option<DocumentColorTask> {
 6631        let version_queried_for = buffer.read(cx).version();
 6632        let buffer_id = buffer.read(cx).remote_id();
 6633
 6634        match fetch_strategy {
 6635            LspFetchStrategy::IgnoreCache => {}
 6636            LspFetchStrategy::UseCache {
 6637                known_cache_version,
 6638            } => {
 6639                if let Some(cached_data) = self.lsp_document_colors.get(&buffer_id)
 6640                    && !version_queried_for.changed_since(&cached_data.colors_for_version)
 6641                {
 6642                    let has_different_servers = self.as_local().is_some_and(|local| {
 6643                        local
 6644                            .buffers_opened_in_servers
 6645                            .get(&buffer_id)
 6646                            .cloned()
 6647                            .unwrap_or_default()
 6648                            != cached_data.colors.keys().copied().collect()
 6649                    });
 6650                    if !has_different_servers {
 6651                        if Some(cached_data.cache_version) == known_cache_version {
 6652                            return None;
 6653                        } else {
 6654                            return Some(
 6655                                Task::ready(Ok(DocumentColors {
 6656                                    colors: cached_data
 6657                                        .colors
 6658                                        .values()
 6659                                        .flatten()
 6660                                        .cloned()
 6661                                        .collect(),
 6662                                    cache_version: Some(cached_data.cache_version),
 6663                                }))
 6664                                .shared(),
 6665                            );
 6666                        }
 6667                    }
 6668                }
 6669            }
 6670        }
 6671
 6672        let lsp_data = self.lsp_document_colors.entry(buffer_id).or_default();
 6673        if let Some((updating_for, running_update)) = &lsp_data.colors_update
 6674            && !version_queried_for.changed_since(updating_for)
 6675        {
 6676            return Some(running_update.clone());
 6677        }
 6678        let query_version_queried_for = version_queried_for.clone();
 6679        let new_task = cx
 6680            .spawn(async move |lsp_store, cx| {
 6681                cx.background_executor()
 6682                    .timer(Duration::from_millis(30))
 6683                    .await;
 6684                let fetched_colors = lsp_store
 6685                    .update(cx, |lsp_store, cx| {
 6686                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 6687                    })?
 6688                    .await
 6689                    .context("fetching document colors")
 6690                    .map_err(Arc::new);
 6691                let fetched_colors = match fetched_colors {
 6692                    Ok(fetched_colors) => {
 6693                        if fetch_strategy != LspFetchStrategy::IgnoreCache
 6694                            && Some(true)
 6695                                == buffer
 6696                                    .update(cx, |buffer, _| {
 6697                                        buffer.version() != query_version_queried_for
 6698                                    })
 6699                                    .ok()
 6700                        {
 6701                            return Ok(DocumentColors::default());
 6702                        }
 6703                        fetched_colors
 6704                    }
 6705                    Err(e) => {
 6706                        lsp_store
 6707                            .update(cx, |lsp_store, _| {
 6708                                lsp_store
 6709                                    .lsp_document_colors
 6710                                    .entry(buffer_id)
 6711                                    .or_default()
 6712                                    .colors_update = None;
 6713                            })
 6714                            .ok();
 6715                        return Err(e);
 6716                    }
 6717                };
 6718
 6719                lsp_store
 6720                    .update(cx, |lsp_store, _| {
 6721                        let lsp_data = lsp_store.lsp_document_colors.entry(buffer_id).or_default();
 6722
 6723                        if let Some(fetched_colors) = fetched_colors {
 6724                            if lsp_data.colors_for_version == query_version_queried_for {
 6725                                lsp_data.colors.extend(fetched_colors);
 6726                                lsp_data.cache_version += 1;
 6727                            } else if !lsp_data
 6728                                .colors_for_version
 6729                                .changed_since(&query_version_queried_for)
 6730                            {
 6731                                lsp_data.colors_for_version = query_version_queried_for;
 6732                                lsp_data.colors = fetched_colors;
 6733                                lsp_data.cache_version += 1;
 6734                            }
 6735                        }
 6736                        lsp_data.colors_update = None;
 6737                        let colors = lsp_data
 6738                            .colors
 6739                            .values()
 6740                            .flatten()
 6741                            .cloned()
 6742                            .collect::<HashSet<_>>();
 6743                        DocumentColors {
 6744                            colors,
 6745                            cache_version: Some(lsp_data.cache_version),
 6746                        }
 6747                    })
 6748                    .map_err(Arc::new)
 6749            })
 6750            .shared();
 6751        lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 6752        Some(new_task)
 6753    }
 6754
 6755    fn fetch_document_colors_for_buffer(
 6756        &mut self,
 6757        buffer: &Entity<Buffer>,
 6758        cx: &mut Context<Self>,
 6759    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 6760        if let Some((client, project_id)) = self.upstream_client() {
 6761            let request = GetDocumentColor {};
 6762            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6763                return Task::ready(Ok(None));
 6764            }
 6765
 6766            let request_task = client.request_lsp(
 6767                project_id,
 6768                LSP_REQUEST_TIMEOUT,
 6769                cx.background_executor().clone(),
 6770                request.to_proto(project_id, buffer.read(cx)),
 6771            );
 6772            let buffer = buffer.clone();
 6773            cx.spawn(async move |lsp_store, cx| {
 6774                let Some(project) = lsp_store.upgrade() else {
 6775                    return Ok(None);
 6776                };
 6777                let colors = join_all(
 6778                    request_task
 6779                        .await
 6780                        .log_err()
 6781                        .flatten()
 6782                        .map(|response| response.payload)
 6783                        .unwrap_or_default()
 6784                        .into_iter()
 6785                        .map(|color_response| {
 6786                            let response = request.response_from_proto(
 6787                                color_response.response,
 6788                                project.clone(),
 6789                                buffer.clone(),
 6790                                cx.clone(),
 6791                            );
 6792                            async move {
 6793                                (
 6794                                    LanguageServerId::from_proto(color_response.server_id),
 6795                                    response.await.log_err().unwrap_or_default(),
 6796                                )
 6797                            }
 6798                        }),
 6799                )
 6800                .await
 6801                .into_iter()
 6802                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6803                    acc.entry(server_id)
 6804                        .or_insert_with(HashSet::default)
 6805                        .extend(colors);
 6806                    acc
 6807                });
 6808                Ok(Some(colors))
 6809            })
 6810        } else {
 6811            let document_colors_task =
 6812                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 6813            cx.background_spawn(async move {
 6814                Ok(Some(
 6815                    document_colors_task
 6816                        .await
 6817                        .into_iter()
 6818                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6819                            acc.entry(server_id)
 6820                                .or_insert_with(HashSet::default)
 6821                                .extend(colors);
 6822                            acc
 6823                        })
 6824                        .into_iter()
 6825                        .collect(),
 6826                ))
 6827            })
 6828        }
 6829    }
 6830
 6831    pub fn signature_help<T: ToPointUtf16>(
 6832        &mut self,
 6833        buffer: &Entity<Buffer>,
 6834        position: T,
 6835        cx: &mut Context<Self>,
 6836    ) -> Task<Option<Vec<SignatureHelp>>> {
 6837        let position = position.to_point_utf16(buffer.read(cx));
 6838
 6839        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6840            let request = GetSignatureHelp { position };
 6841            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6842                return Task::ready(None);
 6843            }
 6844            let request_task = client.request_lsp(
 6845                upstream_project_id,
 6846                LSP_REQUEST_TIMEOUT,
 6847                cx.background_executor().clone(),
 6848                request.to_proto(upstream_project_id, buffer.read(cx)),
 6849            );
 6850            let buffer = buffer.clone();
 6851            cx.spawn(async move |weak_project, cx| {
 6852                let project = weak_project.upgrade()?;
 6853                let signatures = join_all(
 6854                    request_task
 6855                        .await
 6856                        .log_err()
 6857                        .flatten()
 6858                        .map(|response| response.payload)
 6859                        .unwrap_or_default()
 6860                        .into_iter()
 6861                        .map(|response| {
 6862                            let response = GetSignatureHelp { position }.response_from_proto(
 6863                                response.response,
 6864                                project.clone(),
 6865                                buffer.clone(),
 6866                                cx.clone(),
 6867                            );
 6868                            async move { response.await.log_err().flatten() }
 6869                        }),
 6870                )
 6871                .await
 6872                .into_iter()
 6873                .flatten()
 6874                .collect();
 6875                Some(signatures)
 6876            })
 6877        } else {
 6878            let all_actions_task = self.request_multiple_lsp_locally(
 6879                buffer,
 6880                Some(position),
 6881                GetSignatureHelp { position },
 6882                cx,
 6883            );
 6884            cx.background_spawn(async move {
 6885                Some(
 6886                    all_actions_task
 6887                        .await
 6888                        .into_iter()
 6889                        .flat_map(|(_, actions)| actions)
 6890                        .collect::<Vec<_>>(),
 6891                )
 6892            })
 6893        }
 6894    }
 6895
 6896    pub fn hover(
 6897        &mut self,
 6898        buffer: &Entity<Buffer>,
 6899        position: PointUtf16,
 6900        cx: &mut Context<Self>,
 6901    ) -> Task<Option<Vec<Hover>>> {
 6902        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6903            let request = GetHover { position };
 6904            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6905                return Task::ready(None);
 6906            }
 6907            let request_task = client.request_lsp(
 6908                upstream_project_id,
 6909                LSP_REQUEST_TIMEOUT,
 6910                cx.background_executor().clone(),
 6911                request.to_proto(upstream_project_id, buffer.read(cx)),
 6912            );
 6913            let buffer = buffer.clone();
 6914            cx.spawn(async move |weak_project, cx| {
 6915                let project = weak_project.upgrade()?;
 6916                let hovers = join_all(
 6917                    request_task
 6918                        .await
 6919                        .log_err()
 6920                        .flatten()
 6921                        .map(|response| response.payload)
 6922                        .unwrap_or_default()
 6923                        .into_iter()
 6924                        .map(|response| {
 6925                            let response = GetHover { position }.response_from_proto(
 6926                                response.response,
 6927                                project.clone(),
 6928                                buffer.clone(),
 6929                                cx.clone(),
 6930                            );
 6931                            async move {
 6932                                response
 6933                                    .await
 6934                                    .log_err()
 6935                                    .flatten()
 6936                                    .and_then(remove_empty_hover_blocks)
 6937                            }
 6938                        }),
 6939                )
 6940                .await
 6941                .into_iter()
 6942                .flatten()
 6943                .collect();
 6944                Some(hovers)
 6945            })
 6946        } else {
 6947            let all_actions_task = self.request_multiple_lsp_locally(
 6948                buffer,
 6949                Some(position),
 6950                GetHover { position },
 6951                cx,
 6952            );
 6953            cx.background_spawn(async move {
 6954                Some(
 6955                    all_actions_task
 6956                        .await
 6957                        .into_iter()
 6958                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 6959                        .collect::<Vec<Hover>>(),
 6960                )
 6961            })
 6962        }
 6963    }
 6964
 6965    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 6966        let language_registry = self.languages.clone();
 6967
 6968        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 6969            let request = upstream_client.request(proto::GetProjectSymbols {
 6970                project_id: *project_id,
 6971                query: query.to_string(),
 6972            });
 6973            cx.foreground_executor().spawn(async move {
 6974                let response = request.await?;
 6975                let mut symbols = Vec::new();
 6976                let core_symbols = response
 6977                    .symbols
 6978                    .into_iter()
 6979                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 6980                    .collect::<Vec<_>>();
 6981                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 6982                    .await;
 6983                Ok(symbols)
 6984            })
 6985        } else if let Some(local) = self.as_local() {
 6986            struct WorkspaceSymbolsResult {
 6987                server_id: LanguageServerId,
 6988                lsp_adapter: Arc<CachedLspAdapter>,
 6989                worktree: WeakEntity<Worktree>,
 6990                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 6991            }
 6992
 6993            let mut requests = Vec::new();
 6994            let mut requested_servers = BTreeSet::new();
 6995            for (seed, state) in local.language_server_ids.iter() {
 6996                let Some(worktree_handle) = self
 6997                    .worktree_store
 6998                    .read(cx)
 6999                    .worktree_for_id(seed.worktree_id, cx)
 7000                else {
 7001                    continue;
 7002                };
 7003                let worktree = worktree_handle.read(cx);
 7004                if !worktree.is_visible() {
 7005                    continue;
 7006                }
 7007
 7008                if !requested_servers.insert(state.id) {
 7009                    continue;
 7010                }
 7011
 7012                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7013                    Some(LanguageServerState::Running {
 7014                        adapter, server, ..
 7015                    }) => (adapter.clone(), server),
 7016
 7017                    _ => continue,
 7018                };
 7019                let supports_workspace_symbol_request =
 7020                    match server.capabilities().workspace_symbol_provider {
 7021                        Some(OneOf::Left(supported)) => supported,
 7022                        Some(OneOf::Right(_)) => true,
 7023                        None => false,
 7024                    };
 7025                if !supports_workspace_symbol_request {
 7026                    continue;
 7027                }
 7028                let worktree_handle = worktree_handle.clone();
 7029                let server_id = server.server_id();
 7030                requests.push(
 7031                        server
 7032                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7033                                lsp::WorkspaceSymbolParams {
 7034                                    query: query.to_string(),
 7035                                    ..Default::default()
 7036                                },
 7037                            )
 7038                            .map(move |response| {
 7039                                let lsp_symbols = response.into_response()
 7040                                    .context("workspace symbols request")
 7041                                    .log_err()
 7042                                    .flatten()
 7043                                    .map(|symbol_response| match symbol_response {
 7044                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7045                                            flat_responses.into_iter().map(|lsp_symbol| {
 7046                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7047                                            }).collect::<Vec<_>>()
 7048                                        }
 7049                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7050                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7051                                                let location = match lsp_symbol.location {
 7052                                                    OneOf::Left(location) => location,
 7053                                                    OneOf::Right(_) => {
 7054                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7055                                                        return None
 7056                                                    }
 7057                                                };
 7058                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7059                                            }).collect::<Vec<_>>()
 7060                                        }
 7061                                    }).unwrap_or_default();
 7062
 7063                                WorkspaceSymbolsResult {
 7064                                    server_id,
 7065                                    lsp_adapter,
 7066                                    worktree: worktree_handle.downgrade(),
 7067                                    lsp_symbols,
 7068                                }
 7069                            }),
 7070                    );
 7071            }
 7072
 7073            cx.spawn(async move |this, cx| {
 7074                let responses = futures::future::join_all(requests).await;
 7075                let this = match this.upgrade() {
 7076                    Some(this) => this,
 7077                    None => return Ok(Vec::new()),
 7078                };
 7079
 7080                let mut symbols = Vec::new();
 7081                for result in responses {
 7082                    let core_symbols = this.update(cx, |this, cx| {
 7083                        result
 7084                            .lsp_symbols
 7085                            .into_iter()
 7086                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7087                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7088                                let source_worktree = result.worktree.upgrade()?;
 7089                                let source_worktree_id = source_worktree.read(cx).id();
 7090
 7091                                let path = if let Some((tree, rel_path)) =
 7092                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7093                                {
 7094                                    let worktree_id = tree.read(cx).id();
 7095                                    SymbolLocation::InProject(ProjectPath {
 7096                                        worktree_id,
 7097                                        path: rel_path,
 7098                                    })
 7099                                } else {
 7100                                    SymbolLocation::OutsideProject {
 7101                                        signature: this.symbol_signature(&abs_path),
 7102                                        abs_path: abs_path.into(),
 7103                                    }
 7104                                };
 7105
 7106                                Some(CoreSymbol {
 7107                                    source_language_server_id: result.server_id,
 7108                                    language_server_name: result.lsp_adapter.name.clone(),
 7109                                    source_worktree_id,
 7110                                    path,
 7111                                    kind: symbol_kind,
 7112                                    name: symbol_name,
 7113                                    range: range_from_lsp(symbol_location.range),
 7114                                })
 7115                            })
 7116                            .collect()
 7117                    })?;
 7118
 7119                    populate_labels_for_symbols(
 7120                        core_symbols,
 7121                        &language_registry,
 7122                        Some(result.lsp_adapter),
 7123                        &mut symbols,
 7124                    )
 7125                    .await;
 7126                }
 7127
 7128                Ok(symbols)
 7129            })
 7130        } else {
 7131            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7132        }
 7133    }
 7134
 7135    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7136        let mut summary = DiagnosticSummary::default();
 7137        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7138            summary.error_count += path_summary.error_count;
 7139            summary.warning_count += path_summary.warning_count;
 7140        }
 7141        summary
 7142    }
 7143
 7144    /// Returns the diagnostic summary for a specific project path.
 7145    pub fn diagnostic_summary_for_path(
 7146        &self,
 7147        project_path: &ProjectPath,
 7148        _: &App,
 7149    ) -> DiagnosticSummary {
 7150        if let Some(summaries) = self
 7151            .diagnostic_summaries
 7152            .get(&project_path.worktree_id)
 7153            .and_then(|map| map.get(&project_path.path))
 7154        {
 7155            let (error_count, warning_count) = summaries.iter().fold(
 7156                (0, 0),
 7157                |(error_count, warning_count), (_language_server_id, summary)| {
 7158                    (
 7159                        error_count + summary.error_count,
 7160                        warning_count + summary.warning_count,
 7161                    )
 7162                },
 7163            );
 7164
 7165            DiagnosticSummary {
 7166                error_count,
 7167                warning_count,
 7168            }
 7169        } else {
 7170            DiagnosticSummary::default()
 7171        }
 7172    }
 7173
 7174    pub fn diagnostic_summaries<'a>(
 7175        &'a self,
 7176        include_ignored: bool,
 7177        cx: &'a App,
 7178    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7179        self.worktree_store
 7180            .read(cx)
 7181            .visible_worktrees(cx)
 7182            .filter_map(|worktree| {
 7183                let worktree = worktree.read(cx);
 7184                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7185            })
 7186            .flat_map(move |(worktree, summaries)| {
 7187                let worktree_id = worktree.id();
 7188                summaries
 7189                    .iter()
 7190                    .filter(move |(path, _)| {
 7191                        include_ignored
 7192                            || worktree
 7193                                .entry_for_path(path.as_ref())
 7194                                .is_some_and(|entry| !entry.is_ignored)
 7195                    })
 7196                    .flat_map(move |(path, summaries)| {
 7197                        summaries.iter().map(move |(server_id, summary)| {
 7198                            (
 7199                                ProjectPath {
 7200                                    worktree_id,
 7201                                    path: path.clone(),
 7202                                },
 7203                                *server_id,
 7204                                *summary,
 7205                            )
 7206                        })
 7207                    })
 7208            })
 7209    }
 7210
 7211    pub fn on_buffer_edited(
 7212        &mut self,
 7213        buffer: Entity<Buffer>,
 7214        cx: &mut Context<Self>,
 7215    ) -> Option<()> {
 7216        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7217            Some(
 7218                self.as_local()?
 7219                    .language_servers_for_buffer(buffer, cx)
 7220                    .map(|i| i.1.clone())
 7221                    .collect(),
 7222            )
 7223        })?;
 7224
 7225        let buffer = buffer.read(cx);
 7226        let file = File::from_dyn(buffer.file())?;
 7227        let abs_path = file.as_local()?.abs_path(cx);
 7228        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7229        let next_snapshot = buffer.text_snapshot();
 7230        for language_server in language_servers {
 7231            let language_server = language_server.clone();
 7232
 7233            let buffer_snapshots = self
 7234                .as_local_mut()
 7235                .unwrap()
 7236                .buffer_snapshots
 7237                .get_mut(&buffer.remote_id())
 7238                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7239            let previous_snapshot = buffer_snapshots.last()?;
 7240
 7241            let build_incremental_change = || {
 7242                buffer
 7243                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7244                        previous_snapshot.snapshot.version(),
 7245                    )
 7246                    .map(|edit| {
 7247                        let edit_start = edit.new.start.0;
 7248                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7249                        let new_text = next_snapshot
 7250                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7251                            .collect();
 7252                        lsp::TextDocumentContentChangeEvent {
 7253                            range: Some(lsp::Range::new(
 7254                                point_to_lsp(edit_start),
 7255                                point_to_lsp(edit_end),
 7256                            )),
 7257                            range_length: None,
 7258                            text: new_text,
 7259                        }
 7260                    })
 7261                    .collect()
 7262            };
 7263
 7264            let document_sync_kind = language_server
 7265                .capabilities()
 7266                .text_document_sync
 7267                .as_ref()
 7268                .and_then(|sync| match sync {
 7269                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7270                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7271                });
 7272
 7273            let content_changes: Vec<_> = match document_sync_kind {
 7274                Some(lsp::TextDocumentSyncKind::FULL) => {
 7275                    vec![lsp::TextDocumentContentChangeEvent {
 7276                        range: None,
 7277                        range_length: None,
 7278                        text: next_snapshot.text(),
 7279                    }]
 7280                }
 7281                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7282                _ => {
 7283                    #[cfg(any(test, feature = "test-support"))]
 7284                    {
 7285                        build_incremental_change()
 7286                    }
 7287
 7288                    #[cfg(not(any(test, feature = "test-support")))]
 7289                    {
 7290                        continue;
 7291                    }
 7292                }
 7293            };
 7294
 7295            let next_version = previous_snapshot.version + 1;
 7296            buffer_snapshots.push(LspBufferSnapshot {
 7297                version: next_version,
 7298                snapshot: next_snapshot.clone(),
 7299            });
 7300
 7301            language_server
 7302                .notify::<lsp::notification::DidChangeTextDocument>(
 7303                    &lsp::DidChangeTextDocumentParams {
 7304                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7305                            uri.clone(),
 7306                            next_version,
 7307                        ),
 7308                        content_changes,
 7309                    },
 7310                )
 7311                .ok();
 7312            self.pull_workspace_diagnostics(language_server.server_id());
 7313        }
 7314
 7315        None
 7316    }
 7317
 7318    pub fn on_buffer_saved(
 7319        &mut self,
 7320        buffer: Entity<Buffer>,
 7321        cx: &mut Context<Self>,
 7322    ) -> Option<()> {
 7323        let file = File::from_dyn(buffer.read(cx).file())?;
 7324        let worktree_id = file.worktree_id(cx);
 7325        let abs_path = file.as_local()?.abs_path(cx);
 7326        let text_document = lsp::TextDocumentIdentifier {
 7327            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7328        };
 7329        let local = self.as_local()?;
 7330
 7331        for server in local.language_servers_for_worktree(worktree_id) {
 7332            if let Some(include_text) = include_text(server.as_ref()) {
 7333                let text = if include_text {
 7334                    Some(buffer.read(cx).text())
 7335                } else {
 7336                    None
 7337                };
 7338                server
 7339                    .notify::<lsp::notification::DidSaveTextDocument>(
 7340                        &lsp::DidSaveTextDocumentParams {
 7341                            text_document: text_document.clone(),
 7342                            text,
 7343                        },
 7344                    )
 7345                    .ok();
 7346            }
 7347        }
 7348
 7349        let language_servers = buffer.update(cx, |buffer, cx| {
 7350            local.language_server_ids_for_buffer(buffer, cx)
 7351        });
 7352        for language_server_id in language_servers {
 7353            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7354        }
 7355
 7356        None
 7357    }
 7358
 7359    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7360        maybe!(async move {
 7361            let mut refreshed_servers = HashSet::default();
 7362            let servers = lsp_store
 7363                .update(cx, |lsp_store, cx| {
 7364                    let local = lsp_store.as_local()?;
 7365
 7366                    let servers = local
 7367                        .language_server_ids
 7368                        .iter()
 7369                        .filter_map(|(seed, state)| {
 7370                            let worktree = lsp_store
 7371                                .worktree_store
 7372                                .read(cx)
 7373                                .worktree_for_id(seed.worktree_id, cx);
 7374                            let delegate: Arc<dyn LspAdapterDelegate> =
 7375                                worktree.map(|worktree| {
 7376                                    LocalLspAdapterDelegate::new(
 7377                                        local.languages.clone(),
 7378                                        &local.environment,
 7379                                        cx.weak_entity(),
 7380                                        &worktree,
 7381                                        local.http_client.clone(),
 7382                                        local.fs.clone(),
 7383                                        cx,
 7384                                    )
 7385                                })?;
 7386                            let server_id = state.id;
 7387
 7388                            let states = local.language_servers.get(&server_id)?;
 7389
 7390                            match states {
 7391                                LanguageServerState::Starting { .. } => None,
 7392                                LanguageServerState::Running {
 7393                                    adapter, server, ..
 7394                                } => {
 7395                                    let adapter = adapter.clone();
 7396                                    let server = server.clone();
 7397                                    refreshed_servers.insert(server.name());
 7398                                    let toolchain = seed.toolchain.clone();
 7399                                    Some(cx.spawn(async move |_, cx| {
 7400                                        let settings =
 7401                                            LocalLspStore::workspace_configuration_for_adapter(
 7402                                                adapter.adapter.clone(),
 7403                                                &delegate,
 7404                                                toolchain,
 7405                                                cx,
 7406                                            )
 7407                                            .await
 7408                                            .ok()?;
 7409                                        server
 7410                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7411                                                &lsp::DidChangeConfigurationParams { settings },
 7412                                            )
 7413                                            .ok()?;
 7414                                        Some(())
 7415                                    }))
 7416                                }
 7417                            }
 7418                        })
 7419                        .collect::<Vec<_>>();
 7420
 7421                    Some(servers)
 7422                })
 7423                .ok()
 7424                .flatten()?;
 7425
 7426            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7427            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7428            // to stop and unregister its language server wrapper.
 7429            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7430            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7431            let _: Vec<Option<()>> = join_all(servers).await;
 7432
 7433            Some(())
 7434        })
 7435        .await;
 7436    }
 7437
 7438    fn maintain_workspace_config(
 7439        external_refresh_requests: watch::Receiver<()>,
 7440        cx: &mut Context<Self>,
 7441    ) -> Task<Result<()>> {
 7442        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7443        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7444
 7445        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7446            *settings_changed_tx.borrow_mut() = ();
 7447        });
 7448
 7449        let mut joint_future =
 7450            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7451        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7452        // - 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).
 7453        // - 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.
 7454        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7455        // - 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,
 7456        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7457        cx.spawn(async move |this, cx| {
 7458            while let Some(()) = joint_future.next().await {
 7459                this.update(cx, |this, cx| {
 7460                    this.refresh_server_tree(cx);
 7461                })
 7462                .ok();
 7463
 7464                Self::refresh_workspace_configurations(&this, cx).await;
 7465            }
 7466
 7467            drop(settings_observation);
 7468            anyhow::Ok(())
 7469        })
 7470    }
 7471
 7472    pub fn language_servers_for_local_buffer<'a>(
 7473        &'a self,
 7474        buffer: &Buffer,
 7475        cx: &mut App,
 7476    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7477        let local = self.as_local();
 7478        let language_server_ids = local
 7479            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7480            .unwrap_or_default();
 7481
 7482        language_server_ids
 7483            .into_iter()
 7484            .filter_map(
 7485                move |server_id| match local?.language_servers.get(&server_id)? {
 7486                    LanguageServerState::Running {
 7487                        adapter, server, ..
 7488                    } => Some((adapter, server)),
 7489                    _ => None,
 7490                },
 7491            )
 7492    }
 7493
 7494    pub fn language_server_for_local_buffer<'a>(
 7495        &'a self,
 7496        buffer: &'a Buffer,
 7497        server_id: LanguageServerId,
 7498        cx: &'a mut App,
 7499    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7500        self.as_local()?
 7501            .language_servers_for_buffer(buffer, cx)
 7502            .find(|(_, s)| s.server_id() == server_id)
 7503    }
 7504
 7505    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7506        self.diagnostic_summaries.remove(&id_to_remove);
 7507        if let Some(local) = self.as_local_mut() {
 7508            let to_remove = local.remove_worktree(id_to_remove, cx);
 7509            for server in to_remove {
 7510                self.language_server_statuses.remove(&server);
 7511            }
 7512        }
 7513    }
 7514
 7515    pub fn shared(
 7516        &mut self,
 7517        project_id: u64,
 7518        downstream_client: AnyProtoClient,
 7519        _: &mut Context<Self>,
 7520    ) {
 7521        self.downstream_client = Some((downstream_client.clone(), project_id));
 7522
 7523        for (server_id, status) in &self.language_server_statuses {
 7524            if let Some(server) = self.language_server_for_id(*server_id) {
 7525                downstream_client
 7526                    .send(proto::StartLanguageServer {
 7527                        project_id,
 7528                        server: Some(proto::LanguageServer {
 7529                            id: server_id.to_proto(),
 7530                            name: status.name.to_string(),
 7531                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7532                        }),
 7533                        capabilities: serde_json::to_string(&server.capabilities())
 7534                            .expect("serializing server LSP capabilities"),
 7535                    })
 7536                    .log_err();
 7537            }
 7538        }
 7539    }
 7540
 7541    pub fn disconnected_from_host(&mut self) {
 7542        self.downstream_client.take();
 7543    }
 7544
 7545    pub fn disconnected_from_ssh_remote(&mut self) {
 7546        if let LspStoreMode::Remote(RemoteLspStore {
 7547            upstream_client, ..
 7548        }) = &mut self.mode
 7549        {
 7550            upstream_client.take();
 7551        }
 7552    }
 7553
 7554    pub(crate) fn set_language_server_statuses_from_proto(
 7555        &mut self,
 7556        project: WeakEntity<Project>,
 7557        language_servers: Vec<proto::LanguageServer>,
 7558        server_capabilities: Vec<String>,
 7559        cx: &mut Context<Self>,
 7560    ) {
 7561        let lsp_logs = cx
 7562            .try_global::<GlobalLogStore>()
 7563            .map(|lsp_store| lsp_store.0.clone());
 7564
 7565        self.language_server_statuses = language_servers
 7566            .into_iter()
 7567            .zip(server_capabilities)
 7568            .map(|(server, server_capabilities)| {
 7569                let server_id = LanguageServerId(server.id as usize);
 7570                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7571                    self.lsp_server_capabilities
 7572                        .insert(server_id, server_capabilities);
 7573                }
 7574
 7575                let name = LanguageServerName::from_proto(server.name);
 7576                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7577
 7578                if let Some(lsp_logs) = &lsp_logs {
 7579                    lsp_logs.update(cx, |lsp_logs, cx| {
 7580                        lsp_logs.add_language_server(
 7581                            // Only remote clients get their language servers set from proto
 7582                            LanguageServerKind::Remote {
 7583                                project: project.clone(),
 7584                            },
 7585                            server_id,
 7586                            Some(name.clone()),
 7587                            worktree,
 7588                            None,
 7589                            cx,
 7590                        );
 7591                    });
 7592                }
 7593
 7594                (
 7595                    server_id,
 7596                    LanguageServerStatus {
 7597                        name,
 7598                        pending_work: Default::default(),
 7599                        has_pending_diagnostic_updates: false,
 7600                        progress_tokens: Default::default(),
 7601                        worktree,
 7602                    },
 7603                )
 7604            })
 7605            .collect();
 7606    }
 7607
 7608    #[cfg(test)]
 7609    pub fn update_diagnostic_entries(
 7610        &mut self,
 7611        server_id: LanguageServerId,
 7612        abs_path: PathBuf,
 7613        result_id: Option<String>,
 7614        version: Option<i32>,
 7615        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7616        cx: &mut Context<Self>,
 7617    ) -> anyhow::Result<()> {
 7618        self.merge_diagnostic_entries(
 7619            vec![DocumentDiagnosticsUpdate {
 7620                diagnostics: DocumentDiagnostics {
 7621                    diagnostics,
 7622                    document_abs_path: abs_path,
 7623                    version,
 7624                },
 7625                result_id,
 7626                server_id,
 7627                disk_based_sources: Cow::Borrowed(&[]),
 7628            }],
 7629            |_, _, _| false,
 7630            cx,
 7631        )?;
 7632        Ok(())
 7633    }
 7634
 7635    pub fn merge_diagnostic_entries<'a>(
 7636        &mut self,
 7637        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7638        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7639        cx: &mut Context<Self>,
 7640    ) -> anyhow::Result<()> {
 7641        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7642        let mut updated_diagnostics_paths = HashMap::default();
 7643        for mut update in diagnostic_updates {
 7644            let abs_path = &update.diagnostics.document_abs_path;
 7645            let server_id = update.server_id;
 7646            let Some((worktree, relative_path)) =
 7647                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7648            else {
 7649                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7650                return Ok(());
 7651            };
 7652
 7653            let worktree_id = worktree.read(cx).id();
 7654            let project_path = ProjectPath {
 7655                worktree_id,
 7656                path: relative_path,
 7657            };
 7658
 7659            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7660                let snapshot = buffer_handle.read(cx).snapshot();
 7661                let buffer = buffer_handle.read(cx);
 7662                let reused_diagnostics = buffer
 7663                    .buffer_diagnostics(Some(server_id))
 7664                    .iter()
 7665                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 7666                    .map(|v| {
 7667                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 7668                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 7669                        DiagnosticEntry {
 7670                            range: start..end,
 7671                            diagnostic: v.diagnostic.clone(),
 7672                        }
 7673                    })
 7674                    .collect::<Vec<_>>();
 7675
 7676                self.as_local_mut()
 7677                    .context("cannot merge diagnostics on a remote LspStore")?
 7678                    .update_buffer_diagnostics(
 7679                        &buffer_handle,
 7680                        server_id,
 7681                        update.result_id,
 7682                        update.diagnostics.version,
 7683                        update.diagnostics.diagnostics.clone(),
 7684                        reused_diagnostics.clone(),
 7685                        cx,
 7686                    )?;
 7687
 7688                update.diagnostics.diagnostics.extend(reused_diagnostics);
 7689            }
 7690
 7691            let updated = worktree.update(cx, |worktree, cx| {
 7692                self.update_worktree_diagnostics(
 7693                    worktree.id(),
 7694                    server_id,
 7695                    project_path.path.clone(),
 7696                    update.diagnostics.diagnostics,
 7697                    cx,
 7698                )
 7699            })?;
 7700            match updated {
 7701                ControlFlow::Continue(new_summary) => {
 7702                    if let Some((project_id, new_summary)) = new_summary {
 7703                        match &mut diagnostics_summary {
 7704                            Some(diagnostics_summary) => {
 7705                                diagnostics_summary
 7706                                    .more_summaries
 7707                                    .push(proto::DiagnosticSummary {
 7708                                        path: project_path.path.as_ref().to_proto(),
 7709                                        language_server_id: server_id.0 as u64,
 7710                                        error_count: new_summary.error_count,
 7711                                        warning_count: new_summary.warning_count,
 7712                                    })
 7713                            }
 7714                            None => {
 7715                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 7716                                    project_id,
 7717                                    worktree_id: worktree_id.to_proto(),
 7718                                    summary: Some(proto::DiagnosticSummary {
 7719                                        path: project_path.path.as_ref().to_proto(),
 7720                                        language_server_id: server_id.0 as u64,
 7721                                        error_count: new_summary.error_count,
 7722                                        warning_count: new_summary.warning_count,
 7723                                    }),
 7724                                    more_summaries: Vec::new(),
 7725                                })
 7726                            }
 7727                        }
 7728                    }
 7729                    updated_diagnostics_paths
 7730                        .entry(server_id)
 7731                        .or_insert_with(Vec::new)
 7732                        .push(project_path);
 7733                }
 7734                ControlFlow::Break(()) => {}
 7735            }
 7736        }
 7737
 7738        if let Some((diagnostics_summary, (downstream_client, _))) =
 7739            diagnostics_summary.zip(self.downstream_client.as_ref())
 7740        {
 7741            downstream_client.send(diagnostics_summary).log_err();
 7742        }
 7743        for (server_id, paths) in updated_diagnostics_paths {
 7744            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 7745        }
 7746        Ok(())
 7747    }
 7748
 7749    fn update_worktree_diagnostics(
 7750        &mut self,
 7751        worktree_id: WorktreeId,
 7752        server_id: LanguageServerId,
 7753        path_in_worktree: Arc<RelPath>,
 7754        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7755        _: &mut Context<Worktree>,
 7756    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 7757        let local = match &mut self.mode {
 7758            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 7759            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 7760        };
 7761
 7762        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 7763        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 7764        let summaries_by_server_id = summaries_for_tree
 7765            .entry(path_in_worktree.clone())
 7766            .or_default();
 7767
 7768        let old_summary = summaries_by_server_id
 7769            .remove(&server_id)
 7770            .unwrap_or_default();
 7771
 7772        let new_summary = DiagnosticSummary::new(&diagnostics);
 7773        if new_summary.is_empty() {
 7774            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 7775            {
 7776                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7777                    diagnostics_by_server_id.remove(ix);
 7778                }
 7779                if diagnostics_by_server_id.is_empty() {
 7780                    diagnostics_for_tree.remove(&path_in_worktree);
 7781                }
 7782            }
 7783        } else {
 7784            summaries_by_server_id.insert(server_id, new_summary);
 7785            let diagnostics_by_server_id = diagnostics_for_tree
 7786                .entry(path_in_worktree.clone())
 7787                .or_default();
 7788            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7789                Ok(ix) => {
 7790                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 7791                }
 7792                Err(ix) => {
 7793                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 7794                }
 7795            }
 7796        }
 7797
 7798        if !old_summary.is_empty() || !new_summary.is_empty() {
 7799            if let Some((_, project_id)) = &self.downstream_client {
 7800                Ok(ControlFlow::Continue(Some((
 7801                    *project_id,
 7802                    proto::DiagnosticSummary {
 7803                        path: path_in_worktree.to_proto(),
 7804                        language_server_id: server_id.0 as u64,
 7805                        error_count: new_summary.error_count as u32,
 7806                        warning_count: new_summary.warning_count as u32,
 7807                    },
 7808                ))))
 7809            } else {
 7810                Ok(ControlFlow::Continue(None))
 7811            }
 7812        } else {
 7813            Ok(ControlFlow::Break(()))
 7814        }
 7815    }
 7816
 7817    pub fn open_buffer_for_symbol(
 7818        &mut self,
 7819        symbol: &Symbol,
 7820        cx: &mut Context<Self>,
 7821    ) -> Task<Result<Entity<Buffer>>> {
 7822        if let Some((client, project_id)) = self.upstream_client() {
 7823            let request = client.request(proto::OpenBufferForSymbol {
 7824                project_id,
 7825                symbol: Some(Self::serialize_symbol(symbol)),
 7826            });
 7827            cx.spawn(async move |this, cx| {
 7828                let response = request.await?;
 7829                let buffer_id = BufferId::new(response.buffer_id)?;
 7830                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 7831                    .await
 7832            })
 7833        } else if let Some(local) = self.as_local() {
 7834            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 7835                seed.worktree_id == symbol.source_worktree_id
 7836                    && state.id == symbol.source_language_server_id
 7837                    && symbol.language_server_name == seed.name
 7838            });
 7839            if !is_valid {
 7840                return Task::ready(Err(anyhow!(
 7841                    "language server for worktree and language not found"
 7842                )));
 7843            };
 7844
 7845            let symbol_abs_path = match &symbol.path {
 7846                SymbolLocation::InProject(project_path) => self
 7847                    .worktree_store
 7848                    .read(cx)
 7849                    .absolutize(&project_path, cx)
 7850                    .context("no such worktree"),
 7851                SymbolLocation::OutsideProject {
 7852                    abs_path,
 7853                    signature: _,
 7854                } => Ok(abs_path.to_path_buf()),
 7855            };
 7856            let symbol_abs_path = match symbol_abs_path {
 7857                Ok(abs_path) => abs_path,
 7858                Err(err) => return Task::ready(Err(err)),
 7859            };
 7860            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 7861                uri
 7862            } else {
 7863                return Task::ready(Err(anyhow!("invalid symbol path")));
 7864            };
 7865
 7866            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 7867        } else {
 7868            Task::ready(Err(anyhow!("no upstream client or local store")))
 7869        }
 7870    }
 7871
 7872    pub(crate) fn open_local_buffer_via_lsp(
 7873        &mut self,
 7874        abs_path: lsp::Uri,
 7875        language_server_id: LanguageServerId,
 7876        cx: &mut Context<Self>,
 7877    ) -> Task<Result<Entity<Buffer>>> {
 7878        cx.spawn(async move |lsp_store, cx| {
 7879            // Escape percent-encoded string.
 7880            let current_scheme = abs_path.scheme().to_owned();
 7881            // Uri is immutable, so we can't modify the scheme
 7882
 7883            let abs_path = abs_path
 7884                .to_file_path()
 7885                .map_err(|()| anyhow!("can't convert URI to path"))?;
 7886            let p = abs_path.clone();
 7887            let yarn_worktree = lsp_store
 7888                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 7889                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 7890                        cx.spawn(async move |this, cx| {
 7891                            let t = this
 7892                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 7893                                .ok()?;
 7894                            t.await
 7895                        })
 7896                    }),
 7897                    None => Task::ready(None),
 7898                })?
 7899                .await;
 7900            let (worktree_root_target, known_relative_path) =
 7901                if let Some((zip_root, relative_path)) = yarn_worktree {
 7902                    (zip_root, Some(relative_path))
 7903                } else {
 7904                    (Arc::<Path>::from(abs_path.as_path()), None)
 7905                };
 7906            let (worktree, relative_path) = if let Some(result) =
 7907                lsp_store.update(cx, |lsp_store, cx| {
 7908                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7909                        worktree_store.find_worktree(&worktree_root_target, cx)
 7910                    })
 7911                })? {
 7912                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 7913                (result.0, relative_path)
 7914            } else {
 7915                let worktree = lsp_store
 7916                    .update(cx, |lsp_store, cx| {
 7917                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7918                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 7919                        })
 7920                    })?
 7921                    .await?;
 7922                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 7923                    lsp_store
 7924                        .update(cx, |lsp_store, cx| {
 7925                            if let Some(local) = lsp_store.as_local_mut() {
 7926                                local.register_language_server_for_invisible_worktree(
 7927                                    &worktree,
 7928                                    language_server_id,
 7929                                    cx,
 7930                                )
 7931                            }
 7932                        })
 7933                        .ok();
 7934                }
 7935                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 7936                let relative_path = if let Some(known_path) = known_relative_path {
 7937                    known_path
 7938                } else {
 7939                    RelPath::from_std_path(
 7940                        abs_path.strip_prefix(worktree_root)?,
 7941                        PathStyle::local(),
 7942                    )
 7943                    .context("failed to create relative path")?
 7944                };
 7945                (worktree, relative_path)
 7946            };
 7947            let project_path = ProjectPath {
 7948                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 7949                path: relative_path,
 7950            };
 7951            lsp_store
 7952                .update(cx, |lsp_store, cx| {
 7953                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 7954                        buffer_store.open_buffer(project_path, cx)
 7955                    })
 7956                })?
 7957                .await
 7958        })
 7959    }
 7960
 7961    fn request_multiple_lsp_locally<P, R>(
 7962        &mut self,
 7963        buffer: &Entity<Buffer>,
 7964        position: Option<P>,
 7965        request: R,
 7966        cx: &mut Context<Self>,
 7967    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 7968    where
 7969        P: ToOffset,
 7970        R: LspCommand + Clone,
 7971        <R::LspRequest as lsp::request::Request>::Result: Send,
 7972        <R::LspRequest as lsp::request::Request>::Params: Send,
 7973    {
 7974        let Some(local) = self.as_local() else {
 7975            return Task::ready(Vec::new());
 7976        };
 7977
 7978        let snapshot = buffer.read(cx).snapshot();
 7979        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 7980
 7981        let server_ids = buffer.update(cx, |buffer, cx| {
 7982            local
 7983                .language_servers_for_buffer(buffer, cx)
 7984                .filter(|(adapter, _)| {
 7985                    scope
 7986                        .as_ref()
 7987                        .map(|scope| scope.language_allowed(&adapter.name))
 7988                        .unwrap_or(true)
 7989                })
 7990                .map(|(_, server)| server.server_id())
 7991                .filter(|server_id| {
 7992                    self.as_local().is_none_or(|local| {
 7993                        local
 7994                            .buffers_opened_in_servers
 7995                            .get(&snapshot.remote_id())
 7996                            .is_some_and(|servers| servers.contains(server_id))
 7997                    })
 7998                })
 7999                .collect::<Vec<_>>()
 8000        });
 8001
 8002        let mut response_results = server_ids
 8003            .into_iter()
 8004            .map(|server_id| {
 8005                let task = self.request_lsp(
 8006                    buffer.clone(),
 8007                    LanguageServerToQuery::Other(server_id),
 8008                    request.clone(),
 8009                    cx,
 8010                );
 8011                async move { (server_id, task.await) }
 8012            })
 8013            .collect::<FuturesUnordered<_>>();
 8014
 8015        cx.background_spawn(async move {
 8016            let mut responses = Vec::with_capacity(response_results.len());
 8017            while let Some((server_id, response_result)) = response_results.next().await {
 8018                if let Some(response) = response_result.log_err() {
 8019                    responses.push((server_id, response));
 8020                }
 8021            }
 8022            responses
 8023        })
 8024    }
 8025
 8026    async fn handle_lsp_command<T: LspCommand>(
 8027        this: Entity<Self>,
 8028        envelope: TypedEnvelope<T::ProtoRequest>,
 8029        mut cx: AsyncApp,
 8030    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8031    where
 8032        <T::LspRequest as lsp::request::Request>::Params: Send,
 8033        <T::LspRequest as lsp::request::Request>::Result: Send,
 8034    {
 8035        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8036        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8037        let buffer_handle = this.update(&mut cx, |this, cx| {
 8038            this.buffer_store.read(cx).get_existing(buffer_id)
 8039        })??;
 8040        let request = T::from_proto(
 8041            envelope.payload,
 8042            this.clone(),
 8043            buffer_handle.clone(),
 8044            cx.clone(),
 8045        )
 8046        .await?;
 8047        let response = this
 8048            .update(&mut cx, |this, cx| {
 8049                this.request_lsp(
 8050                    buffer_handle.clone(),
 8051                    LanguageServerToQuery::FirstCapable,
 8052                    request,
 8053                    cx,
 8054                )
 8055            })?
 8056            .await?;
 8057        this.update(&mut cx, |this, cx| {
 8058            Ok(T::response_to_proto(
 8059                response,
 8060                this,
 8061                sender_id,
 8062                &buffer_handle.read(cx).version(),
 8063                cx,
 8064            ))
 8065        })?
 8066    }
 8067
 8068    async fn handle_lsp_query(
 8069        lsp_store: Entity<Self>,
 8070        envelope: TypedEnvelope<proto::LspQuery>,
 8071        mut cx: AsyncApp,
 8072    ) -> Result<proto::Ack> {
 8073        use proto::lsp_query::Request;
 8074        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8075        let lsp_query = envelope.payload;
 8076        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8077        match lsp_query.request.context("invalid LSP query request")? {
 8078            Request::GetReferences(get_references) => {
 8079                let position = get_references.position.clone().and_then(deserialize_anchor);
 8080                Self::query_lsp_locally::<GetReferences>(
 8081                    lsp_store,
 8082                    sender_id,
 8083                    lsp_request_id,
 8084                    get_references,
 8085                    position,
 8086                    cx.clone(),
 8087                )
 8088                .await?;
 8089            }
 8090            Request::GetDocumentColor(get_document_color) => {
 8091                Self::query_lsp_locally::<GetDocumentColor>(
 8092                    lsp_store,
 8093                    sender_id,
 8094                    lsp_request_id,
 8095                    get_document_color,
 8096                    None,
 8097                    cx.clone(),
 8098                )
 8099                .await?;
 8100            }
 8101            Request::GetHover(get_hover) => {
 8102                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8103                Self::query_lsp_locally::<GetHover>(
 8104                    lsp_store,
 8105                    sender_id,
 8106                    lsp_request_id,
 8107                    get_hover,
 8108                    position,
 8109                    cx.clone(),
 8110                )
 8111                .await?;
 8112            }
 8113            Request::GetCodeActions(get_code_actions) => {
 8114                Self::query_lsp_locally::<GetCodeActions>(
 8115                    lsp_store,
 8116                    sender_id,
 8117                    lsp_request_id,
 8118                    get_code_actions,
 8119                    None,
 8120                    cx.clone(),
 8121                )
 8122                .await?;
 8123            }
 8124            Request::GetSignatureHelp(get_signature_help) => {
 8125                let position = get_signature_help
 8126                    .position
 8127                    .clone()
 8128                    .and_then(deserialize_anchor);
 8129                Self::query_lsp_locally::<GetSignatureHelp>(
 8130                    lsp_store,
 8131                    sender_id,
 8132                    lsp_request_id,
 8133                    get_signature_help,
 8134                    position,
 8135                    cx.clone(),
 8136                )
 8137                .await?;
 8138            }
 8139            Request::GetCodeLens(get_code_lens) => {
 8140                Self::query_lsp_locally::<GetCodeLens>(
 8141                    lsp_store,
 8142                    sender_id,
 8143                    lsp_request_id,
 8144                    get_code_lens,
 8145                    None,
 8146                    cx.clone(),
 8147                )
 8148                .await?;
 8149            }
 8150            Request::GetDefinition(get_definition) => {
 8151                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8152                Self::query_lsp_locally::<GetDefinitions>(
 8153                    lsp_store,
 8154                    sender_id,
 8155                    lsp_request_id,
 8156                    get_definition,
 8157                    position,
 8158                    cx.clone(),
 8159                )
 8160                .await?;
 8161            }
 8162            Request::GetDeclaration(get_declaration) => {
 8163                let position = get_declaration
 8164                    .position
 8165                    .clone()
 8166                    .and_then(deserialize_anchor);
 8167                Self::query_lsp_locally::<GetDeclarations>(
 8168                    lsp_store,
 8169                    sender_id,
 8170                    lsp_request_id,
 8171                    get_declaration,
 8172                    position,
 8173                    cx.clone(),
 8174                )
 8175                .await?;
 8176            }
 8177            Request::GetTypeDefinition(get_type_definition) => {
 8178                let position = get_type_definition
 8179                    .position
 8180                    .clone()
 8181                    .and_then(deserialize_anchor);
 8182                Self::query_lsp_locally::<GetTypeDefinitions>(
 8183                    lsp_store,
 8184                    sender_id,
 8185                    lsp_request_id,
 8186                    get_type_definition,
 8187                    position,
 8188                    cx.clone(),
 8189                )
 8190                .await?;
 8191            }
 8192            Request::GetImplementation(get_implementation) => {
 8193                let position = get_implementation
 8194                    .position
 8195                    .clone()
 8196                    .and_then(deserialize_anchor);
 8197                Self::query_lsp_locally::<GetImplementations>(
 8198                    lsp_store,
 8199                    sender_id,
 8200                    lsp_request_id,
 8201                    get_implementation,
 8202                    position,
 8203                    cx.clone(),
 8204                )
 8205                .await?;
 8206            }
 8207            // Diagnostics pull synchronizes internally via the buffer state, and cannot be handled generically as the other requests.
 8208            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8209                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8210                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8211                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8212                    this.buffer_store.read(cx).get_existing(buffer_id)
 8213                })??;
 8214                buffer
 8215                    .update(&mut cx, |buffer, _| {
 8216                        buffer.wait_for_version(version.clone())
 8217                    })?
 8218                    .await?;
 8219                lsp_store.update(&mut cx, |lsp_store, cx| {
 8220                    let existing_queries = lsp_store
 8221                        .running_lsp_requests
 8222                        .entry(TypeId::of::<GetDocumentDiagnostics>())
 8223                        .or_default();
 8224                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8225                    ) || buffer.read(cx).version.changed_since(&existing_queries.0)
 8226                    {
 8227                        existing_queries.1.clear();
 8228                    }
 8229                    existing_queries.1.insert(
 8230                        lsp_request_id,
 8231                        cx.spawn(async move |lsp_store, cx| {
 8232                            let diagnostics_pull = lsp_store
 8233                                .update(cx, |lsp_store, cx| {
 8234                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8235                                })
 8236                                .ok();
 8237                            if let Some(diagnostics_pull) = diagnostics_pull {
 8238                                match diagnostics_pull.await {
 8239                                    Ok(()) => {}
 8240                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8241                                };
 8242                            }
 8243                        }),
 8244                    );
 8245                })?;
 8246            }
 8247        }
 8248        Ok(proto::Ack {})
 8249    }
 8250
 8251    async fn handle_lsp_query_response(
 8252        lsp_store: Entity<Self>,
 8253        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8254        cx: AsyncApp,
 8255    ) -> Result<()> {
 8256        lsp_store.read_with(&cx, |lsp_store, _| {
 8257            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8258                upstream_client.handle_lsp_response(envelope.clone());
 8259            }
 8260        })?;
 8261        Ok(())
 8262    }
 8263
 8264    async fn handle_apply_code_action(
 8265        this: Entity<Self>,
 8266        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8267        mut cx: AsyncApp,
 8268    ) -> Result<proto::ApplyCodeActionResponse> {
 8269        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8270        let action =
 8271            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8272        let apply_code_action = this.update(&mut cx, |this, cx| {
 8273            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8274            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8275            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8276        })??;
 8277
 8278        let project_transaction = apply_code_action.await?;
 8279        let project_transaction = this.update(&mut cx, |this, cx| {
 8280            this.buffer_store.update(cx, |buffer_store, cx| {
 8281                buffer_store.serialize_project_transaction_for_peer(
 8282                    project_transaction,
 8283                    sender_id,
 8284                    cx,
 8285                )
 8286            })
 8287        })?;
 8288        Ok(proto::ApplyCodeActionResponse {
 8289            transaction: Some(project_transaction),
 8290        })
 8291    }
 8292
 8293    async fn handle_register_buffer_with_language_servers(
 8294        this: Entity<Self>,
 8295        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8296        mut cx: AsyncApp,
 8297    ) -> Result<proto::Ack> {
 8298        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8299        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8300        this.update(&mut cx, |this, cx| {
 8301            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8302                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8303                    project_id: upstream_project_id,
 8304                    buffer_id: buffer_id.to_proto(),
 8305                    only_servers: envelope.payload.only_servers,
 8306                });
 8307            }
 8308
 8309            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8310                anyhow::bail!("buffer is not open");
 8311            };
 8312
 8313            let handle = this.register_buffer_with_language_servers(
 8314                &buffer,
 8315                envelope
 8316                    .payload
 8317                    .only_servers
 8318                    .into_iter()
 8319                    .filter_map(|selector| {
 8320                        Some(match selector.selector? {
 8321                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8322                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8323                            }
 8324                            proto::language_server_selector::Selector::Name(name) => {
 8325                                LanguageServerSelector::Name(LanguageServerName(
 8326                                    SharedString::from(name),
 8327                                ))
 8328                            }
 8329                        })
 8330                    })
 8331                    .collect(),
 8332                false,
 8333                cx,
 8334            );
 8335            this.buffer_store().update(cx, |buffer_store, _| {
 8336                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8337            });
 8338
 8339            Ok(())
 8340        })??;
 8341        Ok(proto::Ack {})
 8342    }
 8343
 8344    async fn handle_rename_project_entry(
 8345        this: Entity<Self>,
 8346        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8347        mut cx: AsyncApp,
 8348    ) -> Result<proto::ProjectEntryResponse> {
 8349        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8350        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8351        let new_path =
 8352            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8353
 8354        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8355            .update(&mut cx, |this, cx| {
 8356                let (worktree, entry) = this
 8357                    .worktree_store
 8358                    .read(cx)
 8359                    .worktree_and_entry_for_id(entry_id, cx)?;
 8360                let new_worktree = this
 8361                    .worktree_store
 8362                    .read(cx)
 8363                    .worktree_for_id(new_worktree_id, cx)?;
 8364                Some((
 8365                    this.worktree_store.clone(),
 8366                    worktree,
 8367                    new_worktree,
 8368                    entry.clone(),
 8369                ))
 8370            })?
 8371            .context("worktree not found")?;
 8372        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8373            (worktree.absolutize(&old_entry.path), worktree.id())
 8374        })?;
 8375        let new_abs_path =
 8376            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8377
 8378        let _transaction = Self::will_rename_entry(
 8379            this.downgrade(),
 8380            old_worktree_id,
 8381            &old_abs_path,
 8382            &new_abs_path,
 8383            old_entry.is_dir(),
 8384            cx.clone(),
 8385        )
 8386        .await;
 8387        let response = WorktreeStore::handle_rename_project_entry(
 8388            worktree_store,
 8389            envelope.payload,
 8390            cx.clone(),
 8391        )
 8392        .await;
 8393        this.read_with(&cx, |this, _| {
 8394            this.did_rename_entry(
 8395                old_worktree_id,
 8396                &old_abs_path,
 8397                &new_abs_path,
 8398                old_entry.is_dir(),
 8399            );
 8400        })
 8401        .ok();
 8402        response
 8403    }
 8404
 8405    async fn handle_update_diagnostic_summary(
 8406        this: Entity<Self>,
 8407        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8408        mut cx: AsyncApp,
 8409    ) -> Result<()> {
 8410        this.update(&mut cx, |lsp_store, cx| {
 8411            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8412            let mut updated_diagnostics_paths = HashMap::default();
 8413            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8414            for message_summary in envelope
 8415                .payload
 8416                .summary
 8417                .into_iter()
 8418                .chain(envelope.payload.more_summaries)
 8419            {
 8420                let project_path = ProjectPath {
 8421                    worktree_id,
 8422                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8423                };
 8424                let path = project_path.path.clone();
 8425                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8426                let summary = DiagnosticSummary {
 8427                    error_count: message_summary.error_count as usize,
 8428                    warning_count: message_summary.warning_count as usize,
 8429                };
 8430
 8431                if summary.is_empty() {
 8432                    if let Some(worktree_summaries) =
 8433                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8434                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8435                    {
 8436                        summaries.remove(&server_id);
 8437                        if summaries.is_empty() {
 8438                            worktree_summaries.remove(&path);
 8439                        }
 8440                    }
 8441                } else {
 8442                    lsp_store
 8443                        .diagnostic_summaries
 8444                        .entry(worktree_id)
 8445                        .or_default()
 8446                        .entry(path)
 8447                        .or_default()
 8448                        .insert(server_id, summary);
 8449                }
 8450
 8451                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8452                    match &mut diagnostics_summary {
 8453                        Some(diagnostics_summary) => {
 8454                            diagnostics_summary
 8455                                .more_summaries
 8456                                .push(proto::DiagnosticSummary {
 8457                                    path: project_path.path.as_ref().to_proto(),
 8458                                    language_server_id: server_id.0 as u64,
 8459                                    error_count: summary.error_count as u32,
 8460                                    warning_count: summary.warning_count as u32,
 8461                                })
 8462                        }
 8463                        None => {
 8464                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8465                                project_id: *project_id,
 8466                                worktree_id: worktree_id.to_proto(),
 8467                                summary: Some(proto::DiagnosticSummary {
 8468                                    path: project_path.path.as_ref().to_proto(),
 8469                                    language_server_id: server_id.0 as u64,
 8470                                    error_count: summary.error_count as u32,
 8471                                    warning_count: summary.warning_count as u32,
 8472                                }),
 8473                                more_summaries: Vec::new(),
 8474                            })
 8475                        }
 8476                    }
 8477                }
 8478                updated_diagnostics_paths
 8479                    .entry(server_id)
 8480                    .or_insert_with(Vec::new)
 8481                    .push(project_path);
 8482            }
 8483
 8484            if let Some((diagnostics_summary, (downstream_client, _))) =
 8485                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8486            {
 8487                downstream_client.send(diagnostics_summary).log_err();
 8488            }
 8489            for (server_id, paths) in updated_diagnostics_paths {
 8490                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8491            }
 8492            Ok(())
 8493        })?
 8494    }
 8495
 8496    async fn handle_start_language_server(
 8497        lsp_store: Entity<Self>,
 8498        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8499        mut cx: AsyncApp,
 8500    ) -> Result<()> {
 8501        let server = envelope.payload.server.context("invalid server")?;
 8502        let server_capabilities =
 8503            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8504                .with_context(|| {
 8505                    format!(
 8506                        "incorrect server capabilities {}",
 8507                        envelope.payload.capabilities
 8508                    )
 8509                })?;
 8510        lsp_store.update(&mut cx, |lsp_store, cx| {
 8511            let server_id = LanguageServerId(server.id as usize);
 8512            let server_name = LanguageServerName::from_proto(server.name.clone());
 8513            lsp_store
 8514                .lsp_server_capabilities
 8515                .insert(server_id, server_capabilities);
 8516            lsp_store.language_server_statuses.insert(
 8517                server_id,
 8518                LanguageServerStatus {
 8519                    name: server_name.clone(),
 8520                    pending_work: Default::default(),
 8521                    has_pending_diagnostic_updates: false,
 8522                    progress_tokens: Default::default(),
 8523                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8524                },
 8525            );
 8526            cx.emit(LspStoreEvent::LanguageServerAdded(
 8527                server_id,
 8528                server_name,
 8529                server.worktree_id.map(WorktreeId::from_proto),
 8530            ));
 8531            cx.notify();
 8532        })?;
 8533        Ok(())
 8534    }
 8535
 8536    async fn handle_update_language_server(
 8537        lsp_store: Entity<Self>,
 8538        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8539        mut cx: AsyncApp,
 8540    ) -> Result<()> {
 8541        lsp_store.update(&mut cx, |lsp_store, cx| {
 8542            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8543
 8544            match envelope.payload.variant.context("invalid variant")? {
 8545                proto::update_language_server::Variant::WorkStart(payload) => {
 8546                    lsp_store.on_lsp_work_start(
 8547                        language_server_id,
 8548                        payload.token,
 8549                        LanguageServerProgress {
 8550                            title: payload.title,
 8551                            is_disk_based_diagnostics_progress: false,
 8552                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8553                            message: payload.message,
 8554                            percentage: payload.percentage.map(|p| p as usize),
 8555                            last_update_at: cx.background_executor().now(),
 8556                        },
 8557                        cx,
 8558                    );
 8559                }
 8560                proto::update_language_server::Variant::WorkProgress(payload) => {
 8561                    lsp_store.on_lsp_work_progress(
 8562                        language_server_id,
 8563                        payload.token,
 8564                        LanguageServerProgress {
 8565                            title: None,
 8566                            is_disk_based_diagnostics_progress: false,
 8567                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8568                            message: payload.message,
 8569                            percentage: payload.percentage.map(|p| p as usize),
 8570                            last_update_at: cx.background_executor().now(),
 8571                        },
 8572                        cx,
 8573                    );
 8574                }
 8575
 8576                proto::update_language_server::Variant::WorkEnd(payload) => {
 8577                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8578                }
 8579
 8580                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8581                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8582                }
 8583
 8584                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8585                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8586                }
 8587
 8588                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8589                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8590                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8591                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 8592                        language_server_id,
 8593                        name: envelope
 8594                            .payload
 8595                            .server_name
 8596                            .map(SharedString::new)
 8597                            .map(LanguageServerName),
 8598                        message: non_lsp,
 8599                    });
 8600                }
 8601            }
 8602
 8603            Ok(())
 8604        })?
 8605    }
 8606
 8607    async fn handle_language_server_log(
 8608        this: Entity<Self>,
 8609        envelope: TypedEnvelope<proto::LanguageServerLog>,
 8610        mut cx: AsyncApp,
 8611    ) -> Result<()> {
 8612        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8613        let log_type = envelope
 8614            .payload
 8615            .log_type
 8616            .map(LanguageServerLogType::from_proto)
 8617            .context("invalid language server log type")?;
 8618
 8619        let message = envelope.payload.message;
 8620
 8621        this.update(&mut cx, |_, cx| {
 8622            cx.emit(LspStoreEvent::LanguageServerLog(
 8623                language_server_id,
 8624                log_type,
 8625                message,
 8626            ));
 8627        })
 8628    }
 8629
 8630    async fn handle_lsp_ext_cancel_flycheck(
 8631        lsp_store: Entity<Self>,
 8632        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 8633        cx: AsyncApp,
 8634    ) -> Result<proto::Ack> {
 8635        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8636        lsp_store.read_with(&cx, |lsp_store, _| {
 8637            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8638                server
 8639                    .notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())
 8640                    .context("handling lsp ext cancel flycheck")
 8641            } else {
 8642                anyhow::Ok(())
 8643            }
 8644        })??;
 8645
 8646        Ok(proto::Ack {})
 8647    }
 8648
 8649    async fn handle_lsp_ext_run_flycheck(
 8650        lsp_store: Entity<Self>,
 8651        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 8652        mut cx: AsyncApp,
 8653    ) -> Result<proto::Ack> {
 8654        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8655        lsp_store.update(&mut cx, |lsp_store, cx| {
 8656            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8657                let text_document = if envelope.payload.current_file_only {
 8658                    let buffer_id = envelope
 8659                        .payload
 8660                        .buffer_id
 8661                        .map(|id| BufferId::new(id))
 8662                        .transpose()?;
 8663                    buffer_id
 8664                        .and_then(|buffer_id| {
 8665                            lsp_store
 8666                                .buffer_store()
 8667                                .read(cx)
 8668                                .get(buffer_id)
 8669                                .and_then(|buffer| {
 8670                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 8671                                })
 8672                                .map(|path| make_text_document_identifier(&path))
 8673                        })
 8674                        .transpose()?
 8675                } else {
 8676                    None
 8677                };
 8678                server
 8679                    .notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 8680                        &lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 8681                    )
 8682                    .context("handling lsp ext run flycheck")
 8683            } else {
 8684                anyhow::Ok(())
 8685            }
 8686        })??;
 8687
 8688        Ok(proto::Ack {})
 8689    }
 8690
 8691    async fn handle_lsp_ext_clear_flycheck(
 8692        lsp_store: Entity<Self>,
 8693        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 8694        cx: AsyncApp,
 8695    ) -> Result<proto::Ack> {
 8696        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8697        lsp_store.read_with(&cx, |lsp_store, _| {
 8698            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8699                server
 8700                    .notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())
 8701                    .context("handling lsp ext clear flycheck")
 8702            } else {
 8703                anyhow::Ok(())
 8704            }
 8705        })??;
 8706
 8707        Ok(proto::Ack {})
 8708    }
 8709
 8710    pub fn disk_based_diagnostics_started(
 8711        &mut self,
 8712        language_server_id: LanguageServerId,
 8713        cx: &mut Context<Self>,
 8714    ) {
 8715        if let Some(language_server_status) =
 8716            self.language_server_statuses.get_mut(&language_server_id)
 8717        {
 8718            language_server_status.has_pending_diagnostic_updates = true;
 8719        }
 8720
 8721        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 8722        cx.emit(LspStoreEvent::LanguageServerUpdate {
 8723            language_server_id,
 8724            name: self
 8725                .language_server_adapter_for_id(language_server_id)
 8726                .map(|adapter| adapter.name()),
 8727            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 8728                Default::default(),
 8729            ),
 8730        })
 8731    }
 8732
 8733    pub fn disk_based_diagnostics_finished(
 8734        &mut self,
 8735        language_server_id: LanguageServerId,
 8736        cx: &mut Context<Self>,
 8737    ) {
 8738        if let Some(language_server_status) =
 8739            self.language_server_statuses.get_mut(&language_server_id)
 8740        {
 8741            language_server_status.has_pending_diagnostic_updates = false;
 8742        }
 8743
 8744        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 8745        cx.emit(LspStoreEvent::LanguageServerUpdate {
 8746            language_server_id,
 8747            name: self
 8748                .language_server_adapter_for_id(language_server_id)
 8749                .map(|adapter| adapter.name()),
 8750            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 8751                Default::default(),
 8752            ),
 8753        })
 8754    }
 8755
 8756    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 8757    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 8758    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 8759    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 8760    // the language server might take some time to publish diagnostics.
 8761    fn simulate_disk_based_diagnostics_events_if_needed(
 8762        &mut self,
 8763        language_server_id: LanguageServerId,
 8764        cx: &mut Context<Self>,
 8765    ) {
 8766        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 8767
 8768        let Some(LanguageServerState::Running {
 8769            simulate_disk_based_diagnostics_completion,
 8770            adapter,
 8771            ..
 8772        }) = self
 8773            .as_local_mut()
 8774            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 8775        else {
 8776            return;
 8777        };
 8778
 8779        if adapter.disk_based_diagnostics_progress_token.is_some() {
 8780            return;
 8781        }
 8782
 8783        let prev_task =
 8784            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 8785                cx.background_executor()
 8786                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 8787                    .await;
 8788
 8789                this.update(cx, |this, cx| {
 8790                    this.disk_based_diagnostics_finished(language_server_id, cx);
 8791
 8792                    if let Some(LanguageServerState::Running {
 8793                        simulate_disk_based_diagnostics_completion,
 8794                        ..
 8795                    }) = this.as_local_mut().and_then(|local_store| {
 8796                        local_store.language_servers.get_mut(&language_server_id)
 8797                    }) {
 8798                        *simulate_disk_based_diagnostics_completion = None;
 8799                    }
 8800                })
 8801                .ok();
 8802            }));
 8803
 8804        if prev_task.is_none() {
 8805            self.disk_based_diagnostics_started(language_server_id, cx);
 8806        }
 8807    }
 8808
 8809    pub fn language_server_statuses(
 8810        &self,
 8811    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 8812        self.language_server_statuses
 8813            .iter()
 8814            .map(|(key, value)| (*key, value))
 8815    }
 8816
 8817    pub(super) fn did_rename_entry(
 8818        &self,
 8819        worktree_id: WorktreeId,
 8820        old_path: &Path,
 8821        new_path: &Path,
 8822        is_dir: bool,
 8823    ) {
 8824        maybe!({
 8825            let local_store = self.as_local()?;
 8826
 8827            let old_uri = lsp::Uri::from_file_path(old_path)
 8828                .ok()
 8829                .map(|uri| uri.to_string())?;
 8830            let new_uri = lsp::Uri::from_file_path(new_path)
 8831                .ok()
 8832                .map(|uri| uri.to_string())?;
 8833
 8834            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 8835                let Some(filter) = local_store
 8836                    .language_server_paths_watched_for_rename
 8837                    .get(&language_server.server_id())
 8838                else {
 8839                    continue;
 8840                };
 8841
 8842                if filter.should_send_did_rename(&old_uri, is_dir) {
 8843                    language_server
 8844                        .notify::<DidRenameFiles>(&RenameFilesParams {
 8845                            files: vec![FileRename {
 8846                                old_uri: old_uri.clone(),
 8847                                new_uri: new_uri.clone(),
 8848                            }],
 8849                        })
 8850                        .ok();
 8851                }
 8852            }
 8853            Some(())
 8854        });
 8855    }
 8856
 8857    pub(super) fn will_rename_entry(
 8858        this: WeakEntity<Self>,
 8859        worktree_id: WorktreeId,
 8860        old_path: &Path,
 8861        new_path: &Path,
 8862        is_dir: bool,
 8863        cx: AsyncApp,
 8864    ) -> Task<ProjectTransaction> {
 8865        let old_uri = lsp::Uri::from_file_path(old_path)
 8866            .ok()
 8867            .map(|uri| uri.to_string());
 8868        let new_uri = lsp::Uri::from_file_path(new_path)
 8869            .ok()
 8870            .map(|uri| uri.to_string());
 8871        cx.spawn(async move |cx| {
 8872            let mut tasks = vec![];
 8873            this.update(cx, |this, cx| {
 8874                let local_store = this.as_local()?;
 8875                let old_uri = old_uri?;
 8876                let new_uri = new_uri?;
 8877                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 8878                    let Some(filter) = local_store
 8879                        .language_server_paths_watched_for_rename
 8880                        .get(&language_server.server_id())
 8881                    else {
 8882                        continue;
 8883                    };
 8884
 8885                    if filter.should_send_will_rename(&old_uri, is_dir) {
 8886                        let apply_edit = cx.spawn({
 8887                            let old_uri = old_uri.clone();
 8888                            let new_uri = new_uri.clone();
 8889                            let language_server = language_server.clone();
 8890                            async move |this, cx| {
 8891                                let edit = language_server
 8892                                    .request::<WillRenameFiles>(RenameFilesParams {
 8893                                        files: vec![FileRename { old_uri, new_uri }],
 8894                                    })
 8895                                    .await
 8896                                    .into_response()
 8897                                    .context("will rename files")
 8898                                    .log_err()
 8899                                    .flatten()?;
 8900
 8901                                let transaction = LocalLspStore::deserialize_workspace_edit(
 8902                                    this.upgrade()?,
 8903                                    edit,
 8904                                    false,
 8905                                    language_server.clone(),
 8906                                    cx,
 8907                                )
 8908                                .await
 8909                                .ok()?;
 8910                                Some(transaction)
 8911                            }
 8912                        });
 8913                        tasks.push(apply_edit);
 8914                    }
 8915                }
 8916                Some(())
 8917            })
 8918            .ok()
 8919            .flatten();
 8920            let mut merged_transaction = ProjectTransaction::default();
 8921            for task in tasks {
 8922                // Await on tasks sequentially so that the order of application of edits is deterministic
 8923                // (at least with regards to the order of registration of language servers)
 8924                if let Some(transaction) = task.await {
 8925                    for (buffer, buffer_transaction) in transaction.0 {
 8926                        merged_transaction.0.insert(buffer, buffer_transaction);
 8927                    }
 8928                }
 8929            }
 8930            merged_transaction
 8931        })
 8932    }
 8933
 8934    fn lsp_notify_abs_paths_changed(
 8935        &mut self,
 8936        server_id: LanguageServerId,
 8937        changes: Vec<PathEvent>,
 8938    ) {
 8939        maybe!({
 8940            let server = self.language_server_for_id(server_id)?;
 8941            let changes = changes
 8942                .into_iter()
 8943                .filter_map(|event| {
 8944                    let typ = match event.kind? {
 8945                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 8946                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 8947                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 8948                    };
 8949                    Some(lsp::FileEvent {
 8950                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 8951                        typ,
 8952                    })
 8953                })
 8954                .collect::<Vec<_>>();
 8955            if !changes.is_empty() {
 8956                server
 8957                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 8958                        &lsp::DidChangeWatchedFilesParams { changes },
 8959                    )
 8960                    .ok();
 8961            }
 8962            Some(())
 8963        });
 8964    }
 8965
 8966    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 8967        self.as_local()?.language_server_for_id(id)
 8968    }
 8969
 8970    fn on_lsp_progress(
 8971        &mut self,
 8972        progress: lsp::ProgressParams,
 8973        language_server_id: LanguageServerId,
 8974        disk_based_diagnostics_progress_token: Option<String>,
 8975        cx: &mut Context<Self>,
 8976    ) {
 8977        let token = match progress.token {
 8978            lsp::NumberOrString::String(token) => token,
 8979            lsp::NumberOrString::Number(token) => {
 8980                log::info!("skipping numeric progress token {}", token);
 8981                return;
 8982            }
 8983        };
 8984
 8985        match progress.value {
 8986            lsp::ProgressParamsValue::WorkDone(progress) => {
 8987                self.handle_work_done_progress(
 8988                    progress,
 8989                    language_server_id,
 8990                    disk_based_diagnostics_progress_token,
 8991                    token,
 8992                    cx,
 8993                );
 8994            }
 8995            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 8996                if let Some(LanguageServerState::Running {
 8997                    workspace_refresh_task: Some(workspace_refresh_task),
 8998                    ..
 8999                }) = self
 9000                    .as_local_mut()
 9001                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9002                {
 9003                    workspace_refresh_task.progress_tx.try_send(()).ok();
 9004                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9005                }
 9006            }
 9007        }
 9008    }
 9009
 9010    fn handle_work_done_progress(
 9011        &mut self,
 9012        progress: lsp::WorkDoneProgress,
 9013        language_server_id: LanguageServerId,
 9014        disk_based_diagnostics_progress_token: Option<String>,
 9015        token: String,
 9016        cx: &mut Context<Self>,
 9017    ) {
 9018        let language_server_status =
 9019            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9020                status
 9021            } else {
 9022                return;
 9023            };
 9024
 9025        if !language_server_status.progress_tokens.contains(&token) {
 9026            return;
 9027        }
 9028
 9029        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9030            .as_ref()
 9031            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9032
 9033        match progress {
 9034            lsp::WorkDoneProgress::Begin(report) => {
 9035                if is_disk_based_diagnostics_progress {
 9036                    self.disk_based_diagnostics_started(language_server_id, cx);
 9037                }
 9038                self.on_lsp_work_start(
 9039                    language_server_id,
 9040                    token.clone(),
 9041                    LanguageServerProgress {
 9042                        title: Some(report.title),
 9043                        is_disk_based_diagnostics_progress,
 9044                        is_cancellable: report.cancellable.unwrap_or(false),
 9045                        message: report.message.clone(),
 9046                        percentage: report.percentage.map(|p| p as usize),
 9047                        last_update_at: cx.background_executor().now(),
 9048                    },
 9049                    cx,
 9050                );
 9051            }
 9052            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9053                language_server_id,
 9054                token,
 9055                LanguageServerProgress {
 9056                    title: None,
 9057                    is_disk_based_diagnostics_progress,
 9058                    is_cancellable: report.cancellable.unwrap_or(false),
 9059                    message: report.message,
 9060                    percentage: report.percentage.map(|p| p as usize),
 9061                    last_update_at: cx.background_executor().now(),
 9062                },
 9063                cx,
 9064            ),
 9065            lsp::WorkDoneProgress::End(_) => {
 9066                language_server_status.progress_tokens.remove(&token);
 9067                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9068                if is_disk_based_diagnostics_progress {
 9069                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9070                }
 9071            }
 9072        }
 9073    }
 9074
 9075    fn on_lsp_work_start(
 9076        &mut self,
 9077        language_server_id: LanguageServerId,
 9078        token: String,
 9079        progress: LanguageServerProgress,
 9080        cx: &mut Context<Self>,
 9081    ) {
 9082        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9083            status.pending_work.insert(token.clone(), progress.clone());
 9084            cx.notify();
 9085        }
 9086        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9087            language_server_id,
 9088            name: self
 9089                .language_server_adapter_for_id(language_server_id)
 9090                .map(|adapter| adapter.name()),
 9091            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9092                token,
 9093                title: progress.title,
 9094                message: progress.message,
 9095                percentage: progress.percentage.map(|p| p as u32),
 9096                is_cancellable: Some(progress.is_cancellable),
 9097            }),
 9098        })
 9099    }
 9100
 9101    fn on_lsp_work_progress(
 9102        &mut self,
 9103        language_server_id: LanguageServerId,
 9104        token: String,
 9105        progress: LanguageServerProgress,
 9106        cx: &mut Context<Self>,
 9107    ) {
 9108        let mut did_update = false;
 9109        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9110            match status.pending_work.entry(token.clone()) {
 9111                btree_map::Entry::Vacant(entry) => {
 9112                    entry.insert(progress.clone());
 9113                    did_update = true;
 9114                }
 9115                btree_map::Entry::Occupied(mut entry) => {
 9116                    let entry = entry.get_mut();
 9117                    if (progress.last_update_at - entry.last_update_at)
 9118                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9119                    {
 9120                        entry.last_update_at = progress.last_update_at;
 9121                        if progress.message.is_some() {
 9122                            entry.message = progress.message.clone();
 9123                        }
 9124                        if progress.percentage.is_some() {
 9125                            entry.percentage = progress.percentage;
 9126                        }
 9127                        if progress.is_cancellable != entry.is_cancellable {
 9128                            entry.is_cancellable = progress.is_cancellable;
 9129                        }
 9130                        did_update = true;
 9131                    }
 9132                }
 9133            }
 9134        }
 9135
 9136        if did_update {
 9137            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9138                language_server_id,
 9139                name: self
 9140                    .language_server_adapter_for_id(language_server_id)
 9141                    .map(|adapter| adapter.name()),
 9142                message: proto::update_language_server::Variant::WorkProgress(
 9143                    proto::LspWorkProgress {
 9144                        token,
 9145                        message: progress.message,
 9146                        percentage: progress.percentage.map(|p| p as u32),
 9147                        is_cancellable: Some(progress.is_cancellable),
 9148                    },
 9149                ),
 9150            })
 9151        }
 9152    }
 9153
 9154    fn on_lsp_work_end(
 9155        &mut self,
 9156        language_server_id: LanguageServerId,
 9157        token: String,
 9158        cx: &mut Context<Self>,
 9159    ) {
 9160        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9161            if let Some(work) = status.pending_work.remove(&token)
 9162                && !work.is_disk_based_diagnostics_progress
 9163            {
 9164                cx.emit(LspStoreEvent::RefreshInlayHints);
 9165            }
 9166            cx.notify();
 9167        }
 9168
 9169        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9170            language_server_id,
 9171            name: self
 9172                .language_server_adapter_for_id(language_server_id)
 9173                .map(|adapter| adapter.name()),
 9174            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9175        })
 9176    }
 9177
 9178    pub async fn handle_resolve_completion_documentation(
 9179        this: Entity<Self>,
 9180        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9181        mut cx: AsyncApp,
 9182    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9183        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9184
 9185        let completion = this
 9186            .read_with(&cx, |this, cx| {
 9187                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9188                let server = this
 9189                    .language_server_for_id(id)
 9190                    .with_context(|| format!("No language server {id}"))?;
 9191
 9192                anyhow::Ok(cx.background_spawn(async move {
 9193                    let can_resolve = server
 9194                        .capabilities()
 9195                        .completion_provider
 9196                        .as_ref()
 9197                        .and_then(|options| options.resolve_provider)
 9198                        .unwrap_or(false);
 9199                    if can_resolve {
 9200                        server
 9201                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9202                            .await
 9203                            .into_response()
 9204                            .context("resolve completion item")
 9205                    } else {
 9206                        anyhow::Ok(lsp_completion)
 9207                    }
 9208                }))
 9209            })??
 9210            .await?;
 9211
 9212        let mut documentation_is_markdown = false;
 9213        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9214        let documentation = match completion.documentation {
 9215            Some(lsp::Documentation::String(text)) => text,
 9216
 9217            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9218                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9219                value
 9220            }
 9221
 9222            _ => String::new(),
 9223        };
 9224
 9225        // If we have a new buffer_id, that means we're talking to a new client
 9226        // and want to check for new text_edits in the completion too.
 9227        let mut old_replace_start = None;
 9228        let mut old_replace_end = None;
 9229        let mut old_insert_start = None;
 9230        let mut old_insert_end = None;
 9231        let mut new_text = String::default();
 9232        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9233            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9234                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9235                anyhow::Ok(buffer.read(cx).snapshot())
 9236            })??;
 9237
 9238            if let Some(text_edit) = completion.text_edit.as_ref() {
 9239                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9240
 9241                if let Some(mut edit) = edit {
 9242                    LineEnding::normalize(&mut edit.new_text);
 9243
 9244                    new_text = edit.new_text;
 9245                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9246                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9247                    if let Some(insert_range) = edit.insert_range {
 9248                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9249                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9250                    }
 9251                }
 9252            }
 9253        }
 9254
 9255        Ok(proto::ResolveCompletionDocumentationResponse {
 9256            documentation,
 9257            documentation_is_markdown,
 9258            old_replace_start,
 9259            old_replace_end,
 9260            new_text,
 9261            lsp_completion,
 9262            old_insert_start,
 9263            old_insert_end,
 9264        })
 9265    }
 9266
 9267    async fn handle_on_type_formatting(
 9268        this: Entity<Self>,
 9269        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9270        mut cx: AsyncApp,
 9271    ) -> Result<proto::OnTypeFormattingResponse> {
 9272        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9273            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9274            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9275            let position = envelope
 9276                .payload
 9277                .position
 9278                .and_then(deserialize_anchor)
 9279                .context("invalid position")?;
 9280            anyhow::Ok(this.apply_on_type_formatting(
 9281                buffer,
 9282                position,
 9283                envelope.payload.trigger.clone(),
 9284                cx,
 9285            ))
 9286        })??;
 9287
 9288        let transaction = on_type_formatting
 9289            .await?
 9290            .as_ref()
 9291            .map(language::proto::serialize_transaction);
 9292        Ok(proto::OnTypeFormattingResponse { transaction })
 9293    }
 9294
 9295    async fn handle_refresh_inlay_hints(
 9296        this: Entity<Self>,
 9297        _: TypedEnvelope<proto::RefreshInlayHints>,
 9298        mut cx: AsyncApp,
 9299    ) -> Result<proto::Ack> {
 9300        this.update(&mut cx, |_, cx| {
 9301            cx.emit(LspStoreEvent::RefreshInlayHints);
 9302        })?;
 9303        Ok(proto::Ack {})
 9304    }
 9305
 9306    async fn handle_pull_workspace_diagnostics(
 9307        lsp_store: Entity<Self>,
 9308        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9309        mut cx: AsyncApp,
 9310    ) -> Result<proto::Ack> {
 9311        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9312        lsp_store.update(&mut cx, |lsp_store, _| {
 9313            lsp_store.pull_workspace_diagnostics(server_id);
 9314        })?;
 9315        Ok(proto::Ack {})
 9316    }
 9317
 9318    async fn handle_inlay_hints(
 9319        this: Entity<Self>,
 9320        envelope: TypedEnvelope<proto::InlayHints>,
 9321        mut cx: AsyncApp,
 9322    ) -> Result<proto::InlayHintsResponse> {
 9323        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9324        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9325        let buffer = this.update(&mut cx, |this, cx| {
 9326            this.buffer_store.read(cx).get_existing(buffer_id)
 9327        })??;
 9328        buffer
 9329            .update(&mut cx, |buffer, _| {
 9330                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9331            })?
 9332            .await
 9333            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9334
 9335        let start = envelope
 9336            .payload
 9337            .start
 9338            .and_then(deserialize_anchor)
 9339            .context("missing range start")?;
 9340        let end = envelope
 9341            .payload
 9342            .end
 9343            .and_then(deserialize_anchor)
 9344            .context("missing range end")?;
 9345        let buffer_hints = this
 9346            .update(&mut cx, |lsp_store, cx| {
 9347                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9348            })?
 9349            .await
 9350            .context("inlay hints fetch")?;
 9351
 9352        this.update(&mut cx, |project, cx| {
 9353            InlayHints::response_to_proto(
 9354                buffer_hints,
 9355                project,
 9356                sender_id,
 9357                &buffer.read(cx).version(),
 9358                cx,
 9359            )
 9360        })
 9361    }
 9362
 9363    async fn handle_get_color_presentation(
 9364        lsp_store: Entity<Self>,
 9365        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9366        mut cx: AsyncApp,
 9367    ) -> Result<proto::GetColorPresentationResponse> {
 9368        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9369        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9370            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9371        })??;
 9372
 9373        let color = envelope
 9374            .payload
 9375            .color
 9376            .context("invalid color resolve request")?;
 9377        let start = color
 9378            .lsp_range_start
 9379            .context("invalid color resolve request")?;
 9380        let end = color
 9381            .lsp_range_end
 9382            .context("invalid color resolve request")?;
 9383
 9384        let color = DocumentColor {
 9385            lsp_range: lsp::Range {
 9386                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9387                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9388            },
 9389            color: lsp::Color {
 9390                red: color.red,
 9391                green: color.green,
 9392                blue: color.blue,
 9393                alpha: color.alpha,
 9394            },
 9395            resolved: false,
 9396            color_presentations: Vec::new(),
 9397        };
 9398        let resolved_color = lsp_store
 9399            .update(&mut cx, |lsp_store, cx| {
 9400                lsp_store.resolve_color_presentation(
 9401                    color,
 9402                    buffer.clone(),
 9403                    LanguageServerId(envelope.payload.server_id as usize),
 9404                    cx,
 9405                )
 9406            })?
 9407            .await
 9408            .context("resolving color presentation")?;
 9409
 9410        Ok(proto::GetColorPresentationResponse {
 9411            presentations: resolved_color
 9412                .color_presentations
 9413                .into_iter()
 9414                .map(|presentation| proto::ColorPresentation {
 9415                    label: presentation.label.to_string(),
 9416                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9417                    additional_text_edits: presentation
 9418                        .additional_text_edits
 9419                        .into_iter()
 9420                        .map(serialize_lsp_edit)
 9421                        .collect(),
 9422                })
 9423                .collect(),
 9424        })
 9425    }
 9426
 9427    async fn handle_resolve_inlay_hint(
 9428        this: Entity<Self>,
 9429        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9430        mut cx: AsyncApp,
 9431    ) -> Result<proto::ResolveInlayHintResponse> {
 9432        let proto_hint = envelope
 9433            .payload
 9434            .hint
 9435            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9436        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9437            .context("resolved proto inlay hint conversion")?;
 9438        let buffer = this.update(&mut cx, |this, cx| {
 9439            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9440            this.buffer_store.read(cx).get_existing(buffer_id)
 9441        })??;
 9442        let response_hint = this
 9443            .update(&mut cx, |this, cx| {
 9444                this.resolve_inlay_hint(
 9445                    hint,
 9446                    buffer,
 9447                    LanguageServerId(envelope.payload.language_server_id as usize),
 9448                    cx,
 9449                )
 9450            })?
 9451            .await
 9452            .context("inlay hints fetch")?;
 9453        Ok(proto::ResolveInlayHintResponse {
 9454            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9455        })
 9456    }
 9457
 9458    async fn handle_refresh_code_lens(
 9459        this: Entity<Self>,
 9460        _: TypedEnvelope<proto::RefreshCodeLens>,
 9461        mut cx: AsyncApp,
 9462    ) -> Result<proto::Ack> {
 9463        this.update(&mut cx, |_, cx| {
 9464            cx.emit(LspStoreEvent::RefreshCodeLens);
 9465        })?;
 9466        Ok(proto::Ack {})
 9467    }
 9468
 9469    async fn handle_open_buffer_for_symbol(
 9470        this: Entity<Self>,
 9471        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9472        mut cx: AsyncApp,
 9473    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9474        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9475        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9476        let symbol = Self::deserialize_symbol(symbol)?;
 9477        this.read_with(&cx, |this, _| {
 9478            if let SymbolLocation::OutsideProject {
 9479                abs_path,
 9480                signature,
 9481            } = &symbol.path
 9482            {
 9483                let new_signature = this.symbol_signature(&abs_path);
 9484                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9485            }
 9486            Ok(())
 9487        })??;
 9488        let buffer = this
 9489            .update(&mut cx, |this, cx| {
 9490                this.open_buffer_for_symbol(
 9491                    &Symbol {
 9492                        language_server_name: symbol.language_server_name,
 9493                        source_worktree_id: symbol.source_worktree_id,
 9494                        source_language_server_id: symbol.source_language_server_id,
 9495                        path: symbol.path,
 9496                        name: symbol.name,
 9497                        kind: symbol.kind,
 9498                        range: symbol.range,
 9499                        label: CodeLabel {
 9500                            text: Default::default(),
 9501                            runs: Default::default(),
 9502                            filter_range: Default::default(),
 9503                        },
 9504                    },
 9505                    cx,
 9506                )
 9507            })?
 9508            .await?;
 9509
 9510        this.update(&mut cx, |this, cx| {
 9511            let is_private = buffer
 9512                .read(cx)
 9513                .file()
 9514                .map(|f| f.is_private())
 9515                .unwrap_or_default();
 9516            if is_private {
 9517                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9518            } else {
 9519                this.buffer_store
 9520                    .update(cx, |buffer_store, cx| {
 9521                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9522                    })
 9523                    .detach_and_log_err(cx);
 9524                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9525                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9526            }
 9527        })?
 9528    }
 9529
 9530    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9531        let mut hasher = Sha256::new();
 9532        hasher.update(abs_path.to_string_lossy().as_bytes());
 9533        hasher.update(self.nonce.to_be_bytes());
 9534        hasher.finalize().as_slice().try_into().unwrap()
 9535    }
 9536
 9537    pub async fn handle_get_project_symbols(
 9538        this: Entity<Self>,
 9539        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9540        mut cx: AsyncApp,
 9541    ) -> Result<proto::GetProjectSymbolsResponse> {
 9542        let symbols = this
 9543            .update(&mut cx, |this, cx| {
 9544                this.symbols(&envelope.payload.query, cx)
 9545            })?
 9546            .await?;
 9547
 9548        Ok(proto::GetProjectSymbolsResponse {
 9549            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9550        })
 9551    }
 9552
 9553    pub async fn handle_restart_language_servers(
 9554        this: Entity<Self>,
 9555        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9556        mut cx: AsyncApp,
 9557    ) -> Result<proto::Ack> {
 9558        this.update(&mut cx, |lsp_store, cx| {
 9559            let buffers =
 9560                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9561            lsp_store.restart_language_servers_for_buffers(
 9562                buffers,
 9563                envelope
 9564                    .payload
 9565                    .only_servers
 9566                    .into_iter()
 9567                    .filter_map(|selector| {
 9568                        Some(match selector.selector? {
 9569                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9570                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9571                            }
 9572                            proto::language_server_selector::Selector::Name(name) => {
 9573                                LanguageServerSelector::Name(LanguageServerName(
 9574                                    SharedString::from(name),
 9575                                ))
 9576                            }
 9577                        })
 9578                    })
 9579                    .collect(),
 9580                cx,
 9581            );
 9582        })?;
 9583
 9584        Ok(proto::Ack {})
 9585    }
 9586
 9587    pub async fn handle_stop_language_servers(
 9588        lsp_store: Entity<Self>,
 9589        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9590        mut cx: AsyncApp,
 9591    ) -> Result<proto::Ack> {
 9592        lsp_store.update(&mut cx, |lsp_store, cx| {
 9593            if envelope.payload.all
 9594                && envelope.payload.also_servers.is_empty()
 9595                && envelope.payload.buffer_ids.is_empty()
 9596            {
 9597                lsp_store.stop_all_language_servers(cx);
 9598            } else {
 9599                let buffers =
 9600                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9601                lsp_store
 9602                    .stop_language_servers_for_buffers(
 9603                        buffers,
 9604                        envelope
 9605                            .payload
 9606                            .also_servers
 9607                            .into_iter()
 9608                            .filter_map(|selector| {
 9609                                Some(match selector.selector? {
 9610                                    proto::language_server_selector::Selector::ServerId(
 9611                                        server_id,
 9612                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9613                                        server_id,
 9614                                    )),
 9615                                    proto::language_server_selector::Selector::Name(name) => {
 9616                                        LanguageServerSelector::Name(LanguageServerName(
 9617                                            SharedString::from(name),
 9618                                        ))
 9619                                    }
 9620                                })
 9621                            })
 9622                            .collect(),
 9623                        cx,
 9624                    )
 9625                    .detach_and_log_err(cx);
 9626            }
 9627        })?;
 9628
 9629        Ok(proto::Ack {})
 9630    }
 9631
 9632    pub async fn handle_cancel_language_server_work(
 9633        this: Entity<Self>,
 9634        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
 9635        mut cx: AsyncApp,
 9636    ) -> Result<proto::Ack> {
 9637        this.update(&mut cx, |this, cx| {
 9638            if let Some(work) = envelope.payload.work {
 9639                match work {
 9640                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
 9641                        let buffers =
 9642                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
 9643                        this.cancel_language_server_work_for_buffers(buffers, cx);
 9644                    }
 9645                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
 9646                        let server_id = LanguageServerId::from_proto(work.language_server_id);
 9647                        this.cancel_language_server_work(server_id, work.token, cx);
 9648                    }
 9649                }
 9650            }
 9651        })?;
 9652
 9653        Ok(proto::Ack {})
 9654    }
 9655
 9656    fn buffer_ids_to_buffers(
 9657        &mut self,
 9658        buffer_ids: impl Iterator<Item = u64>,
 9659        cx: &mut Context<Self>,
 9660    ) -> Vec<Entity<Buffer>> {
 9661        buffer_ids
 9662            .into_iter()
 9663            .flat_map(|buffer_id| {
 9664                self.buffer_store
 9665                    .read(cx)
 9666                    .get(BufferId::new(buffer_id).log_err()?)
 9667            })
 9668            .collect::<Vec<_>>()
 9669    }
 9670
 9671    async fn handle_apply_additional_edits_for_completion(
 9672        this: Entity<Self>,
 9673        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
 9674        mut cx: AsyncApp,
 9675    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
 9676        let (buffer, completion) = this.update(&mut cx, |this, cx| {
 9677            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9678            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9679            let completion = Self::deserialize_completion(
 9680                envelope.payload.completion.context("invalid completion")?,
 9681            )?;
 9682            anyhow::Ok((buffer, completion))
 9683        })??;
 9684
 9685        let apply_additional_edits = this.update(&mut cx, |this, cx| {
 9686            this.apply_additional_edits_for_completion(
 9687                buffer,
 9688                Rc::new(RefCell::new(Box::new([Completion {
 9689                    replace_range: completion.replace_range,
 9690                    new_text: completion.new_text,
 9691                    source: completion.source,
 9692                    documentation: None,
 9693                    label: CodeLabel {
 9694                        text: Default::default(),
 9695                        runs: Default::default(),
 9696                        filter_range: Default::default(),
 9697                    },
 9698                    insert_text_mode: None,
 9699                    icon_path: None,
 9700                    confirm: None,
 9701                }]))),
 9702                0,
 9703                false,
 9704                cx,
 9705            )
 9706        })?;
 9707
 9708        Ok(proto::ApplyCompletionAdditionalEditsResponse {
 9709            transaction: apply_additional_edits
 9710                .await?
 9711                .as_ref()
 9712                .map(language::proto::serialize_transaction),
 9713        })
 9714    }
 9715
 9716    pub fn last_formatting_failure(&self) -> Option<&str> {
 9717        self.last_formatting_failure.as_deref()
 9718    }
 9719
 9720    pub fn reset_last_formatting_failure(&mut self) {
 9721        self.last_formatting_failure = None;
 9722    }
 9723
 9724    pub fn environment_for_buffer(
 9725        &self,
 9726        buffer: &Entity<Buffer>,
 9727        cx: &mut Context<Self>,
 9728    ) -> Shared<Task<Option<HashMap<String, String>>>> {
 9729        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
 9730            environment.update(cx, |env, cx| {
 9731                env.get_buffer_environment(buffer, &self.worktree_store, cx)
 9732            })
 9733        } else {
 9734            Task::ready(None).shared()
 9735        }
 9736    }
 9737
 9738    pub fn format(
 9739        &mut self,
 9740        buffers: HashSet<Entity<Buffer>>,
 9741        target: LspFormatTarget,
 9742        push_to_history: bool,
 9743        trigger: FormatTrigger,
 9744        cx: &mut Context<Self>,
 9745    ) -> Task<anyhow::Result<ProjectTransaction>> {
 9746        let logger = zlog::scoped!("format");
 9747        if self.as_local().is_some() {
 9748            zlog::trace!(logger => "Formatting locally");
 9749            let logger = zlog::scoped!(logger => "local");
 9750            let buffers = buffers
 9751                .into_iter()
 9752                .map(|buffer_handle| {
 9753                    let buffer = buffer_handle.read(cx);
 9754                    let buffer_abs_path = File::from_dyn(buffer.file())
 9755                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
 9756
 9757                    (buffer_handle, buffer_abs_path, buffer.remote_id())
 9758                })
 9759                .collect::<Vec<_>>();
 9760
 9761            cx.spawn(async move |lsp_store, cx| {
 9762                let mut formattable_buffers = Vec::with_capacity(buffers.len());
 9763
 9764                for (handle, abs_path, id) in buffers {
 9765                    let env = lsp_store
 9766                        .update(cx, |lsp_store, cx| {
 9767                            lsp_store.environment_for_buffer(&handle, cx)
 9768                        })?
 9769                        .await;
 9770
 9771                    let ranges = match &target {
 9772                        LspFormatTarget::Buffers => None,
 9773                        LspFormatTarget::Ranges(ranges) => {
 9774                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
 9775                        }
 9776                    };
 9777
 9778                    formattable_buffers.push(FormattableBuffer {
 9779                        handle,
 9780                        abs_path,
 9781                        env,
 9782                        ranges,
 9783                    });
 9784                }
 9785                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
 9786
 9787                let format_timer = zlog::time!(logger => "Formatting buffers");
 9788                let result = LocalLspStore::format_locally(
 9789                    lsp_store.clone(),
 9790                    formattable_buffers,
 9791                    push_to_history,
 9792                    trigger,
 9793                    logger,
 9794                    cx,
 9795                )
 9796                .await;
 9797                format_timer.end();
 9798
 9799                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
 9800
 9801                lsp_store.update(cx, |lsp_store, _| {
 9802                    lsp_store.update_last_formatting_failure(&result);
 9803                })?;
 9804
 9805                result
 9806            })
 9807        } else if let Some((client, project_id)) = self.upstream_client() {
 9808            zlog::trace!(logger => "Formatting remotely");
 9809            let logger = zlog::scoped!(logger => "remote");
 9810            // Don't support formatting ranges via remote
 9811            match target {
 9812                LspFormatTarget::Buffers => {}
 9813                LspFormatTarget::Ranges(_) => {
 9814                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
 9815                    return Task::ready(Ok(ProjectTransaction::default()));
 9816                }
 9817            }
 9818
 9819            let buffer_store = self.buffer_store();
 9820            cx.spawn(async move |lsp_store, cx| {
 9821                zlog::trace!(logger => "Sending remote format request");
 9822                let request_timer = zlog::time!(logger => "remote format request");
 9823                let result = client
 9824                    .request(proto::FormatBuffers {
 9825                        project_id,
 9826                        trigger: trigger as i32,
 9827                        buffer_ids: buffers
 9828                            .iter()
 9829                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
 9830                            .collect::<Result<_>>()?,
 9831                    })
 9832                    .await
 9833                    .and_then(|result| result.transaction.context("missing transaction"));
 9834                request_timer.end();
 9835
 9836                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
 9837
 9838                lsp_store.update(cx, |lsp_store, _| {
 9839                    lsp_store.update_last_formatting_failure(&result);
 9840                })?;
 9841
 9842                let transaction_response = result?;
 9843                let _timer = zlog::time!(logger => "deserializing project transaction");
 9844                buffer_store
 9845                    .update(cx, |buffer_store, cx| {
 9846                        buffer_store.deserialize_project_transaction(
 9847                            transaction_response,
 9848                            push_to_history,
 9849                            cx,
 9850                        )
 9851                    })?
 9852                    .await
 9853            })
 9854        } else {
 9855            zlog::trace!(logger => "Not formatting");
 9856            Task::ready(Ok(ProjectTransaction::default()))
 9857        }
 9858    }
 9859
 9860    async fn handle_format_buffers(
 9861        this: Entity<Self>,
 9862        envelope: TypedEnvelope<proto::FormatBuffers>,
 9863        mut cx: AsyncApp,
 9864    ) -> Result<proto::FormatBuffersResponse> {
 9865        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9866        let format = this.update(&mut cx, |this, cx| {
 9867            let mut buffers = HashSet::default();
 9868            for buffer_id in &envelope.payload.buffer_ids {
 9869                let buffer_id = BufferId::new(*buffer_id)?;
 9870                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
 9871            }
 9872            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
 9873            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
 9874        })??;
 9875
 9876        let project_transaction = format.await?;
 9877        let project_transaction = this.update(&mut cx, |this, cx| {
 9878            this.buffer_store.update(cx, |buffer_store, cx| {
 9879                buffer_store.serialize_project_transaction_for_peer(
 9880                    project_transaction,
 9881                    sender_id,
 9882                    cx,
 9883                )
 9884            })
 9885        })?;
 9886        Ok(proto::FormatBuffersResponse {
 9887            transaction: Some(project_transaction),
 9888        })
 9889    }
 9890
 9891    async fn handle_apply_code_action_kind(
 9892        this: Entity<Self>,
 9893        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
 9894        mut cx: AsyncApp,
 9895    ) -> Result<proto::ApplyCodeActionKindResponse> {
 9896        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9897        let format = this.update(&mut cx, |this, cx| {
 9898            let mut buffers = HashSet::default();
 9899            for buffer_id in &envelope.payload.buffer_ids {
 9900                let buffer_id = BufferId::new(*buffer_id)?;
 9901                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
 9902            }
 9903            let kind = match envelope.payload.kind.as_str() {
 9904                "" => CodeActionKind::EMPTY,
 9905                "quickfix" => CodeActionKind::QUICKFIX,
 9906                "refactor" => CodeActionKind::REFACTOR,
 9907                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
 9908                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
 9909                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
 9910                "source" => CodeActionKind::SOURCE,
 9911                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
 9912                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
 9913                _ => anyhow::bail!(
 9914                    "Invalid code action kind {}",
 9915                    envelope.payload.kind.as_str()
 9916                ),
 9917            };
 9918            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
 9919        })??;
 9920
 9921        let project_transaction = format.await?;
 9922        let project_transaction = this.update(&mut cx, |this, cx| {
 9923            this.buffer_store.update(cx, |buffer_store, cx| {
 9924                buffer_store.serialize_project_transaction_for_peer(
 9925                    project_transaction,
 9926                    sender_id,
 9927                    cx,
 9928                )
 9929            })
 9930        })?;
 9931        Ok(proto::ApplyCodeActionKindResponse {
 9932            transaction: Some(project_transaction),
 9933        })
 9934    }
 9935
 9936    async fn shutdown_language_server(
 9937        server_state: Option<LanguageServerState>,
 9938        name: LanguageServerName,
 9939        cx: &mut AsyncApp,
 9940    ) {
 9941        let server = match server_state {
 9942            Some(LanguageServerState::Starting { startup, .. }) => {
 9943                let mut timer = cx
 9944                    .background_executor()
 9945                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
 9946                    .fuse();
 9947
 9948                select! {
 9949                    server = startup.fuse() => server,
 9950                    () = timer => {
 9951                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
 9952                        None
 9953                    },
 9954                }
 9955            }
 9956
 9957            Some(LanguageServerState::Running { server, .. }) => Some(server),
 9958
 9959            None => None,
 9960        };
 9961
 9962        if let Some(server) = server
 9963            && let Some(shutdown) = server.shutdown()
 9964        {
 9965            shutdown.await;
 9966        }
 9967    }
 9968
 9969    // Returns a list of all of the worktrees which no longer have a language server and the root path
 9970    // for the stopped server
 9971    fn stop_local_language_server(
 9972        &mut self,
 9973        server_id: LanguageServerId,
 9974        cx: &mut Context<Self>,
 9975    ) -> Task<()> {
 9976        let local = match &mut self.mode {
 9977            LspStoreMode::Local(local) => local,
 9978            _ => {
 9979                return Task::ready(());
 9980            }
 9981        };
 9982
 9983        // Remove this server ID from all entries in the given worktree.
 9984        local
 9985            .language_server_ids
 9986            .retain(|_, state| state.id != server_id);
 9987        self.buffer_store.update(cx, |buffer_store, cx| {
 9988            for buffer in buffer_store.buffers() {
 9989                buffer.update(cx, |buffer, cx| {
 9990                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 9991                    buffer.set_completion_triggers(server_id, Default::default(), cx);
 9992                });
 9993            }
 9994        });
 9995
 9996        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
 9997            summaries.retain(|path, summaries_by_server_id| {
 9998                if summaries_by_server_id.remove(&server_id).is_some() {
 9999                    if let Some((client, project_id)) = self.downstream_client.clone() {
10000                        client
10001                            .send(proto::UpdateDiagnosticSummary {
10002                                project_id,
10003                                worktree_id: worktree_id.to_proto(),
10004                                summary: Some(proto::DiagnosticSummary {
10005                                    path: path.as_ref().to_proto(),
10006                                    language_server_id: server_id.0 as u64,
10007                                    error_count: 0,
10008                                    warning_count: 0,
10009                                }),
10010                                more_summaries: Vec::new(),
10011                            })
10012                            .log_err();
10013                    }
10014                    !summaries_by_server_id.is_empty()
10015                } else {
10016                    true
10017                }
10018            });
10019        }
10020
10021        let local = self.as_local_mut().unwrap();
10022        for diagnostics in local.diagnostics.values_mut() {
10023            diagnostics.retain(|_, diagnostics_by_server_id| {
10024                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10025                    diagnostics_by_server_id.remove(ix);
10026                    !diagnostics_by_server_id.is_empty()
10027                } else {
10028                    true
10029                }
10030            });
10031        }
10032        local.language_server_watched_paths.remove(&server_id);
10033
10034        let server_state = local.language_servers.remove(&server_id);
10035        self.cleanup_lsp_data(server_id);
10036        let name = self
10037            .language_server_statuses
10038            .remove(&server_id)
10039            .map(|status| status.name)
10040            .or_else(|| {
10041                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10042                    Some(adapter.name())
10043                } else {
10044                    None
10045                }
10046            });
10047
10048        if let Some(name) = name {
10049            log::info!("stopping language server {name}");
10050            self.languages
10051                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10052            cx.notify();
10053
10054            return cx.spawn(async move |lsp_store, cx| {
10055                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10056                lsp_store
10057                    .update(cx, |lsp_store, cx| {
10058                        lsp_store
10059                            .languages
10060                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10061                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10062                        cx.notify();
10063                    })
10064                    .ok();
10065            });
10066        }
10067
10068        if server_state.is_some() {
10069            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10070        }
10071        Task::ready(())
10072    }
10073
10074    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10075        if let Some((client, project_id)) = self.upstream_client() {
10076            let request = client.request(proto::StopLanguageServers {
10077                project_id,
10078                buffer_ids: Vec::new(),
10079                also_servers: Vec::new(),
10080                all: true,
10081            });
10082            cx.background_spawn(request).detach_and_log_err(cx);
10083        } else {
10084            let Some(local) = self.as_local_mut() else {
10085                return;
10086            };
10087            let language_servers_to_stop = local
10088                .language_server_ids
10089                .values()
10090                .map(|state| state.id)
10091                .collect();
10092            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10093            let tasks = language_servers_to_stop
10094                .into_iter()
10095                .map(|server| self.stop_local_language_server(server, cx))
10096                .collect::<Vec<_>>();
10097            cx.background_spawn(async move {
10098                futures::future::join_all(tasks).await;
10099            })
10100            .detach();
10101        }
10102    }
10103
10104    pub fn restart_language_servers_for_buffers(
10105        &mut self,
10106        buffers: Vec<Entity<Buffer>>,
10107        only_restart_servers: HashSet<LanguageServerSelector>,
10108        cx: &mut Context<Self>,
10109    ) {
10110        if let Some((client, project_id)) = self.upstream_client() {
10111            let request = client.request(proto::RestartLanguageServers {
10112                project_id,
10113                buffer_ids: buffers
10114                    .into_iter()
10115                    .map(|b| b.read(cx).remote_id().to_proto())
10116                    .collect(),
10117                only_servers: only_restart_servers
10118                    .into_iter()
10119                    .map(|selector| {
10120                        let selector = match selector {
10121                            LanguageServerSelector::Id(language_server_id) => {
10122                                proto::language_server_selector::Selector::ServerId(
10123                                    language_server_id.to_proto(),
10124                                )
10125                            }
10126                            LanguageServerSelector::Name(language_server_name) => {
10127                                proto::language_server_selector::Selector::Name(
10128                                    language_server_name.to_string(),
10129                                )
10130                            }
10131                        };
10132                        proto::LanguageServerSelector {
10133                            selector: Some(selector),
10134                        }
10135                    })
10136                    .collect(),
10137                all: false,
10138            });
10139            cx.background_spawn(request).detach_and_log_err(cx);
10140        } else {
10141            let stop_task = if only_restart_servers.is_empty() {
10142                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10143            } else {
10144                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10145            };
10146            cx.spawn(async move |lsp_store, cx| {
10147                stop_task.await;
10148                lsp_store
10149                    .update(cx, |lsp_store, cx| {
10150                        for buffer in buffers {
10151                            lsp_store.register_buffer_with_language_servers(
10152                                &buffer,
10153                                only_restart_servers.clone(),
10154                                true,
10155                                cx,
10156                            );
10157                        }
10158                    })
10159                    .ok()
10160            })
10161            .detach();
10162        }
10163    }
10164
10165    pub fn stop_language_servers_for_buffers(
10166        &mut self,
10167        buffers: Vec<Entity<Buffer>>,
10168        also_stop_servers: HashSet<LanguageServerSelector>,
10169        cx: &mut Context<Self>,
10170    ) -> Task<Result<()>> {
10171        if let Some((client, project_id)) = self.upstream_client() {
10172            let request = client.request(proto::StopLanguageServers {
10173                project_id,
10174                buffer_ids: buffers
10175                    .into_iter()
10176                    .map(|b| b.read(cx).remote_id().to_proto())
10177                    .collect(),
10178                also_servers: also_stop_servers
10179                    .into_iter()
10180                    .map(|selector| {
10181                        let selector = match selector {
10182                            LanguageServerSelector::Id(language_server_id) => {
10183                                proto::language_server_selector::Selector::ServerId(
10184                                    language_server_id.to_proto(),
10185                                )
10186                            }
10187                            LanguageServerSelector::Name(language_server_name) => {
10188                                proto::language_server_selector::Selector::Name(
10189                                    language_server_name.to_string(),
10190                                )
10191                            }
10192                        };
10193                        proto::LanguageServerSelector {
10194                            selector: Some(selector),
10195                        }
10196                    })
10197                    .collect(),
10198                all: false,
10199            });
10200            cx.background_spawn(async move {
10201                let _ = request.await?;
10202                Ok(())
10203            })
10204        } else {
10205            let task =
10206                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10207            cx.background_spawn(async move {
10208                task.await;
10209                Ok(())
10210            })
10211        }
10212    }
10213
10214    fn stop_local_language_servers_for_buffers(
10215        &mut self,
10216        buffers: &[Entity<Buffer>],
10217        also_stop_servers: HashSet<LanguageServerSelector>,
10218        cx: &mut Context<Self>,
10219    ) -> Task<()> {
10220        let Some(local) = self.as_local_mut() else {
10221            return Task::ready(());
10222        };
10223        let mut language_server_names_to_stop = BTreeSet::default();
10224        let mut language_servers_to_stop = also_stop_servers
10225            .into_iter()
10226            .flat_map(|selector| match selector {
10227                LanguageServerSelector::Id(id) => Some(id),
10228                LanguageServerSelector::Name(name) => {
10229                    language_server_names_to_stop.insert(name);
10230                    None
10231                }
10232            })
10233            .collect::<BTreeSet<_>>();
10234
10235        let mut covered_worktrees = HashSet::default();
10236        for buffer in buffers {
10237            buffer.update(cx, |buffer, cx| {
10238                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10239                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10240                    && covered_worktrees.insert(worktree_id)
10241                {
10242                    language_server_names_to_stop.retain(|name| {
10243                        let old_ids_count = language_servers_to_stop.len();
10244                        let all_language_servers_with_this_name = local
10245                            .language_server_ids
10246                            .iter()
10247                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10248                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10249                        old_ids_count == language_servers_to_stop.len()
10250                    });
10251                }
10252            });
10253        }
10254        for name in language_server_names_to_stop {
10255            language_servers_to_stop.extend(
10256                local
10257                    .language_server_ids
10258                    .iter()
10259                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10260            );
10261        }
10262
10263        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10264        let tasks = language_servers_to_stop
10265            .into_iter()
10266            .map(|server| self.stop_local_language_server(server, cx))
10267            .collect::<Vec<_>>();
10268
10269        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10270    }
10271
10272    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10273        let (worktree, relative_path) =
10274            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10275
10276        let project_path = ProjectPath {
10277            worktree_id: worktree.read(cx).id(),
10278            path: relative_path,
10279        };
10280
10281        Some(
10282            self.buffer_store()
10283                .read(cx)
10284                .get_by_path(&project_path)?
10285                .read(cx),
10286        )
10287    }
10288
10289    #[cfg(any(test, feature = "test-support"))]
10290    pub fn update_diagnostics(
10291        &mut self,
10292        server_id: LanguageServerId,
10293        diagnostics: lsp::PublishDiagnosticsParams,
10294        result_id: Option<String>,
10295        source_kind: DiagnosticSourceKind,
10296        disk_based_sources: &[String],
10297        cx: &mut Context<Self>,
10298    ) -> Result<()> {
10299        self.merge_lsp_diagnostics(
10300            source_kind,
10301            vec![DocumentDiagnosticsUpdate {
10302                diagnostics,
10303                result_id,
10304                server_id,
10305                disk_based_sources: Cow::Borrowed(disk_based_sources),
10306            }],
10307            |_, _, _| false,
10308            cx,
10309        )
10310    }
10311
10312    pub fn merge_lsp_diagnostics(
10313        &mut self,
10314        source_kind: DiagnosticSourceKind,
10315        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10316        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10317        cx: &mut Context<Self>,
10318    ) -> Result<()> {
10319        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10320        let updates = lsp_diagnostics
10321            .into_iter()
10322            .filter_map(|update| {
10323                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10324                Some(DocumentDiagnosticsUpdate {
10325                    diagnostics: self.lsp_to_document_diagnostics(
10326                        abs_path,
10327                        source_kind,
10328                        update.server_id,
10329                        update.diagnostics,
10330                        &update.disk_based_sources,
10331                    ),
10332                    result_id: update.result_id,
10333                    server_id: update.server_id,
10334                    disk_based_sources: update.disk_based_sources,
10335                })
10336            })
10337            .collect();
10338        self.merge_diagnostic_entries(updates, merge, cx)?;
10339        Ok(())
10340    }
10341
10342    fn lsp_to_document_diagnostics(
10343        &mut self,
10344        document_abs_path: PathBuf,
10345        source_kind: DiagnosticSourceKind,
10346        server_id: LanguageServerId,
10347        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10348        disk_based_sources: &[String],
10349    ) -> DocumentDiagnostics {
10350        let mut diagnostics = Vec::default();
10351        let mut primary_diagnostic_group_ids = HashMap::default();
10352        let mut sources_by_group_id = HashMap::default();
10353        let mut supporting_diagnostics = HashMap::default();
10354
10355        let adapter = self.language_server_adapter_for_id(server_id);
10356
10357        // Ensure that primary diagnostics are always the most severe
10358        lsp_diagnostics
10359            .diagnostics
10360            .sort_by_key(|item| item.severity);
10361
10362        for diagnostic in &lsp_diagnostics.diagnostics {
10363            let source = diagnostic.source.as_ref();
10364            let range = range_from_lsp(diagnostic.range);
10365            let is_supporting = diagnostic
10366                .related_information
10367                .as_ref()
10368                .is_some_and(|infos| {
10369                    infos.iter().any(|info| {
10370                        primary_diagnostic_group_ids.contains_key(&(
10371                            source,
10372                            diagnostic.code.clone(),
10373                            range_from_lsp(info.location.range),
10374                        ))
10375                    })
10376                });
10377
10378            let is_unnecessary = diagnostic
10379                .tags
10380                .as_ref()
10381                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10382
10383            let underline = self
10384                .language_server_adapter_for_id(server_id)
10385                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10386
10387            if is_supporting {
10388                supporting_diagnostics.insert(
10389                    (source, diagnostic.code.clone(), range),
10390                    (diagnostic.severity, is_unnecessary),
10391                );
10392            } else {
10393                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10394                let is_disk_based =
10395                    source.is_some_and(|source| disk_based_sources.contains(source));
10396
10397                sources_by_group_id.insert(group_id, source);
10398                primary_diagnostic_group_ids
10399                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10400
10401                diagnostics.push(DiagnosticEntry {
10402                    range,
10403                    diagnostic: Diagnostic {
10404                        source: diagnostic.source.clone(),
10405                        source_kind,
10406                        code: diagnostic.code.clone(),
10407                        code_description: diagnostic
10408                            .code_description
10409                            .as_ref()
10410                            .and_then(|d| d.href.clone()),
10411                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10412                        markdown: adapter.as_ref().and_then(|adapter| {
10413                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10414                        }),
10415                        message: diagnostic.message.trim().to_string(),
10416                        group_id,
10417                        is_primary: true,
10418                        is_disk_based,
10419                        is_unnecessary,
10420                        underline,
10421                        data: diagnostic.data.clone(),
10422                    },
10423                });
10424                if let Some(infos) = &diagnostic.related_information {
10425                    for info in infos {
10426                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10427                            let range = range_from_lsp(info.location.range);
10428                            diagnostics.push(DiagnosticEntry {
10429                                range,
10430                                diagnostic: Diagnostic {
10431                                    source: diagnostic.source.clone(),
10432                                    source_kind,
10433                                    code: diagnostic.code.clone(),
10434                                    code_description: diagnostic
10435                                        .code_description
10436                                        .as_ref()
10437                                        .and_then(|d| d.href.clone()),
10438                                    severity: DiagnosticSeverity::INFORMATION,
10439                                    markdown: adapter.as_ref().and_then(|adapter| {
10440                                        adapter.diagnostic_message_to_markdown(&info.message)
10441                                    }),
10442                                    message: info.message.trim().to_string(),
10443                                    group_id,
10444                                    is_primary: false,
10445                                    is_disk_based,
10446                                    is_unnecessary: false,
10447                                    underline,
10448                                    data: diagnostic.data.clone(),
10449                                },
10450                            });
10451                        }
10452                    }
10453                }
10454            }
10455        }
10456
10457        for entry in &mut diagnostics {
10458            let diagnostic = &mut entry.diagnostic;
10459            if !diagnostic.is_primary {
10460                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10461                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10462                    source,
10463                    diagnostic.code.clone(),
10464                    entry.range.clone(),
10465                )) {
10466                    if let Some(severity) = severity {
10467                        diagnostic.severity = severity;
10468                    }
10469                    diagnostic.is_unnecessary = is_unnecessary;
10470                }
10471            }
10472        }
10473
10474        DocumentDiagnostics {
10475            diagnostics,
10476            document_abs_path,
10477            version: lsp_diagnostics.version,
10478        }
10479    }
10480
10481    fn insert_newly_running_language_server(
10482        &mut self,
10483        adapter: Arc<CachedLspAdapter>,
10484        language_server: Arc<LanguageServer>,
10485        server_id: LanguageServerId,
10486        key: LanguageServerSeed,
10487        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10488        cx: &mut Context<Self>,
10489    ) {
10490        let Some(local) = self.as_local_mut() else {
10491            return;
10492        };
10493        // If the language server for this key doesn't match the server id, don't store the
10494        // server. Which will cause it to be dropped, killing the process
10495        if local
10496            .language_server_ids
10497            .get(&key)
10498            .map(|state| state.id != server_id)
10499            .unwrap_or(false)
10500        {
10501            return;
10502        }
10503
10504        // Update language_servers collection with Running variant of LanguageServerState
10505        // indicating that the server is up and running and ready
10506        let workspace_folders = workspace_folders.lock().clone();
10507        language_server.set_workspace_folders(workspace_folders);
10508
10509        local.language_servers.insert(
10510            server_id,
10511            LanguageServerState::Running {
10512                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10513                    language_server.clone(),
10514                    cx,
10515                ),
10516                adapter: adapter.clone(),
10517                server: language_server.clone(),
10518                simulate_disk_based_diagnostics_completion: None,
10519            },
10520        );
10521        local
10522            .languages
10523            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10524        if let Some(file_ops_caps) = language_server
10525            .capabilities()
10526            .workspace
10527            .as_ref()
10528            .and_then(|ws| ws.file_operations.as_ref())
10529        {
10530            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10531            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10532            if did_rename_caps.or(will_rename_caps).is_some() {
10533                let watcher = RenamePathsWatchedForServer::default()
10534                    .with_did_rename_patterns(did_rename_caps)
10535                    .with_will_rename_patterns(will_rename_caps);
10536                local
10537                    .language_server_paths_watched_for_rename
10538                    .insert(server_id, watcher);
10539            }
10540        }
10541
10542        self.language_server_statuses.insert(
10543            server_id,
10544            LanguageServerStatus {
10545                name: language_server.name(),
10546                pending_work: Default::default(),
10547                has_pending_diagnostic_updates: false,
10548                progress_tokens: Default::default(),
10549                worktree: Some(key.worktree_id),
10550            },
10551        );
10552
10553        cx.emit(LspStoreEvent::LanguageServerAdded(
10554            server_id,
10555            language_server.name(),
10556            Some(key.worktree_id),
10557        ));
10558        cx.emit(LspStoreEvent::RefreshInlayHints);
10559
10560        let server_capabilities = language_server.capabilities();
10561        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10562            downstream_client
10563                .send(proto::StartLanguageServer {
10564                    project_id: *project_id,
10565                    server: Some(proto::LanguageServer {
10566                        id: server_id.to_proto(),
10567                        name: language_server.name().to_string(),
10568                        worktree_id: Some(key.worktree_id.to_proto()),
10569                    }),
10570                    capabilities: serde_json::to_string(&server_capabilities)
10571                        .expect("serializing server LSP capabilities"),
10572                })
10573                .log_err();
10574        }
10575        self.lsp_server_capabilities
10576            .insert(server_id, server_capabilities);
10577
10578        // Tell the language server about every open buffer in the worktree that matches the language.
10579        // Also check for buffers in worktrees that reused this server
10580        let mut worktrees_using_server = vec![key.worktree_id];
10581        if let Some(local) = self.as_local() {
10582            // Find all worktrees that have this server in their language server tree
10583            for (worktree_id, servers) in &local.lsp_tree.instances {
10584                if *worktree_id != key.worktree_id {
10585                    for server_map in servers.roots.values() {
10586                        if server_map
10587                            .values()
10588                            .any(|(node, _)| node.id() == Some(server_id))
10589                        {
10590                            worktrees_using_server.push(*worktree_id);
10591                        }
10592                    }
10593                }
10594            }
10595        }
10596
10597        let mut buffer_paths_registered = Vec::new();
10598        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10599            let mut lsp_adapters = HashMap::default();
10600            for buffer_handle in buffer_store.buffers() {
10601                let buffer = buffer_handle.read(cx);
10602                let file = match File::from_dyn(buffer.file()) {
10603                    Some(file) => file,
10604                    None => continue,
10605                };
10606                let language = match buffer.language() {
10607                    Some(language) => language,
10608                    None => continue,
10609                };
10610
10611                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10612                    || !lsp_adapters
10613                        .entry(language.name())
10614                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
10615                        .iter()
10616                        .any(|a| a.name == key.name)
10617                {
10618                    continue;
10619                }
10620                // didOpen
10621                let file = match file.as_local() {
10622                    Some(file) => file,
10623                    None => continue,
10624                };
10625
10626                let local = self.as_local_mut().unwrap();
10627
10628                let buffer_id = buffer.remote_id();
10629                if local.registered_buffers.contains_key(&buffer_id) {
10630                    let versions = local
10631                        .buffer_snapshots
10632                        .entry(buffer_id)
10633                        .or_default()
10634                        .entry(server_id)
10635                        .and_modify(|_| {
10636                            assert!(
10637                            false,
10638                            "There should not be an existing snapshot for a newly inserted buffer"
10639                        )
10640                        })
10641                        .or_insert_with(|| {
10642                            vec![LspBufferSnapshot {
10643                                version: 0,
10644                                snapshot: buffer.text_snapshot(),
10645                            }]
10646                        });
10647
10648                    let snapshot = versions.last().unwrap();
10649                    let version = snapshot.version;
10650                    let initial_snapshot = &snapshot.snapshot;
10651                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
10652                    language_server.register_buffer(
10653                        uri,
10654                        adapter.language_id(&language.name()),
10655                        version,
10656                        initial_snapshot.text(),
10657                    );
10658                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
10659                    local
10660                        .buffers_opened_in_servers
10661                        .entry(buffer_id)
10662                        .or_default()
10663                        .insert(server_id);
10664                }
10665                buffer_handle.update(cx, |buffer, cx| {
10666                    buffer.set_completion_triggers(
10667                        server_id,
10668                        language_server
10669                            .capabilities()
10670                            .completion_provider
10671                            .as_ref()
10672                            .and_then(|provider| {
10673                                provider
10674                                    .trigger_characters
10675                                    .as_ref()
10676                                    .map(|characters| characters.iter().cloned().collect())
10677                            })
10678                            .unwrap_or_default(),
10679                        cx,
10680                    )
10681                });
10682            }
10683        });
10684
10685        for (buffer_id, abs_path) in buffer_paths_registered {
10686            cx.emit(LspStoreEvent::LanguageServerUpdate {
10687                language_server_id: server_id,
10688                name: Some(adapter.name()),
10689                message: proto::update_language_server::Variant::RegisteredForBuffer(
10690                    proto::RegisteredForBuffer {
10691                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
10692                        buffer_id: buffer_id.to_proto(),
10693                    },
10694                ),
10695            });
10696        }
10697
10698        cx.notify();
10699    }
10700
10701    pub fn language_servers_running_disk_based_diagnostics(
10702        &self,
10703    ) -> impl Iterator<Item = LanguageServerId> + '_ {
10704        self.language_server_statuses
10705            .iter()
10706            .filter_map(|(id, status)| {
10707                if status.has_pending_diagnostic_updates {
10708                    Some(*id)
10709                } else {
10710                    None
10711                }
10712            })
10713    }
10714
10715    pub(crate) fn cancel_language_server_work_for_buffers(
10716        &mut self,
10717        buffers: impl IntoIterator<Item = Entity<Buffer>>,
10718        cx: &mut Context<Self>,
10719    ) {
10720        if let Some((client, project_id)) = self.upstream_client() {
10721            let request = client.request(proto::CancelLanguageServerWork {
10722                project_id,
10723                work: Some(proto::cancel_language_server_work::Work::Buffers(
10724                    proto::cancel_language_server_work::Buffers {
10725                        buffer_ids: buffers
10726                            .into_iter()
10727                            .map(|b| b.read(cx).remote_id().to_proto())
10728                            .collect(),
10729                    },
10730                )),
10731            });
10732            cx.background_spawn(request).detach_and_log_err(cx);
10733        } else if let Some(local) = self.as_local() {
10734            let servers = buffers
10735                .into_iter()
10736                .flat_map(|buffer| {
10737                    buffer.update(cx, |buffer, cx| {
10738                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
10739                    })
10740                })
10741                .collect::<HashSet<_>>();
10742            for server_id in servers {
10743                self.cancel_language_server_work(server_id, None, cx);
10744            }
10745        }
10746    }
10747
10748    pub(crate) fn cancel_language_server_work(
10749        &mut self,
10750        server_id: LanguageServerId,
10751        token_to_cancel: Option<String>,
10752        cx: &mut Context<Self>,
10753    ) {
10754        if let Some(local) = self.as_local() {
10755            let status = self.language_server_statuses.get(&server_id);
10756            let server = local.language_servers.get(&server_id);
10757            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
10758            {
10759                for (token, progress) in &status.pending_work {
10760                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
10761                        && token != token_to_cancel
10762                    {
10763                        continue;
10764                    }
10765                    if progress.is_cancellable {
10766                        server
10767                            .notify::<lsp::notification::WorkDoneProgressCancel>(
10768                                &WorkDoneProgressCancelParams {
10769                                    token: lsp::NumberOrString::String(token.clone()),
10770                                },
10771                            )
10772                            .ok();
10773                    }
10774                }
10775            }
10776        } else if let Some((client, project_id)) = self.upstream_client() {
10777            let request = client.request(proto::CancelLanguageServerWork {
10778                project_id,
10779                work: Some(
10780                    proto::cancel_language_server_work::Work::LanguageServerWork(
10781                        proto::cancel_language_server_work::LanguageServerWork {
10782                            language_server_id: server_id.to_proto(),
10783                            token: token_to_cancel,
10784                        },
10785                    ),
10786                ),
10787            });
10788            cx.background_spawn(request).detach_and_log_err(cx);
10789        }
10790    }
10791
10792    fn register_supplementary_language_server(
10793        &mut self,
10794        id: LanguageServerId,
10795        name: LanguageServerName,
10796        server: Arc<LanguageServer>,
10797        cx: &mut Context<Self>,
10798    ) {
10799        if let Some(local) = self.as_local_mut() {
10800            local
10801                .supplementary_language_servers
10802                .insert(id, (name.clone(), server));
10803            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
10804        }
10805    }
10806
10807    fn unregister_supplementary_language_server(
10808        &mut self,
10809        id: LanguageServerId,
10810        cx: &mut Context<Self>,
10811    ) {
10812        if let Some(local) = self.as_local_mut() {
10813            local.supplementary_language_servers.remove(&id);
10814            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
10815        }
10816    }
10817
10818    pub(crate) fn supplementary_language_servers(
10819        &self,
10820    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
10821        self.as_local().into_iter().flat_map(|local| {
10822            local
10823                .supplementary_language_servers
10824                .iter()
10825                .map(|(id, (name, _))| (*id, name.clone()))
10826        })
10827    }
10828
10829    pub fn language_server_adapter_for_id(
10830        &self,
10831        id: LanguageServerId,
10832    ) -> Option<Arc<CachedLspAdapter>> {
10833        self.as_local()
10834            .and_then(|local| local.language_servers.get(&id))
10835            .and_then(|language_server_state| match language_server_state {
10836                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
10837                _ => None,
10838            })
10839    }
10840
10841    pub(super) fn update_local_worktree_language_servers(
10842        &mut self,
10843        worktree_handle: &Entity<Worktree>,
10844        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
10845        cx: &mut Context<Self>,
10846    ) {
10847        if changes.is_empty() {
10848            return;
10849        }
10850
10851        let Some(local) = self.as_local() else { return };
10852
10853        local.prettier_store.update(cx, |prettier_store, cx| {
10854            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
10855        });
10856
10857        let worktree_id = worktree_handle.read(cx).id();
10858        let mut language_server_ids = local
10859            .language_server_ids
10860            .iter()
10861            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
10862            .collect::<Vec<_>>();
10863        language_server_ids.sort();
10864        language_server_ids.dedup();
10865
10866        // let abs_path = worktree_handle.read(cx).abs_path();
10867        for server_id in &language_server_ids {
10868            if let Some(LanguageServerState::Running { server, .. }) =
10869                local.language_servers.get(server_id)
10870                && let Some(watched_paths) = local
10871                    .language_server_watched_paths
10872                    .get(server_id)
10873                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
10874            {
10875                let params = lsp::DidChangeWatchedFilesParams {
10876                    changes: changes
10877                        .iter()
10878                        .filter_map(|(path, _, change)| {
10879                            if !watched_paths.is_match(path.as_std_path()) {
10880                                return None;
10881                            }
10882                            let typ = match change {
10883                                PathChange::Loaded => return None,
10884                                PathChange::Added => lsp::FileChangeType::CREATED,
10885                                PathChange::Removed => lsp::FileChangeType::DELETED,
10886                                PathChange::Updated => lsp::FileChangeType::CHANGED,
10887                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
10888                            };
10889                            let uri = lsp::Uri::from_file_path(
10890                                worktree_handle.read(cx).absolutize(&path),
10891                            )
10892                            .ok()?;
10893                            Some(lsp::FileEvent { uri, typ })
10894                        })
10895                        .collect(),
10896                };
10897                if !params.changes.is_empty() {
10898                    server
10899                        .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
10900                        .ok();
10901                }
10902            }
10903        }
10904        for (path, _, _) in changes {
10905            if let Some(file_name) = path.file_name()
10906                && local.watched_manifest_filenames.contains(file_name)
10907            {
10908                self.request_workspace_config_refresh();
10909                break;
10910            }
10911        }
10912    }
10913
10914    pub fn wait_for_remote_buffer(
10915        &mut self,
10916        id: BufferId,
10917        cx: &mut Context<Self>,
10918    ) -> Task<Result<Entity<Buffer>>> {
10919        self.buffer_store.update(cx, |buffer_store, cx| {
10920            buffer_store.wait_for_remote_buffer(id, cx)
10921        })
10922    }
10923
10924    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
10925        let mut result = proto::Symbol {
10926            language_server_name: symbol.language_server_name.0.to_string(),
10927            source_worktree_id: symbol.source_worktree_id.to_proto(),
10928            language_server_id: symbol.source_language_server_id.to_proto(),
10929            name: symbol.name.clone(),
10930            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
10931            start: Some(proto::PointUtf16 {
10932                row: symbol.range.start.0.row,
10933                column: symbol.range.start.0.column,
10934            }),
10935            end: Some(proto::PointUtf16 {
10936                row: symbol.range.end.0.row,
10937                column: symbol.range.end.0.column,
10938            }),
10939            worktree_id: Default::default(),
10940            path: Default::default(),
10941            signature: Default::default(),
10942        };
10943        match &symbol.path {
10944            SymbolLocation::InProject(path) => {
10945                result.worktree_id = path.worktree_id.to_proto();
10946                result.path = path.path.to_proto();
10947            }
10948            SymbolLocation::OutsideProject {
10949                abs_path,
10950                signature,
10951            } => {
10952                result.path = abs_path.to_string_lossy().to_string();
10953                result.signature = signature.to_vec();
10954            }
10955        }
10956        result
10957    }
10958
10959    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
10960        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
10961        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
10962        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
10963
10964        let path = if serialized_symbol.signature.is_empty() {
10965            SymbolLocation::InProject(ProjectPath {
10966                worktree_id,
10967                path: RelPath::from_proto(&serialized_symbol.path)
10968                    .context("invalid symbol path")?,
10969            })
10970        } else {
10971            SymbolLocation::OutsideProject {
10972                abs_path: Path::new(&serialized_symbol.path).into(),
10973                signature: serialized_symbol
10974                    .signature
10975                    .try_into()
10976                    .map_err(|_| anyhow!("invalid signature"))?,
10977            }
10978        };
10979
10980        let start = serialized_symbol.start.context("invalid start")?;
10981        let end = serialized_symbol.end.context("invalid end")?;
10982        Ok(CoreSymbol {
10983            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
10984            source_worktree_id,
10985            source_language_server_id: LanguageServerId::from_proto(
10986                serialized_symbol.language_server_id,
10987            ),
10988            path,
10989            name: serialized_symbol.name,
10990            range: Unclipped(PointUtf16::new(start.row, start.column))
10991                ..Unclipped(PointUtf16::new(end.row, end.column)),
10992            kind,
10993        })
10994    }
10995
10996    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
10997        let mut serialized_completion = proto::Completion {
10998            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
10999            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11000            new_text: completion.new_text.clone(),
11001            ..proto::Completion::default()
11002        };
11003        match &completion.source {
11004            CompletionSource::Lsp {
11005                insert_range,
11006                server_id,
11007                lsp_completion,
11008                lsp_defaults,
11009                resolved,
11010            } => {
11011                let (old_insert_start, old_insert_end) = insert_range
11012                    .as_ref()
11013                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11014                    .unzip();
11015
11016                serialized_completion.old_insert_start = old_insert_start;
11017                serialized_completion.old_insert_end = old_insert_end;
11018                serialized_completion.source = proto::completion::Source::Lsp as i32;
11019                serialized_completion.server_id = server_id.0 as u64;
11020                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11021                serialized_completion.lsp_defaults = lsp_defaults
11022                    .as_deref()
11023                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11024                serialized_completion.resolved = *resolved;
11025            }
11026            CompletionSource::BufferWord {
11027                word_range,
11028                resolved,
11029            } => {
11030                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11031                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11032                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11033                serialized_completion.resolved = *resolved;
11034            }
11035            CompletionSource::Custom => {
11036                serialized_completion.source = proto::completion::Source::Custom as i32;
11037                serialized_completion.resolved = true;
11038            }
11039            CompletionSource::Dap { sort_text } => {
11040                serialized_completion.source = proto::completion::Source::Dap as i32;
11041                serialized_completion.sort_text = Some(sort_text.clone());
11042            }
11043        }
11044
11045        serialized_completion
11046    }
11047
11048    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11049        let old_replace_start = completion
11050            .old_replace_start
11051            .and_then(deserialize_anchor)
11052            .context("invalid old start")?;
11053        let old_replace_end = completion
11054            .old_replace_end
11055            .and_then(deserialize_anchor)
11056            .context("invalid old end")?;
11057        let insert_range = {
11058            match completion.old_insert_start.zip(completion.old_insert_end) {
11059                Some((start, end)) => {
11060                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11061                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11062                    Some(start..end)
11063                }
11064                None => None,
11065            }
11066        };
11067        Ok(CoreCompletion {
11068            replace_range: old_replace_start..old_replace_end,
11069            new_text: completion.new_text,
11070            source: match proto::completion::Source::from_i32(completion.source) {
11071                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11072                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11073                    insert_range,
11074                    server_id: LanguageServerId::from_proto(completion.server_id),
11075                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11076                    lsp_defaults: completion
11077                        .lsp_defaults
11078                        .as_deref()
11079                        .map(serde_json::from_slice)
11080                        .transpose()?,
11081                    resolved: completion.resolved,
11082                },
11083                Some(proto::completion::Source::BufferWord) => {
11084                    let word_range = completion
11085                        .buffer_word_start
11086                        .and_then(deserialize_anchor)
11087                        .context("invalid buffer word start")?
11088                        ..completion
11089                            .buffer_word_end
11090                            .and_then(deserialize_anchor)
11091                            .context("invalid buffer word end")?;
11092                    CompletionSource::BufferWord {
11093                        word_range,
11094                        resolved: completion.resolved,
11095                    }
11096                }
11097                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11098                    sort_text: completion
11099                        .sort_text
11100                        .context("expected sort text to exist")?,
11101                },
11102                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11103            },
11104        })
11105    }
11106
11107    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11108        let (kind, lsp_action) = match &action.lsp_action {
11109            LspAction::Action(code_action) => (
11110                proto::code_action::Kind::Action as i32,
11111                serde_json::to_vec(code_action).unwrap(),
11112            ),
11113            LspAction::Command(command) => (
11114                proto::code_action::Kind::Command as i32,
11115                serde_json::to_vec(command).unwrap(),
11116            ),
11117            LspAction::CodeLens(code_lens) => (
11118                proto::code_action::Kind::CodeLens as i32,
11119                serde_json::to_vec(code_lens).unwrap(),
11120            ),
11121        };
11122
11123        proto::CodeAction {
11124            server_id: action.server_id.0 as u64,
11125            start: Some(serialize_anchor(&action.range.start)),
11126            end: Some(serialize_anchor(&action.range.end)),
11127            lsp_action,
11128            kind,
11129            resolved: action.resolved,
11130        }
11131    }
11132
11133    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11134        let start = action
11135            .start
11136            .and_then(deserialize_anchor)
11137            .context("invalid start")?;
11138        let end = action
11139            .end
11140            .and_then(deserialize_anchor)
11141            .context("invalid end")?;
11142        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11143            Some(proto::code_action::Kind::Action) => {
11144                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11145            }
11146            Some(proto::code_action::Kind::Command) => {
11147                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11148            }
11149            Some(proto::code_action::Kind::CodeLens) => {
11150                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11151            }
11152            None => anyhow::bail!("Unknown action kind {}", action.kind),
11153        };
11154        Ok(CodeAction {
11155            server_id: LanguageServerId(action.server_id as usize),
11156            range: start..end,
11157            resolved: action.resolved,
11158            lsp_action,
11159        })
11160    }
11161
11162    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11163        match &formatting_result {
11164            Ok(_) => self.last_formatting_failure = None,
11165            Err(error) => {
11166                let error_string = format!("{error:#}");
11167                log::error!("Formatting failed: {error_string}");
11168                self.last_formatting_failure
11169                    .replace(error_string.lines().join(" "));
11170            }
11171        }
11172    }
11173
11174    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11175        self.lsp_server_capabilities.remove(&for_server);
11176        for buffer_colors in self.lsp_document_colors.values_mut() {
11177            buffer_colors.colors.remove(&for_server);
11178            buffer_colors.cache_version += 1;
11179        }
11180        for buffer_lens in self.lsp_code_lens.values_mut() {
11181            buffer_lens.lens.remove(&for_server);
11182        }
11183        if let Some(local) = self.as_local_mut() {
11184            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11185            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11186                buffer_servers.remove(&for_server);
11187            }
11188        }
11189    }
11190
11191    pub fn result_id(
11192        &self,
11193        server_id: LanguageServerId,
11194        buffer_id: BufferId,
11195        cx: &App,
11196    ) -> Option<String> {
11197        let abs_path = self
11198            .buffer_store
11199            .read(cx)
11200            .get(buffer_id)
11201            .and_then(|b| File::from_dyn(b.read(cx).file()))
11202            .map(|f| f.abs_path(cx))?;
11203        self.as_local()?
11204            .buffer_pull_diagnostics_result_ids
11205            .get(&server_id)?
11206            .get(&abs_path)?
11207            .clone()
11208    }
11209
11210    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11211        let Some(local) = self.as_local() else {
11212            return HashMap::default();
11213        };
11214        local
11215            .buffer_pull_diagnostics_result_ids
11216            .get(&server_id)
11217            .into_iter()
11218            .flatten()
11219            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11220            .collect()
11221    }
11222
11223    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11224        if let Some(LanguageServerState::Running {
11225            workspace_refresh_task: Some(workspace_refresh_task),
11226            ..
11227        }) = self
11228            .as_local_mut()
11229            .and_then(|local| local.language_servers.get_mut(&server_id))
11230        {
11231            workspace_refresh_task.refresh_tx.try_send(()).ok();
11232        }
11233    }
11234
11235    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11236        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11237            return;
11238        };
11239        let Some(local) = self.as_local_mut() else {
11240            return;
11241        };
11242
11243        for server_id in buffer.update(cx, |buffer, cx| {
11244            local.language_server_ids_for_buffer(buffer, cx)
11245        }) {
11246            if let Some(LanguageServerState::Running {
11247                workspace_refresh_task: Some(workspace_refresh_task),
11248                ..
11249            }) = local.language_servers.get_mut(&server_id)
11250            {
11251                workspace_refresh_task.refresh_tx.try_send(()).ok();
11252            }
11253        }
11254    }
11255
11256    fn apply_workspace_diagnostic_report(
11257        &mut self,
11258        server_id: LanguageServerId,
11259        report: lsp::WorkspaceDiagnosticReportResult,
11260        cx: &mut Context<Self>,
11261    ) {
11262        let workspace_diagnostics =
11263            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11264        let mut unchanged_buffers = HashSet::default();
11265        let mut changed_buffers = HashSet::default();
11266        let workspace_diagnostics_updates = workspace_diagnostics
11267            .into_iter()
11268            .filter_map(
11269                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11270                    LspPullDiagnostics::Response {
11271                        server_id,
11272                        uri,
11273                        diagnostics,
11274                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11275                    LspPullDiagnostics::Default => None,
11276                },
11277            )
11278            .fold(
11279                HashMap::default(),
11280                |mut acc, (server_id, uri, diagnostics, version)| {
11281                    let (result_id, diagnostics) = match diagnostics {
11282                        PulledDiagnostics::Unchanged { result_id } => {
11283                            unchanged_buffers.insert(uri.clone());
11284                            (Some(result_id), Vec::new())
11285                        }
11286                        PulledDiagnostics::Changed {
11287                            result_id,
11288                            diagnostics,
11289                        } => {
11290                            changed_buffers.insert(uri.clone());
11291                            (result_id, diagnostics)
11292                        }
11293                    };
11294                    let disk_based_sources = Cow::Owned(
11295                        self.language_server_adapter_for_id(server_id)
11296                            .as_ref()
11297                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11298                            .unwrap_or(&[])
11299                            .to_vec(),
11300                    );
11301                    acc.entry(server_id)
11302                        .or_insert_with(Vec::new)
11303                        .push(DocumentDiagnosticsUpdate {
11304                            server_id,
11305                            diagnostics: lsp::PublishDiagnosticsParams {
11306                                uri,
11307                                diagnostics,
11308                                version,
11309                            },
11310                            result_id,
11311                            disk_based_sources,
11312                        });
11313                    acc
11314                },
11315            );
11316
11317        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11318            self.merge_lsp_diagnostics(
11319                DiagnosticSourceKind::Pulled,
11320                diagnostic_updates,
11321                |buffer, old_diagnostic, cx| {
11322                    File::from_dyn(buffer.file())
11323                        .and_then(|file| {
11324                            let abs_path = file.as_local()?.abs_path(cx);
11325                            lsp::Uri::from_file_path(abs_path).ok()
11326                        })
11327                        .is_none_or(|buffer_uri| {
11328                            unchanged_buffers.contains(&buffer_uri)
11329                                || match old_diagnostic.source_kind {
11330                                    DiagnosticSourceKind::Pulled => {
11331                                        !changed_buffers.contains(&buffer_uri)
11332                                    }
11333                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11334                                        true
11335                                    }
11336                                }
11337                        })
11338                },
11339                cx,
11340            )
11341            .log_err();
11342        }
11343    }
11344
11345    fn register_server_capabilities(
11346        &mut self,
11347        server_id: LanguageServerId,
11348        params: lsp::RegistrationParams,
11349        cx: &mut Context<Self>,
11350    ) -> anyhow::Result<()> {
11351        let server = self
11352            .language_server_for_id(server_id)
11353            .with_context(|| format!("no server {server_id} found"))?;
11354        for reg in params.registrations {
11355            match reg.method.as_str() {
11356                "workspace/didChangeWatchedFiles" => {
11357                    if let Some(options) = reg.register_options {
11358                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11359                            let caps = serde_json::from_value(options)?;
11360                            local_lsp_store
11361                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11362                            true
11363                        } else {
11364                            false
11365                        };
11366                        if notify {
11367                            notify_server_capabilities_updated(&server, cx);
11368                        }
11369                    }
11370                }
11371                "workspace/didChangeConfiguration" => {
11372                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11373                }
11374                "workspace/didChangeWorkspaceFolders" => {
11375                    // In this case register options is an empty object, we can ignore it
11376                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11377                        supported: Some(true),
11378                        change_notifications: Some(OneOf::Right(reg.id)),
11379                    };
11380                    server.update_capabilities(|capabilities| {
11381                        capabilities
11382                            .workspace
11383                            .get_or_insert_default()
11384                            .workspace_folders = Some(caps);
11385                    });
11386                    notify_server_capabilities_updated(&server, cx);
11387                }
11388                "workspace/symbol" => {
11389                    let options = parse_register_capabilities(reg)?;
11390                    server.update_capabilities(|capabilities| {
11391                        capabilities.workspace_symbol_provider = Some(options);
11392                    });
11393                    notify_server_capabilities_updated(&server, cx);
11394                }
11395                "workspace/fileOperations" => {
11396                    if let Some(options) = reg.register_options {
11397                        let caps = serde_json::from_value(options)?;
11398                        server.update_capabilities(|capabilities| {
11399                            capabilities
11400                                .workspace
11401                                .get_or_insert_default()
11402                                .file_operations = Some(caps);
11403                        });
11404                        notify_server_capabilities_updated(&server, cx);
11405                    }
11406                }
11407                "workspace/executeCommand" => {
11408                    if let Some(options) = reg.register_options {
11409                        let options = serde_json::from_value(options)?;
11410                        server.update_capabilities(|capabilities| {
11411                            capabilities.execute_command_provider = Some(options);
11412                        });
11413                        notify_server_capabilities_updated(&server, cx);
11414                    }
11415                }
11416                "textDocument/rangeFormatting" => {
11417                    let options = parse_register_capabilities(reg)?;
11418                    server.update_capabilities(|capabilities| {
11419                        capabilities.document_range_formatting_provider = Some(options);
11420                    });
11421                    notify_server_capabilities_updated(&server, cx);
11422                }
11423                "textDocument/onTypeFormatting" => {
11424                    if let Some(options) = reg
11425                        .register_options
11426                        .map(serde_json::from_value)
11427                        .transpose()?
11428                    {
11429                        server.update_capabilities(|capabilities| {
11430                            capabilities.document_on_type_formatting_provider = Some(options);
11431                        });
11432                        notify_server_capabilities_updated(&server, cx);
11433                    }
11434                }
11435                "textDocument/formatting" => {
11436                    let options = parse_register_capabilities(reg)?;
11437                    server.update_capabilities(|capabilities| {
11438                        capabilities.document_formatting_provider = Some(options);
11439                    });
11440                    notify_server_capabilities_updated(&server, cx);
11441                }
11442                "textDocument/rename" => {
11443                    let options = parse_register_capabilities(reg)?;
11444                    server.update_capabilities(|capabilities| {
11445                        capabilities.rename_provider = Some(options);
11446                    });
11447                    notify_server_capabilities_updated(&server, cx);
11448                }
11449                "textDocument/inlayHint" => {
11450                    let options = parse_register_capabilities(reg)?;
11451                    server.update_capabilities(|capabilities| {
11452                        capabilities.inlay_hint_provider = Some(options);
11453                    });
11454                    notify_server_capabilities_updated(&server, cx);
11455                }
11456                "textDocument/documentSymbol" => {
11457                    let options = parse_register_capabilities(reg)?;
11458                    server.update_capabilities(|capabilities| {
11459                        capabilities.document_symbol_provider = Some(options);
11460                    });
11461                    notify_server_capabilities_updated(&server, cx);
11462                }
11463                "textDocument/codeAction" => {
11464                    let options = parse_register_capabilities(reg)?;
11465                    let provider = match options {
11466                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11467                        OneOf::Right(caps) => caps,
11468                    };
11469                    server.update_capabilities(|capabilities| {
11470                        capabilities.code_action_provider = Some(provider);
11471                    });
11472                    notify_server_capabilities_updated(&server, cx);
11473                }
11474                "textDocument/definition" => {
11475                    let options = parse_register_capabilities(reg)?;
11476                    server.update_capabilities(|capabilities| {
11477                        capabilities.definition_provider = Some(options);
11478                    });
11479                    notify_server_capabilities_updated(&server, cx);
11480                }
11481                "textDocument/completion" => {
11482                    if let Some(caps) = reg
11483                        .register_options
11484                        .map(serde_json::from_value)
11485                        .transpose()?
11486                    {
11487                        server.update_capabilities(|capabilities| {
11488                            capabilities.completion_provider = Some(caps);
11489                        });
11490                        notify_server_capabilities_updated(&server, cx);
11491                    }
11492                }
11493                "textDocument/hover" => {
11494                    let options = parse_register_capabilities(reg)?;
11495                    let provider = match options {
11496                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11497                        OneOf::Right(caps) => caps,
11498                    };
11499                    server.update_capabilities(|capabilities| {
11500                        capabilities.hover_provider = Some(provider);
11501                    });
11502                    notify_server_capabilities_updated(&server, cx);
11503                }
11504                "textDocument/signatureHelp" => {
11505                    if let Some(caps) = reg
11506                        .register_options
11507                        .map(serde_json::from_value)
11508                        .transpose()?
11509                    {
11510                        server.update_capabilities(|capabilities| {
11511                            capabilities.signature_help_provider = Some(caps);
11512                        });
11513                        notify_server_capabilities_updated(&server, cx);
11514                    }
11515                }
11516                "textDocument/didChange" => {
11517                    if let Some(sync_kind) = reg
11518                        .register_options
11519                        .and_then(|opts| opts.get("syncKind").cloned())
11520                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11521                        .transpose()?
11522                    {
11523                        server.update_capabilities(|capabilities| {
11524                            let mut sync_options =
11525                                Self::take_text_document_sync_options(capabilities);
11526                            sync_options.change = Some(sync_kind);
11527                            capabilities.text_document_sync =
11528                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11529                        });
11530                        notify_server_capabilities_updated(&server, cx);
11531                    }
11532                }
11533                "textDocument/didSave" => {
11534                    if let Some(include_text) = reg
11535                        .register_options
11536                        .map(|opts| {
11537                            let transpose = opts
11538                                .get("includeText")
11539                                .cloned()
11540                                .map(serde_json::from_value::<Option<bool>>)
11541                                .transpose();
11542                            match transpose {
11543                                Ok(value) => Ok(value.flatten()),
11544                                Err(e) => Err(e),
11545                            }
11546                        })
11547                        .transpose()?
11548                    {
11549                        server.update_capabilities(|capabilities| {
11550                            let mut sync_options =
11551                                Self::take_text_document_sync_options(capabilities);
11552                            sync_options.save =
11553                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11554                                    include_text,
11555                                }));
11556                            capabilities.text_document_sync =
11557                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11558                        });
11559                        notify_server_capabilities_updated(&server, cx);
11560                    }
11561                }
11562                "textDocument/codeLens" => {
11563                    if let Some(caps) = reg
11564                        .register_options
11565                        .map(serde_json::from_value)
11566                        .transpose()?
11567                    {
11568                        server.update_capabilities(|capabilities| {
11569                            capabilities.code_lens_provider = Some(caps);
11570                        });
11571                        notify_server_capabilities_updated(&server, cx);
11572                    }
11573                }
11574                "textDocument/diagnostic" => {
11575                    if let Some(caps) = reg
11576                        .register_options
11577                        .map(serde_json::from_value)
11578                        .transpose()?
11579                    {
11580                        server.update_capabilities(|capabilities| {
11581                            capabilities.diagnostic_provider = Some(caps);
11582                        });
11583                        notify_server_capabilities_updated(&server, cx);
11584                    }
11585                }
11586                "textDocument/documentColor" => {
11587                    let options = parse_register_capabilities(reg)?;
11588                    let provider = match options {
11589                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
11590                        OneOf::Right(caps) => caps,
11591                    };
11592                    server.update_capabilities(|capabilities| {
11593                        capabilities.color_provider = Some(provider);
11594                    });
11595                    notify_server_capabilities_updated(&server, cx);
11596                }
11597                _ => log::warn!("unhandled capability registration: {reg:?}"),
11598            }
11599        }
11600
11601        Ok(())
11602    }
11603
11604    fn unregister_server_capabilities(
11605        &mut self,
11606        server_id: LanguageServerId,
11607        params: lsp::UnregistrationParams,
11608        cx: &mut Context<Self>,
11609    ) -> anyhow::Result<()> {
11610        let server = self
11611            .language_server_for_id(server_id)
11612            .with_context(|| format!("no server {server_id} found"))?;
11613        for unreg in params.unregisterations.iter() {
11614            match unreg.method.as_str() {
11615                "workspace/didChangeWatchedFiles" => {
11616                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11617                        local_lsp_store
11618                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11619                        true
11620                    } else {
11621                        false
11622                    };
11623                    if notify {
11624                        notify_server_capabilities_updated(&server, cx);
11625                    }
11626                }
11627                "workspace/didChangeConfiguration" => {
11628                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11629                }
11630                "workspace/didChangeWorkspaceFolders" => {
11631                    server.update_capabilities(|capabilities| {
11632                        capabilities
11633                            .workspace
11634                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11635                                workspace_folders: None,
11636                                file_operations: None,
11637                            })
11638                            .workspace_folders = None;
11639                    });
11640                    notify_server_capabilities_updated(&server, cx);
11641                }
11642                "workspace/symbol" => {
11643                    server.update_capabilities(|capabilities| {
11644                        capabilities.workspace_symbol_provider = None
11645                    });
11646                    notify_server_capabilities_updated(&server, cx);
11647                }
11648                "workspace/fileOperations" => {
11649                    server.update_capabilities(|capabilities| {
11650                        capabilities
11651                            .workspace
11652                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11653                                workspace_folders: None,
11654                                file_operations: None,
11655                            })
11656                            .file_operations = None;
11657                    });
11658                    notify_server_capabilities_updated(&server, cx);
11659                }
11660                "workspace/executeCommand" => {
11661                    server.update_capabilities(|capabilities| {
11662                        capabilities.execute_command_provider = None;
11663                    });
11664                    notify_server_capabilities_updated(&server, cx);
11665                }
11666                "textDocument/rangeFormatting" => {
11667                    server.update_capabilities(|capabilities| {
11668                        capabilities.document_range_formatting_provider = None
11669                    });
11670                    notify_server_capabilities_updated(&server, cx);
11671                }
11672                "textDocument/onTypeFormatting" => {
11673                    server.update_capabilities(|capabilities| {
11674                        capabilities.document_on_type_formatting_provider = None;
11675                    });
11676                    notify_server_capabilities_updated(&server, cx);
11677                }
11678                "textDocument/formatting" => {
11679                    server.update_capabilities(|capabilities| {
11680                        capabilities.document_formatting_provider = None;
11681                    });
11682                    notify_server_capabilities_updated(&server, cx);
11683                }
11684                "textDocument/rename" => {
11685                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
11686                    notify_server_capabilities_updated(&server, cx);
11687                }
11688                "textDocument/codeAction" => {
11689                    server.update_capabilities(|capabilities| {
11690                        capabilities.code_action_provider = None;
11691                    });
11692                    notify_server_capabilities_updated(&server, cx);
11693                }
11694                "textDocument/definition" => {
11695                    server.update_capabilities(|capabilities| {
11696                        capabilities.definition_provider = None;
11697                    });
11698                    notify_server_capabilities_updated(&server, cx);
11699                }
11700                "textDocument/completion" => {
11701                    server.update_capabilities(|capabilities| {
11702                        capabilities.completion_provider = None;
11703                    });
11704                    notify_server_capabilities_updated(&server, cx);
11705                }
11706                "textDocument/hover" => {
11707                    server.update_capabilities(|capabilities| {
11708                        capabilities.hover_provider = None;
11709                    });
11710                    notify_server_capabilities_updated(&server, cx);
11711                }
11712                "textDocument/signatureHelp" => {
11713                    server.update_capabilities(|capabilities| {
11714                        capabilities.signature_help_provider = None;
11715                    });
11716                    notify_server_capabilities_updated(&server, cx);
11717                }
11718                "textDocument/didChange" => {
11719                    server.update_capabilities(|capabilities| {
11720                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11721                        sync_options.change = None;
11722                        capabilities.text_document_sync =
11723                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11724                    });
11725                    notify_server_capabilities_updated(&server, cx);
11726                }
11727                "textDocument/didSave" => {
11728                    server.update_capabilities(|capabilities| {
11729                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11730                        sync_options.save = None;
11731                        capabilities.text_document_sync =
11732                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11733                    });
11734                    notify_server_capabilities_updated(&server, cx);
11735                }
11736                "textDocument/codeLens" => {
11737                    server.update_capabilities(|capabilities| {
11738                        capabilities.code_lens_provider = None;
11739                    });
11740                    notify_server_capabilities_updated(&server, cx);
11741                }
11742                "textDocument/diagnostic" => {
11743                    server.update_capabilities(|capabilities| {
11744                        capabilities.diagnostic_provider = None;
11745                    });
11746                    notify_server_capabilities_updated(&server, cx);
11747                }
11748                "textDocument/documentColor" => {
11749                    server.update_capabilities(|capabilities| {
11750                        capabilities.color_provider = None;
11751                    });
11752                    notify_server_capabilities_updated(&server, cx);
11753                }
11754                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
11755            }
11756        }
11757
11758        Ok(())
11759    }
11760
11761    async fn query_lsp_locally<T>(
11762        lsp_store: Entity<Self>,
11763        sender_id: proto::PeerId,
11764        lsp_request_id: LspRequestId,
11765        proto_request: T::ProtoRequest,
11766        position: Option<Anchor>,
11767        mut cx: AsyncApp,
11768    ) -> Result<()>
11769    where
11770        T: LspCommand + Clone,
11771        T::ProtoRequest: proto::LspRequestMessage,
11772        <T::ProtoRequest as proto::RequestMessage>::Response:
11773            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
11774    {
11775        let buffer_id = BufferId::new(proto_request.buffer_id())?;
11776        let version = deserialize_version(proto_request.buffer_version());
11777        let buffer = lsp_store.update(&mut cx, |this, cx| {
11778            this.buffer_store.read(cx).get_existing(buffer_id)
11779        })??;
11780        buffer
11781            .update(&mut cx, |buffer, _| {
11782                buffer.wait_for_version(version.clone())
11783            })?
11784            .await?;
11785        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
11786        let request =
11787            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
11788        lsp_store.update(&mut cx, |lsp_store, cx| {
11789            let request_task =
11790                lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx);
11791            let existing_queries = lsp_store
11792                .running_lsp_requests
11793                .entry(TypeId::of::<T>())
11794                .or_default();
11795            if T::ProtoRequest::stop_previous_requests()
11796                || buffer_version.changed_since(&existing_queries.0)
11797            {
11798                existing_queries.1.clear();
11799            }
11800            existing_queries.1.insert(
11801                lsp_request_id,
11802                cx.spawn(async move |lsp_store, cx| {
11803                    let response = request_task.await;
11804                    lsp_store
11805                        .update(cx, |lsp_store, cx| {
11806                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
11807                            {
11808                                let response = response
11809                                    .into_iter()
11810                                    .map(|(server_id, response)| {
11811                                        (
11812                                            server_id.to_proto(),
11813                                            T::response_to_proto(
11814                                                response,
11815                                                lsp_store,
11816                                                sender_id,
11817                                                &buffer_version,
11818                                                cx,
11819                                            )
11820                                            .into(),
11821                                        )
11822                                    })
11823                                    .collect::<HashMap<_, _>>();
11824                                match client.send_lsp_response::<T::ProtoRequest>(
11825                                    project_id,
11826                                    lsp_request_id,
11827                                    response,
11828                                ) {
11829                                    Ok(()) => {}
11830                                    Err(e) => {
11831                                        log::error!("Failed to send LSP response: {e:#}",)
11832                                    }
11833                                }
11834                            }
11835                        })
11836                        .ok();
11837                }),
11838            );
11839        })?;
11840        Ok(())
11841    }
11842
11843    fn take_text_document_sync_options(
11844        capabilities: &mut lsp::ServerCapabilities,
11845    ) -> lsp::TextDocumentSyncOptions {
11846        match capabilities.text_document_sync.take() {
11847            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
11848            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
11849                let mut sync_options = lsp::TextDocumentSyncOptions::default();
11850                sync_options.change = Some(sync_kind);
11851                sync_options
11852            }
11853            None => lsp::TextDocumentSyncOptions::default(),
11854        }
11855    }
11856
11857    #[cfg(any(test, feature = "test-support"))]
11858    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
11859        let data = self.lsp_code_lens.get_mut(&buffer_id)?;
11860        Some(data.update.take()?.1)
11861    }
11862
11863    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
11864        self.downstream_client.clone()
11865    }
11866
11867    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
11868        self.worktree_store.clone()
11869    }
11870}
11871
11872// Registration with registerOptions as null, should fallback to true.
11873// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
11874fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
11875    reg: lsp::Registration,
11876) -> Result<OneOf<bool, T>> {
11877    Ok(match reg.register_options {
11878        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
11879        None => OneOf::Left(true),
11880    })
11881}
11882
11883fn subscribe_to_binary_statuses(
11884    languages: &Arc<LanguageRegistry>,
11885    cx: &mut Context<'_, LspStore>,
11886) -> Task<()> {
11887    let mut server_statuses = languages.language_server_binary_statuses();
11888    cx.spawn(async move |lsp_store, cx| {
11889        while let Some((server_name, binary_status)) = server_statuses.next().await {
11890            if lsp_store
11891                .update(cx, |_, cx| {
11892                    let mut message = None;
11893                    let binary_status = match binary_status {
11894                        BinaryStatus::None => proto::ServerBinaryStatus::None,
11895                        BinaryStatus::CheckingForUpdate => {
11896                            proto::ServerBinaryStatus::CheckingForUpdate
11897                        }
11898                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
11899                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
11900                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
11901                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
11902                        BinaryStatus::Failed { error } => {
11903                            message = Some(error);
11904                            proto::ServerBinaryStatus::Failed
11905                        }
11906                    };
11907                    cx.emit(LspStoreEvent::LanguageServerUpdate {
11908                        // Binary updates are about the binary that might not have any language server id at that point.
11909                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
11910                        language_server_id: LanguageServerId(0),
11911                        name: Some(server_name),
11912                        message: proto::update_language_server::Variant::StatusUpdate(
11913                            proto::StatusUpdate {
11914                                message,
11915                                status: Some(proto::status_update::Status::Binary(
11916                                    binary_status as i32,
11917                                )),
11918                            },
11919                        ),
11920                    });
11921                })
11922                .is_err()
11923            {
11924                break;
11925            }
11926        }
11927    })
11928}
11929
11930fn lsp_workspace_diagnostics_refresh(
11931    server: Arc<LanguageServer>,
11932    cx: &mut Context<'_, LspStore>,
11933) -> Option<WorkspaceRefreshTask> {
11934    let identifier = match server.capabilities().diagnostic_provider? {
11935        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
11936            if !diagnostic_options.workspace_diagnostics {
11937                return None;
11938            }
11939            diagnostic_options.identifier
11940        }
11941        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
11942            let diagnostic_options = registration_options.diagnostic_options;
11943            if !diagnostic_options.workspace_diagnostics {
11944                return None;
11945            }
11946            diagnostic_options.identifier
11947        }
11948    };
11949
11950    let (progress_tx, mut progress_rx) = mpsc::channel(1);
11951    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
11952    refresh_tx.try_send(()).ok();
11953
11954    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
11955        let mut attempts = 0;
11956        let max_attempts = 50;
11957        let mut requests = 0;
11958
11959        loop {
11960            let Some(()) = refresh_rx.recv().await else {
11961                return;
11962            };
11963
11964            'request: loop {
11965                requests += 1;
11966                if attempts > max_attempts {
11967                    log::error!(
11968                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
11969                    );
11970                    return;
11971                }
11972                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
11973                cx.background_executor()
11974                    .timer(Duration::from_millis(backoff_millis))
11975                    .await;
11976                attempts += 1;
11977
11978                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
11979                    lsp_store
11980                        .all_result_ids(server.server_id())
11981                        .into_iter()
11982                        .filter_map(|(abs_path, result_id)| {
11983                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
11984                            Some(lsp::PreviousResultId {
11985                                uri,
11986                                value: result_id,
11987                            })
11988                        })
11989                        .collect()
11990                }) else {
11991                    return;
11992                };
11993
11994                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
11995
11996                progress_rx.try_recv().ok();
11997                let timer =
11998                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
11999                let progress = pin!(progress_rx.recv().fuse());
12000                let response_result = server
12001                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12002                        lsp::WorkspaceDiagnosticParams {
12003                            previous_result_ids,
12004                            identifier: identifier.clone(),
12005                            work_done_progress_params: Default::default(),
12006                            partial_result_params: lsp::PartialResultParams {
12007                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12008                            },
12009                        },
12010                        select(timer, progress).then(|either| match either {
12011                            Either::Left((message, ..)) => ready(message).left_future(),
12012                            Either::Right(..) => pending::<String>().right_future(),
12013                        }),
12014                    )
12015                    .await;
12016
12017                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12018                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12019                match response_result {
12020                    ConnectionResult::Timeout => {
12021                        log::error!("Timeout during workspace diagnostics pull");
12022                        continue 'request;
12023                    }
12024                    ConnectionResult::ConnectionReset => {
12025                        log::error!("Server closed a workspace diagnostics pull request");
12026                        continue 'request;
12027                    }
12028                    ConnectionResult::Result(Err(e)) => {
12029                        log::error!("Error during workspace diagnostics pull: {e:#}");
12030                        break 'request;
12031                    }
12032                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12033                        attempts = 0;
12034                        if lsp_store
12035                            .update(cx, |lsp_store, cx| {
12036                                lsp_store.apply_workspace_diagnostic_report(
12037                                    server.server_id(),
12038                                    pulled_diagnostics,
12039                                    cx,
12040                                )
12041                            })
12042                            .is_err()
12043                        {
12044                            return;
12045                        }
12046                        break 'request;
12047                    }
12048                }
12049            }
12050        }
12051    });
12052
12053    Some(WorkspaceRefreshTask {
12054        refresh_tx,
12055        progress_tx,
12056        task: workspace_query_language_server,
12057    })
12058}
12059
12060fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12061    let CompletionSource::BufferWord {
12062        word_range,
12063        resolved,
12064    } = &mut completion.source
12065    else {
12066        return;
12067    };
12068    if *resolved {
12069        return;
12070    }
12071
12072    if completion.new_text
12073        != snapshot
12074            .text_for_range(word_range.clone())
12075            .collect::<String>()
12076    {
12077        return;
12078    }
12079
12080    let mut offset = 0;
12081    for chunk in snapshot.chunks(word_range.clone(), true) {
12082        let end_offset = offset + chunk.text.len();
12083        if let Some(highlight_id) = chunk.syntax_highlight_id {
12084            completion
12085                .label
12086                .runs
12087                .push((offset..end_offset, highlight_id));
12088        }
12089        offset = end_offset;
12090    }
12091    *resolved = true;
12092}
12093
12094impl EventEmitter<LspStoreEvent> for LspStore {}
12095
12096fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12097    hover
12098        .contents
12099        .retain(|hover_block| !hover_block.text.trim().is_empty());
12100    if hover.contents.is_empty() {
12101        None
12102    } else {
12103        Some(hover)
12104    }
12105}
12106
12107async fn populate_labels_for_completions(
12108    new_completions: Vec<CoreCompletion>,
12109    language: Option<Arc<Language>>,
12110    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12111) -> Vec<Completion> {
12112    let lsp_completions = new_completions
12113        .iter()
12114        .filter_map(|new_completion| {
12115            new_completion
12116                .source
12117                .lsp_completion(true)
12118                .map(|lsp_completion| lsp_completion.into_owned())
12119        })
12120        .collect::<Vec<_>>();
12121
12122    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12123        lsp_adapter
12124            .labels_for_completions(&lsp_completions, language)
12125            .await
12126            .log_err()
12127            .unwrap_or_default()
12128    } else {
12129        Vec::new()
12130    }
12131    .into_iter()
12132    .fuse();
12133
12134    let mut completions = Vec::new();
12135    for completion in new_completions {
12136        match completion.source.lsp_completion(true) {
12137            Some(lsp_completion) => {
12138                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12139
12140                let mut label = labels.next().flatten().unwrap_or_else(|| {
12141                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12142                });
12143                ensure_uniform_list_compatible_label(&mut label);
12144                completions.push(Completion {
12145                    label,
12146                    documentation,
12147                    replace_range: completion.replace_range,
12148                    new_text: completion.new_text,
12149                    insert_text_mode: lsp_completion.insert_text_mode,
12150                    source: completion.source,
12151                    icon_path: None,
12152                    confirm: None,
12153                });
12154            }
12155            None => {
12156                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12157                ensure_uniform_list_compatible_label(&mut label);
12158                completions.push(Completion {
12159                    label,
12160                    documentation: None,
12161                    replace_range: completion.replace_range,
12162                    new_text: completion.new_text,
12163                    source: completion.source,
12164                    insert_text_mode: None,
12165                    icon_path: None,
12166                    confirm: None,
12167                });
12168            }
12169        }
12170    }
12171    completions
12172}
12173
12174#[derive(Debug)]
12175pub enum LanguageServerToQuery {
12176    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12177    FirstCapable,
12178    /// Query a specific language server.
12179    Other(LanguageServerId),
12180}
12181
12182#[derive(Default)]
12183struct RenamePathsWatchedForServer {
12184    did_rename: Vec<RenameActionPredicate>,
12185    will_rename: Vec<RenameActionPredicate>,
12186}
12187
12188impl RenamePathsWatchedForServer {
12189    fn with_did_rename_patterns(
12190        mut self,
12191        did_rename: Option<&FileOperationRegistrationOptions>,
12192    ) -> Self {
12193        if let Some(did_rename) = did_rename {
12194            self.did_rename = did_rename
12195                .filters
12196                .iter()
12197                .filter_map(|filter| filter.try_into().log_err())
12198                .collect();
12199        }
12200        self
12201    }
12202    fn with_will_rename_patterns(
12203        mut self,
12204        will_rename: Option<&FileOperationRegistrationOptions>,
12205    ) -> Self {
12206        if let Some(will_rename) = will_rename {
12207            self.will_rename = will_rename
12208                .filters
12209                .iter()
12210                .filter_map(|filter| filter.try_into().log_err())
12211                .collect();
12212        }
12213        self
12214    }
12215
12216    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12217        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12218    }
12219    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12220        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12221    }
12222}
12223
12224impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12225    type Error = globset::Error;
12226    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12227        Ok(Self {
12228            kind: ops.pattern.matches.clone(),
12229            glob: GlobBuilder::new(&ops.pattern.glob)
12230                .case_insensitive(
12231                    ops.pattern
12232                        .options
12233                        .as_ref()
12234                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12235                )
12236                .build()?
12237                .compile_matcher(),
12238        })
12239    }
12240}
12241struct RenameActionPredicate {
12242    glob: GlobMatcher,
12243    kind: Option<FileOperationPatternKind>,
12244}
12245
12246impl RenameActionPredicate {
12247    // Returns true if language server should be notified
12248    fn eval(&self, path: &str, is_dir: bool) -> bool {
12249        self.kind.as_ref().is_none_or(|kind| {
12250            let expected_kind = if is_dir {
12251                FileOperationPatternKind::Folder
12252            } else {
12253                FileOperationPatternKind::File
12254            };
12255            kind == &expected_kind
12256        }) && self.glob.is_match(path)
12257    }
12258}
12259
12260#[derive(Default)]
12261struct LanguageServerWatchedPaths {
12262    worktree_paths: HashMap<WorktreeId, GlobSet>,
12263    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12264}
12265
12266#[derive(Default)]
12267struct LanguageServerWatchedPathsBuilder {
12268    worktree_paths: HashMap<WorktreeId, GlobSet>,
12269    abs_paths: HashMap<Arc<Path>, GlobSet>,
12270}
12271
12272impl LanguageServerWatchedPathsBuilder {
12273    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12274        self.worktree_paths.insert(worktree_id, glob_set);
12275    }
12276    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12277        self.abs_paths.insert(path, glob_set);
12278    }
12279    fn build(
12280        self,
12281        fs: Arc<dyn Fs>,
12282        language_server_id: LanguageServerId,
12283        cx: &mut Context<LspStore>,
12284    ) -> LanguageServerWatchedPaths {
12285        let project = cx.weak_entity();
12286
12287        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12288        let abs_paths = self
12289            .abs_paths
12290            .into_iter()
12291            .map(|(abs_path, globset)| {
12292                let task = cx.spawn({
12293                    let abs_path = abs_path.clone();
12294                    let fs = fs.clone();
12295
12296                    let lsp_store = project.clone();
12297                    async move |_, cx| {
12298                        maybe!(async move {
12299                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12300                            while let Some(update) = push_updates.0.next().await {
12301                                let action = lsp_store
12302                                    .update(cx, |this, _| {
12303                                        let Some(local) = this.as_local() else {
12304                                            return ControlFlow::Break(());
12305                                        };
12306                                        let Some(watcher) = local
12307                                            .language_server_watched_paths
12308                                            .get(&language_server_id)
12309                                        else {
12310                                            return ControlFlow::Break(());
12311                                        };
12312                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12313                                            "Watched abs path is not registered with a watcher",
12314                                        );
12315                                        let matching_entries = update
12316                                            .into_iter()
12317                                            .filter(|event| globs.is_match(&event.path))
12318                                            .collect::<Vec<_>>();
12319                                        this.lsp_notify_abs_paths_changed(
12320                                            language_server_id,
12321                                            matching_entries,
12322                                        );
12323                                        ControlFlow::Continue(())
12324                                    })
12325                                    .ok()?;
12326
12327                                if action.is_break() {
12328                                    break;
12329                                }
12330                            }
12331                            Some(())
12332                        })
12333                        .await;
12334                    }
12335                });
12336                (abs_path, (globset, task))
12337            })
12338            .collect();
12339        LanguageServerWatchedPaths {
12340            worktree_paths: self.worktree_paths,
12341            abs_paths,
12342        }
12343    }
12344}
12345
12346struct LspBufferSnapshot {
12347    version: i32,
12348    snapshot: TextBufferSnapshot,
12349}
12350
12351/// A prompt requested by LSP server.
12352#[derive(Clone, Debug)]
12353pub struct LanguageServerPromptRequest {
12354    pub level: PromptLevel,
12355    pub message: String,
12356    pub actions: Vec<MessageActionItem>,
12357    pub lsp_name: String,
12358    pub(crate) response_channel: Sender<MessageActionItem>,
12359}
12360
12361impl LanguageServerPromptRequest {
12362    pub async fn respond(self, index: usize) -> Option<()> {
12363        if let Some(response) = self.actions.into_iter().nth(index) {
12364            self.response_channel.send(response).await.ok()
12365        } else {
12366            None
12367        }
12368    }
12369}
12370impl PartialEq for LanguageServerPromptRequest {
12371    fn eq(&self, other: &Self) -> bool {
12372        self.message == other.message && self.actions == other.actions
12373    }
12374}
12375
12376#[derive(Clone, Debug, PartialEq)]
12377pub enum LanguageServerLogType {
12378    Log(MessageType),
12379    Trace { verbose_info: Option<String> },
12380    Rpc { received: bool },
12381}
12382
12383impl LanguageServerLogType {
12384    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12385        match self {
12386            Self::Log(log_type) => {
12387                use proto::log_message::LogLevel;
12388                let level = match *log_type {
12389                    MessageType::ERROR => LogLevel::Error,
12390                    MessageType::WARNING => LogLevel::Warning,
12391                    MessageType::INFO => LogLevel::Info,
12392                    MessageType::LOG => LogLevel::Log,
12393                    other => {
12394                        log::warn!("Unknown lsp log message type: {other:?}");
12395                        LogLevel::Log
12396                    }
12397                };
12398                proto::language_server_log::LogType::Log(proto::LogMessage {
12399                    level: level as i32,
12400                })
12401            }
12402            Self::Trace { verbose_info } => {
12403                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12404                    verbose_info: verbose_info.to_owned(),
12405                })
12406            }
12407            Self::Rpc { received } => {
12408                let kind = if *received {
12409                    proto::rpc_message::Kind::Received
12410                } else {
12411                    proto::rpc_message::Kind::Sent
12412                };
12413                let kind = kind as i32;
12414                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12415            }
12416        }
12417    }
12418
12419    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12420        use proto::log_message::LogLevel;
12421        use proto::rpc_message;
12422        match log_type {
12423            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12424                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12425                    LogLevel::Error => MessageType::ERROR,
12426                    LogLevel::Warning => MessageType::WARNING,
12427                    LogLevel::Info => MessageType::INFO,
12428                    LogLevel::Log => MessageType::LOG,
12429                },
12430            ),
12431            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12432                verbose_info: trace_message.verbose_info,
12433            },
12434            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12435                received: match rpc_message::Kind::from_i32(message.kind)
12436                    .unwrap_or(rpc_message::Kind::Received)
12437                {
12438                    rpc_message::Kind::Received => true,
12439                    rpc_message::Kind::Sent => false,
12440                },
12441            },
12442        }
12443    }
12444}
12445
12446pub struct WorkspaceRefreshTask {
12447    refresh_tx: mpsc::Sender<()>,
12448    progress_tx: mpsc::Sender<()>,
12449    #[allow(dead_code)]
12450    task: Task<()>,
12451}
12452
12453pub enum LanguageServerState {
12454    Starting {
12455        startup: Task<Option<Arc<LanguageServer>>>,
12456        /// List of language servers that will be added to the workspace once it's initialization completes.
12457        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
12458    },
12459
12460    Running {
12461        adapter: Arc<CachedLspAdapter>,
12462        server: Arc<LanguageServer>,
12463        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12464        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12465    },
12466}
12467
12468impl LanguageServerState {
12469    fn add_workspace_folder(&self, uri: Uri) {
12470        match self {
12471            LanguageServerState::Starting {
12472                pending_workspace_folders,
12473                ..
12474            } => {
12475                pending_workspace_folders.lock().insert(uri);
12476            }
12477            LanguageServerState::Running { server, .. } => {
12478                server.add_workspace_folder(uri);
12479            }
12480        }
12481    }
12482    fn _remove_workspace_folder(&self, uri: Uri) {
12483        match self {
12484            LanguageServerState::Starting {
12485                pending_workspace_folders,
12486                ..
12487            } => {
12488                pending_workspace_folders.lock().remove(&uri);
12489            }
12490            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12491        }
12492    }
12493}
12494
12495impl std::fmt::Debug for LanguageServerState {
12496    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12497        match self {
12498            LanguageServerState::Starting { .. } => {
12499                f.debug_struct("LanguageServerState::Starting").finish()
12500            }
12501            LanguageServerState::Running { .. } => {
12502                f.debug_struct("LanguageServerState::Running").finish()
12503            }
12504        }
12505    }
12506}
12507
12508#[derive(Clone, Debug, Serialize)]
12509pub struct LanguageServerProgress {
12510    pub is_disk_based_diagnostics_progress: bool,
12511    pub is_cancellable: bool,
12512    pub title: Option<String>,
12513    pub message: Option<String>,
12514    pub percentage: Option<usize>,
12515    #[serde(skip_serializing)]
12516    pub last_update_at: Instant,
12517}
12518
12519#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12520pub struct DiagnosticSummary {
12521    pub error_count: usize,
12522    pub warning_count: usize,
12523}
12524
12525impl DiagnosticSummary {
12526    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12527        let mut this = Self {
12528            error_count: 0,
12529            warning_count: 0,
12530        };
12531
12532        for entry in diagnostics {
12533            if entry.diagnostic.is_primary {
12534                match entry.diagnostic.severity {
12535                    DiagnosticSeverity::ERROR => this.error_count += 1,
12536                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12537                    _ => {}
12538                }
12539            }
12540        }
12541
12542        this
12543    }
12544
12545    pub fn is_empty(&self) -> bool {
12546        self.error_count == 0 && self.warning_count == 0
12547    }
12548
12549    pub fn to_proto(
12550        self,
12551        language_server_id: LanguageServerId,
12552        path: &RelPath,
12553    ) -> proto::DiagnosticSummary {
12554        proto::DiagnosticSummary {
12555            path: path.to_proto(),
12556            language_server_id: language_server_id.0 as u64,
12557            error_count: self.error_count as u32,
12558            warning_count: self.warning_count as u32,
12559        }
12560    }
12561}
12562
12563#[derive(Clone, Debug)]
12564pub enum CompletionDocumentation {
12565    /// There is no documentation for this completion.
12566    Undocumented,
12567    /// A single line of documentation.
12568    SingleLine(SharedString),
12569    /// Multiple lines of plain text documentation.
12570    MultiLinePlainText(SharedString),
12571    /// Markdown documentation.
12572    MultiLineMarkdown(SharedString),
12573    /// Both single line and multiple lines of plain text documentation.
12574    SingleLineAndMultiLinePlainText {
12575        single_line: SharedString,
12576        plain_text: Option<SharedString>,
12577    },
12578}
12579
12580impl CompletionDocumentation {
12581    #[cfg(any(test, feature = "test-support"))]
12582    pub fn text(&self) -> SharedString {
12583        match self {
12584            CompletionDocumentation::Undocumented => "".into(),
12585            CompletionDocumentation::SingleLine(s) => s.clone(),
12586            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
12587            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
12588            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
12589                single_line.clone()
12590            }
12591        }
12592    }
12593}
12594
12595impl From<lsp::Documentation> for CompletionDocumentation {
12596    fn from(docs: lsp::Documentation) -> Self {
12597        match docs {
12598            lsp::Documentation::String(text) => {
12599                if text.lines().count() <= 1 {
12600                    CompletionDocumentation::SingleLine(text.into())
12601                } else {
12602                    CompletionDocumentation::MultiLinePlainText(text.into())
12603                }
12604            }
12605
12606            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
12607                lsp::MarkupKind::PlainText => {
12608                    if value.lines().count() <= 1 {
12609                        CompletionDocumentation::SingleLine(value.into())
12610                    } else {
12611                        CompletionDocumentation::MultiLinePlainText(value.into())
12612                    }
12613                }
12614
12615                lsp::MarkupKind::Markdown => {
12616                    CompletionDocumentation::MultiLineMarkdown(value.into())
12617                }
12618            },
12619        }
12620    }
12621}
12622
12623fn glob_literal_prefix(glob: &Path) -> PathBuf {
12624    glob.components()
12625        .take_while(|component| match component {
12626            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
12627            _ => true,
12628        })
12629        .collect()
12630}
12631
12632pub struct SshLspAdapter {
12633    name: LanguageServerName,
12634    binary: LanguageServerBinary,
12635    initialization_options: Option<String>,
12636    code_action_kinds: Option<Vec<CodeActionKind>>,
12637}
12638
12639impl SshLspAdapter {
12640    pub fn new(
12641        name: LanguageServerName,
12642        binary: LanguageServerBinary,
12643        initialization_options: Option<String>,
12644        code_action_kinds: Option<String>,
12645    ) -> Self {
12646        Self {
12647            name,
12648            binary,
12649            initialization_options,
12650            code_action_kinds: code_action_kinds
12651                .as_ref()
12652                .and_then(|c| serde_json::from_str(c).ok()),
12653        }
12654    }
12655}
12656
12657impl LspInstaller for SshLspAdapter {
12658    type BinaryVersion = ();
12659    async fn check_if_user_installed(
12660        &self,
12661        _: &dyn LspAdapterDelegate,
12662        _: Option<Toolchain>,
12663        _: &AsyncApp,
12664    ) -> Option<LanguageServerBinary> {
12665        Some(self.binary.clone())
12666    }
12667
12668    async fn cached_server_binary(
12669        &self,
12670        _: PathBuf,
12671        _: &dyn LspAdapterDelegate,
12672    ) -> Option<LanguageServerBinary> {
12673        None
12674    }
12675
12676    async fn fetch_latest_server_version(
12677        &self,
12678        _: &dyn LspAdapterDelegate,
12679        _: bool,
12680        _: &mut AsyncApp,
12681    ) -> Result<()> {
12682        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
12683    }
12684
12685    async fn fetch_server_binary(
12686        &self,
12687        _: (),
12688        _: PathBuf,
12689        _: &dyn LspAdapterDelegate,
12690    ) -> Result<LanguageServerBinary> {
12691        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
12692    }
12693}
12694
12695#[async_trait(?Send)]
12696impl LspAdapter for SshLspAdapter {
12697    fn name(&self) -> LanguageServerName {
12698        self.name.clone()
12699    }
12700
12701    async fn initialization_options(
12702        self: Arc<Self>,
12703        _: &Arc<dyn LspAdapterDelegate>,
12704    ) -> Result<Option<serde_json::Value>> {
12705        let Some(options) = &self.initialization_options else {
12706            return Ok(None);
12707        };
12708        let result = serde_json::from_str(options)?;
12709        Ok(result)
12710    }
12711
12712    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
12713        self.code_action_kinds.clone()
12714    }
12715}
12716
12717pub fn language_server_settings<'a>(
12718    delegate: &'a dyn LspAdapterDelegate,
12719    language: &LanguageServerName,
12720    cx: &'a App,
12721) -> Option<&'a LspSettings> {
12722    language_server_settings_for(
12723        SettingsLocation {
12724            worktree_id: delegate.worktree_id(),
12725            path: RelPath::empty(),
12726        },
12727        language,
12728        cx,
12729    )
12730}
12731
12732pub(crate) fn language_server_settings_for<'a>(
12733    location: SettingsLocation<'a>,
12734    language: &LanguageServerName,
12735    cx: &'a App,
12736) -> Option<&'a LspSettings> {
12737    ProjectSettings::get(Some(location), cx).lsp.get(language)
12738}
12739
12740pub struct LocalLspAdapterDelegate {
12741    lsp_store: WeakEntity<LspStore>,
12742    worktree: worktree::Snapshot,
12743    fs: Arc<dyn Fs>,
12744    http_client: Arc<dyn HttpClient>,
12745    language_registry: Arc<LanguageRegistry>,
12746    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
12747}
12748
12749impl LocalLspAdapterDelegate {
12750    pub fn new(
12751        language_registry: Arc<LanguageRegistry>,
12752        environment: &Entity<ProjectEnvironment>,
12753        lsp_store: WeakEntity<LspStore>,
12754        worktree: &Entity<Worktree>,
12755        http_client: Arc<dyn HttpClient>,
12756        fs: Arc<dyn Fs>,
12757        cx: &mut App,
12758    ) -> Arc<Self> {
12759        let load_shell_env_task = environment.update(cx, |env, cx| {
12760            env.get_worktree_environment(worktree.clone(), cx)
12761        });
12762
12763        Arc::new(Self {
12764            lsp_store,
12765            worktree: worktree.read(cx).snapshot(),
12766            fs,
12767            http_client,
12768            language_registry,
12769            load_shell_env_task,
12770        })
12771    }
12772
12773    fn from_local_lsp(
12774        local: &LocalLspStore,
12775        worktree: &Entity<Worktree>,
12776        cx: &mut App,
12777    ) -> Arc<Self> {
12778        Self::new(
12779            local.languages.clone(),
12780            &local.environment,
12781            local.weak.clone(),
12782            worktree,
12783            local.http_client.clone(),
12784            local.fs.clone(),
12785            cx,
12786        )
12787    }
12788}
12789
12790#[async_trait]
12791impl LspAdapterDelegate for LocalLspAdapterDelegate {
12792    fn show_notification(&self, message: &str, cx: &mut App) {
12793        self.lsp_store
12794            .update(cx, |_, cx| {
12795                cx.emit(LspStoreEvent::Notification(message.to_owned()))
12796            })
12797            .ok();
12798    }
12799
12800    fn http_client(&self) -> Arc<dyn HttpClient> {
12801        self.http_client.clone()
12802    }
12803
12804    fn worktree_id(&self) -> WorktreeId {
12805        self.worktree.id()
12806    }
12807
12808    fn worktree_root_path(&self) -> &Path {
12809        self.worktree.abs_path().as_ref()
12810    }
12811
12812    async fn shell_env(&self) -> HashMap<String, String> {
12813        let task = self.load_shell_env_task.clone();
12814        task.await.unwrap_or_default()
12815    }
12816
12817    async fn npm_package_installed_version(
12818        &self,
12819        package_name: &str,
12820    ) -> Result<Option<(PathBuf, String)>> {
12821        let local_package_directory = self.worktree_root_path();
12822        let node_modules_directory = local_package_directory.join("node_modules");
12823
12824        if let Some(version) =
12825            read_package_installed_version(node_modules_directory.clone(), package_name).await?
12826        {
12827            return Ok(Some((node_modules_directory, version)));
12828        }
12829        let Some(npm) = self.which("npm".as_ref()).await else {
12830            log::warn!(
12831                "Failed to find npm executable for {:?}",
12832                local_package_directory
12833            );
12834            return Ok(None);
12835        };
12836
12837        let env = self.shell_env().await;
12838        let output = util::command::new_smol_command(&npm)
12839            .args(["root", "-g"])
12840            .envs(env)
12841            .current_dir(local_package_directory)
12842            .output()
12843            .await?;
12844        let global_node_modules =
12845            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
12846
12847        if let Some(version) =
12848            read_package_installed_version(global_node_modules.clone(), package_name).await?
12849        {
12850            return Ok(Some((global_node_modules, version)));
12851        }
12852        return Ok(None);
12853    }
12854
12855    #[cfg(not(target_os = "windows"))]
12856    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12857        let worktree_abs_path = self.worktree.abs_path();
12858        let shell_path = self.shell_env().await.get("PATH").cloned();
12859        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
12860    }
12861
12862    #[cfg(target_os = "windows")]
12863    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12864        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
12865        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
12866        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
12867        which::which(command).ok()
12868    }
12869
12870    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
12871        let working_dir = self.worktree_root_path();
12872        let output = util::command::new_smol_command(&command.path)
12873            .args(command.arguments)
12874            .envs(command.env.clone().unwrap_or_default())
12875            .current_dir(working_dir)
12876            .output()
12877            .await?;
12878
12879        anyhow::ensure!(
12880            output.status.success(),
12881            "{}, stdout: {:?}, stderr: {:?}",
12882            output.status,
12883            String::from_utf8_lossy(&output.stdout),
12884            String::from_utf8_lossy(&output.stderr)
12885        );
12886        Ok(())
12887    }
12888
12889    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
12890        self.language_registry
12891            .update_lsp_binary_status(server_name, status);
12892    }
12893
12894    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
12895        self.language_registry
12896            .all_lsp_adapters()
12897            .into_iter()
12898            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
12899            .collect()
12900    }
12901
12902    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
12903        let dir = self.language_registry.language_server_download_dir(name)?;
12904
12905        if !dir.exists() {
12906            smol::fs::create_dir_all(&dir)
12907                .await
12908                .context("failed to create container directory")
12909                .log_err()?;
12910        }
12911
12912        Some(dir)
12913    }
12914
12915    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
12916        let entry = self
12917            .worktree
12918            .entry_for_path(path)
12919            .with_context(|| format!("no worktree entry for path {path:?}"))?;
12920        let abs_path = self.worktree.absolutize(&entry.path);
12921        self.fs.load(&abs_path).await
12922    }
12923}
12924
12925async fn populate_labels_for_symbols(
12926    symbols: Vec<CoreSymbol>,
12927    language_registry: &Arc<LanguageRegistry>,
12928    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12929    output: &mut Vec<Symbol>,
12930) {
12931    #[allow(clippy::mutable_key_type)]
12932    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
12933
12934    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
12935    for symbol in symbols {
12936        let Some(file_name) = symbol.path.file_name() else {
12937            continue;
12938        };
12939        let language = language_registry
12940            .language_for_file_path(Path::new(file_name))
12941            .await
12942            .ok()
12943            .or_else(|| {
12944                unknown_paths.insert(file_name.into());
12945                None
12946            });
12947        symbols_by_language
12948            .entry(language)
12949            .or_default()
12950            .push(symbol);
12951    }
12952
12953    for unknown_path in unknown_paths {
12954        log::info!("no language found for symbol in file {unknown_path:?}");
12955    }
12956
12957    let mut label_params = Vec::new();
12958    for (language, mut symbols) in symbols_by_language {
12959        label_params.clear();
12960        label_params.extend(
12961            symbols
12962                .iter_mut()
12963                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
12964        );
12965
12966        let mut labels = Vec::new();
12967        if let Some(language) = language {
12968            let lsp_adapter = lsp_adapter.clone().or_else(|| {
12969                language_registry
12970                    .lsp_adapters(&language.name())
12971                    .first()
12972                    .cloned()
12973            });
12974            if let Some(lsp_adapter) = lsp_adapter {
12975                labels = lsp_adapter
12976                    .labels_for_symbols(&label_params, &language)
12977                    .await
12978                    .log_err()
12979                    .unwrap_or_default();
12980            }
12981        }
12982
12983        for ((symbol, (name, _)), label) in symbols
12984            .into_iter()
12985            .zip(label_params.drain(..))
12986            .zip(labels.into_iter().chain(iter::repeat(None)))
12987        {
12988            output.push(Symbol {
12989                language_server_name: symbol.language_server_name,
12990                source_worktree_id: symbol.source_worktree_id,
12991                source_language_server_id: symbol.source_language_server_id,
12992                path: symbol.path,
12993                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
12994                name,
12995                kind: symbol.kind,
12996                range: symbol.range,
12997            });
12998        }
12999    }
13000}
13001
13002fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13003    match server.capabilities().text_document_sync.as_ref()? {
13004        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13005            // Server wants didSave but didn't specify includeText.
13006            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13007            // Server doesn't want didSave at all.
13008            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13009            // Server provided SaveOptions.
13010            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13011                Some(save_options.include_text.unwrap_or(false))
13012            }
13013        },
13014        // We do not have any save info. Kind affects didChange only.
13015        lsp::TextDocumentSyncCapability::Kind(_) => None,
13016    }
13017}
13018
13019/// Completion items are displayed in a `UniformList`.
13020/// Usually, those items are single-line strings, but in LSP responses,
13021/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13022/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13023/// 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,
13024/// breaking the completions menu presentation.
13025///
13026/// 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.
13027fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13028    let mut new_text = String::with_capacity(label.text.len());
13029    let mut offset_map = vec![0; label.text.len() + 1];
13030    let mut last_char_was_space = false;
13031    let mut new_idx = 0;
13032    let chars = label.text.char_indices().fuse();
13033    let mut newlines_removed = false;
13034
13035    for (idx, c) in chars {
13036        offset_map[idx] = new_idx;
13037
13038        match c {
13039            '\n' if last_char_was_space => {
13040                newlines_removed = true;
13041            }
13042            '\t' | ' ' if last_char_was_space => {}
13043            '\n' if !last_char_was_space => {
13044                new_text.push(' ');
13045                new_idx += 1;
13046                last_char_was_space = true;
13047                newlines_removed = true;
13048            }
13049            ' ' | '\t' => {
13050                new_text.push(' ');
13051                new_idx += 1;
13052                last_char_was_space = true;
13053            }
13054            _ => {
13055                new_text.push(c);
13056                new_idx += c.len_utf8();
13057                last_char_was_space = false;
13058            }
13059        }
13060    }
13061    offset_map[label.text.len()] = new_idx;
13062
13063    // Only modify the label if newlines were removed.
13064    if !newlines_removed {
13065        return;
13066    }
13067
13068    let last_index = new_idx;
13069    let mut run_ranges_errors = Vec::new();
13070    label.runs.retain_mut(|(range, _)| {
13071        match offset_map.get(range.start) {
13072            Some(&start) => range.start = start,
13073            None => {
13074                run_ranges_errors.push(range.clone());
13075                return false;
13076            }
13077        }
13078
13079        match offset_map.get(range.end) {
13080            Some(&end) => range.end = end,
13081            None => {
13082                run_ranges_errors.push(range.clone());
13083                range.end = last_index;
13084            }
13085        }
13086        true
13087    });
13088    if !run_ranges_errors.is_empty() {
13089        log::error!(
13090            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13091            label.text
13092        );
13093    }
13094
13095    let mut wrong_filter_range = None;
13096    if label.filter_range == (0..label.text.len()) {
13097        label.filter_range = 0..new_text.len();
13098    } else {
13099        let mut original_filter_range = Some(label.filter_range.clone());
13100        match offset_map.get(label.filter_range.start) {
13101            Some(&start) => label.filter_range.start = start,
13102            None => {
13103                wrong_filter_range = original_filter_range.take();
13104                label.filter_range.start = last_index;
13105            }
13106        }
13107
13108        match offset_map.get(label.filter_range.end) {
13109            Some(&end) => label.filter_range.end = end,
13110            None => {
13111                wrong_filter_range = original_filter_range.take();
13112                label.filter_range.end = last_index;
13113            }
13114        }
13115    }
13116    if let Some(wrong_filter_range) = wrong_filter_range {
13117        log::error!(
13118            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13119            label.text
13120        );
13121    }
13122
13123    label.text = new_text;
13124}
13125
13126#[cfg(test)]
13127mod tests {
13128    use language::HighlightId;
13129
13130    use super::*;
13131
13132    #[test]
13133    fn test_glob_literal_prefix() {
13134        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13135        assert_eq!(
13136            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13137            Path::new("node_modules")
13138        );
13139        assert_eq!(
13140            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13141            Path::new("foo")
13142        );
13143        assert_eq!(
13144            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13145            Path::new("foo/bar/baz.js")
13146        );
13147
13148        #[cfg(target_os = "windows")]
13149        {
13150            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13151            assert_eq!(
13152                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13153                Path::new("node_modules")
13154            );
13155            assert_eq!(
13156                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13157                Path::new("foo")
13158            );
13159            assert_eq!(
13160                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13161                Path::new("foo/bar/baz.js")
13162            );
13163        }
13164    }
13165
13166    #[test]
13167    fn test_multi_len_chars_normalization() {
13168        let mut label = CodeLabel {
13169            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13170            runs: vec![(0..6, HighlightId(1))],
13171            filter_range: 0..6,
13172        };
13173        ensure_uniform_list_compatible_label(&mut label);
13174        assert_eq!(
13175            label,
13176            CodeLabel {
13177                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13178                runs: vec![(0..6, HighlightId(1))],
13179                filter_range: 0..6,
13180            }
13181        );
13182    }
13183}