lsp_store.rs

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