lsp_store.rs

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