lsp_store.rs

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