lsp_store.rs

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