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