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