lsp_store.rs

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