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