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