lsp_store.rs

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