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