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