lsp_store.rs

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