lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17
   18use crate::{
   19    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   20    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, LocationLink, LspAction,
   21    LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   22    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   23    buffer_store::{BufferStore, BufferStoreEvent},
   24    environment::ProjectEnvironment,
   25    lsp_command::{self, *},
   26    lsp_store::{
   27        self,
   28        log_store::{GlobalLogStore, LanguageServerKind},
   29    },
   30    manifest_tree::{
   31        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   32        ManifestTree,
   33    },
   34    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   35    project_settings::{LspSettings, ProjectSettings},
   36    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   37    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   38    yarn::YarnPathStore,
   39};
   40use anyhow::{Context as _, Result, anyhow};
   41use async_trait::async_trait;
   42use client::{TypedEnvelope, proto};
   43use clock::Global;
   44use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   45use futures::{
   46    AsyncWriteExt, Future, FutureExt, StreamExt,
   47    future::{Either, Shared, join_all, pending, select},
   48    select, select_biased,
   49    stream::FuturesUnordered,
   50};
   51use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   52use gpui::{
   53    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   54    WeakEntity,
   55};
   56use http_client::HttpClient;
   57use itertools::Itertools as _;
   58use language::{
   59    Bias, BinaryStatus, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   60    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   61    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   62    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   63    Transaction, Unclipped,
   64    language_settings::{
   65        FormatOnSave, Formatter, LanguageSettings, SelectedFormatter, language_settings,
   66    },
   67    point_to_lsp,
   68    proto::{
   69        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   70        serialize_lsp_edit, serialize_version,
   71    },
   72    range_from_lsp, range_to_lsp,
   73};
   74use lsp::{
   75    AdapterServerCapabilities, CodeActionKind, CompletionContext, DiagnosticSeverity,
   76    DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter,
   77    FileOperationPatternKind, FileOperationRegistrationOptions, FileRename, FileSystemWatcher,
   78    LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions,
   79    LanguageServerId, LanguageServerName, LanguageServerSelector, LspRequestFuture,
   80    MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind,
   81    TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles, WorkDoneProgressCancelParams,
   82    WorkspaceFolder, notification::DidRenameFiles,
   83};
   84use node_runtime::read_package_installed_version;
   85use parking_lot::Mutex;
   86use postage::{mpsc, sink::Sink, stream::Stream, watch};
   87use rand::prelude::*;
   88use rpc::{
   89    AnyProtoClient,
   90    proto::{LspRequestId, LspRequestMessage as _},
   91};
   92use serde::Serialize;
   93use settings::{Settings, SettingsLocation, SettingsStore};
   94use sha2::{Digest, Sha256};
   95use smol::channel::Sender;
   96use snippet::Snippet;
   97use std::{
   98    any::TypeId,
   99    borrow::Cow,
  100    cell::RefCell,
  101    cmp::{Ordering, Reverse},
  102    convert::TryInto,
  103    ffi::OsStr,
  104    future::ready,
  105    iter, mem,
  106    ops::{ControlFlow, Range},
  107    path::{self, Path, PathBuf},
  108    pin::pin,
  109    rc::Rc,
  110    sync::Arc,
  111    time::{Duration, Instant},
  112};
  113use sum_tree::Dimensions;
  114use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  115
  116use util::{
  117    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  118    paths::{PathStyle, SanitizedPath},
  119    post_inc,
  120    rel_path::RelPath,
  121};
  122
  123pub use fs::*;
  124pub use language::Location;
  125#[cfg(any(test, feature = "test-support"))]
  126pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  127pub use worktree::{
  128    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  129    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  130};
  131
  132const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  133pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  134
  135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  136pub enum FormatTrigger {
  137    Save,
  138    Manual,
  139}
  140
  141pub enum LspFormatTarget {
  142    Buffers,
  143    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  144}
  145
  146pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  147
  148impl FormatTrigger {
  149    fn from_proto(value: i32) -> FormatTrigger {
  150        match value {
  151            0 => FormatTrigger::Save,
  152            1 => FormatTrigger::Manual,
  153            _ => FormatTrigger::Save,
  154        }
  155    }
  156}
  157
  158#[derive(Clone)]
  159struct UnifiedLanguageServer {
  160    id: LanguageServerId,
  161    project_roots: HashSet<Arc<RelPath>>,
  162}
  163
  164#[derive(Clone, Hash, PartialEq, Eq)]
  165struct LanguageServerSeed {
  166    worktree_id: WorktreeId,
  167    name: LanguageServerName,
  168    toolchain: Option<Toolchain>,
  169    settings: Arc<LspSettings>,
  170}
  171
  172#[derive(Debug)]
  173pub struct DocumentDiagnosticsUpdate<'a, D> {
  174    pub diagnostics: D,
  175    pub result_id: Option<String>,
  176    pub server_id: LanguageServerId,
  177    pub disk_based_sources: Cow<'a, [String]>,
  178}
  179
  180pub struct DocumentDiagnostics {
  181    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  182    document_abs_path: PathBuf,
  183    version: Option<i32>,
  184}
  185
  186pub struct LocalLspStore {
  187    weak: WeakEntity<LspStore>,
  188    worktree_store: Entity<WorktreeStore>,
  189    toolchain_store: Entity<LocalToolchainStore>,
  190    http_client: Arc<dyn HttpClient>,
  191    environment: Entity<ProjectEnvironment>,
  192    fs: Arc<dyn Fs>,
  193    languages: Arc<LanguageRegistry>,
  194    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  195    yarn: Entity<YarnPathStore>,
  196    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  197    buffers_being_formatted: HashSet<BufferId>,
  198    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  199    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  200    watched_manifest_filenames: HashSet<ManifestName>,
  201    language_server_paths_watched_for_rename:
  202        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  203    language_server_watcher_registrations:
  204        HashMap<LanguageServerId, HashMap<String, Vec<FileSystemWatcher>>>,
  205    supplementary_language_servers:
  206        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  207    prettier_store: Entity<PrettierStore>,
  208    next_diagnostic_group_id: usize,
  209    diagnostics: HashMap<
  210        WorktreeId,
  211        HashMap<
  212            Arc<RelPath>,
  213            Vec<(
  214                LanguageServerId,
  215                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  216            )>,
  217        >,
  218    >,
  219    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  220    _subscription: gpui::Subscription,
  221    lsp_tree: LanguageServerTree,
  222    registered_buffers: HashMap<BufferId, usize>,
  223    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  224    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  225}
  226
  227impl LocalLspStore {
  228    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  229    pub fn running_language_server_for_id(
  230        &self,
  231        id: LanguageServerId,
  232    ) -> Option<&Arc<LanguageServer>> {
  233        let language_server_state = self.language_servers.get(&id)?;
  234
  235        match language_server_state {
  236            LanguageServerState::Running { server, .. } => Some(server),
  237            LanguageServerState::Starting { .. } => None,
  238        }
  239    }
  240
  241    fn get_or_insert_language_server(
  242        &mut self,
  243        worktree_handle: &Entity<Worktree>,
  244        delegate: Arc<LocalLspAdapterDelegate>,
  245        disposition: &Arc<LaunchDisposition>,
  246        language_name: &LanguageName,
  247        cx: &mut App,
  248    ) -> LanguageServerId {
  249        let key = LanguageServerSeed {
  250            worktree_id: worktree_handle.read(cx).id(),
  251            name: disposition.server_name.clone(),
  252            settings: disposition.settings.clone(),
  253            toolchain: disposition.toolchain.clone(),
  254        };
  255        if let Some(state) = self.language_server_ids.get_mut(&key) {
  256            state.project_roots.insert(disposition.path.path.clone());
  257            state.id
  258        } else {
  259            let adapter = self
  260                .languages
  261                .lsp_adapters(language_name)
  262                .into_iter()
  263                .find(|adapter| adapter.name() == disposition.server_name)
  264                .expect("To find LSP adapter");
  265            let new_language_server_id = self.start_language_server(
  266                worktree_handle,
  267                delegate,
  268                adapter,
  269                disposition.settings.clone(),
  270                key.clone(),
  271                cx,
  272            );
  273            if let Some(state) = self.language_server_ids.get_mut(&key) {
  274                state.project_roots.insert(disposition.path.path.clone());
  275            } else {
  276                debug_assert!(
  277                    false,
  278                    "Expected `start_language_server` to ensure that `key` exists in a map"
  279                );
  280            }
  281            new_language_server_id
  282        }
  283    }
  284
  285    fn start_language_server(
  286        &mut self,
  287        worktree_handle: &Entity<Worktree>,
  288        delegate: Arc<LocalLspAdapterDelegate>,
  289        adapter: Arc<CachedLspAdapter>,
  290        settings: Arc<LspSettings>,
  291        key: LanguageServerSeed,
  292        cx: &mut App,
  293    ) -> LanguageServerId {
  294        let worktree = worktree_handle.read(cx);
  295
  296        let root_path = worktree.abs_path();
  297        let toolchain = key.toolchain.clone();
  298        let override_options = settings.initialization_options.clone();
  299
  300        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  301
  302        let server_id = self.languages.next_language_server_id();
  303        log::trace!(
  304            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  305            adapter.name.0
  306        );
  307
  308        let binary = self.get_language_server_binary(
  309            adapter.clone(),
  310            settings,
  311            toolchain.clone(),
  312            delegate.clone(),
  313            true,
  314            cx,
  315        );
  316        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  317
  318        let pending_server = cx.spawn({
  319            let adapter = adapter.clone();
  320            let server_name = adapter.name.clone();
  321            let stderr_capture = stderr_capture.clone();
  322            #[cfg(any(test, feature = "test-support"))]
  323            let lsp_store = self.weak.clone();
  324            let pending_workspace_folders = pending_workspace_folders.clone();
  325            async move |cx| {
  326                let binary = binary.await?;
  327                #[cfg(any(test, feature = "test-support"))]
  328                if let Some(server) = lsp_store
  329                    .update(&mut cx.clone(), |this, cx| {
  330                        this.languages.create_fake_language_server(
  331                            server_id,
  332                            &server_name,
  333                            binary.clone(),
  334                            &mut cx.to_async(),
  335                        )
  336                    })
  337                    .ok()
  338                    .flatten()
  339                {
  340                    return Ok(server);
  341                }
  342
  343                let code_action_kinds = adapter.code_action_kinds();
  344                lsp::LanguageServer::new(
  345                    stderr_capture,
  346                    server_id,
  347                    server_name,
  348                    binary,
  349                    &root_path,
  350                    code_action_kinds,
  351                    Some(pending_workspace_folders),
  352                    cx,
  353                )
  354            }
  355        });
  356
  357        let startup = {
  358            let server_name = adapter.name.0.clone();
  359            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  360            let key = key.clone();
  361            let adapter = adapter.clone();
  362            let lsp_store = self.weak.clone();
  363            let pending_workspace_folders = pending_workspace_folders.clone();
  364
  365            let pull_diagnostics = ProjectSettings::get_global(cx)
  366                .diagnostics
  367                .lsp_pull_diagnostics
  368                .enabled;
  369            cx.spawn(async move |cx| {
  370                let result = async {
  371                    let language_server = pending_server.await?;
  372
  373                    let workspace_config = Self::workspace_configuration_for_adapter(
  374                        adapter.adapter.clone(),
  375                        &delegate,
  376                        toolchain,
  377                        cx,
  378                    )
  379                    .await?;
  380
  381                    let mut initialization_options = Self::initialization_options_for_adapter(
  382                        adapter.adapter.clone(),
  383                        &delegate,
  384                    )
  385                    .await?;
  386
  387                    match (&mut initialization_options, override_options) {
  388                        (Some(initialization_options), Some(override_options)) => {
  389                            merge_json_value_into(override_options, initialization_options);
  390                        }
  391                        (None, override_options) => initialization_options = override_options,
  392                        _ => {}
  393                    }
  394
  395                    let initialization_params = cx.update(|cx| {
  396                        let mut params =
  397                            language_server.default_initialize_params(pull_diagnostics, cx);
  398                        params.initialization_options = initialization_options;
  399                        adapter.adapter.prepare_initialize_params(params, cx)
  400                    })??;
  401
  402                    Self::setup_lsp_messages(
  403                        lsp_store.clone(),
  404                        &language_server,
  405                        delegate.clone(),
  406                        adapter.clone(),
  407                    );
  408
  409                    let did_change_configuration_params =
  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<RelPath> = 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                    let code_action_kinds = code_actions
 1525                        .iter()
 1526                        .filter_map(|(action_kind, enabled)| {
 1527                            enabled.then_some(action_kind.clone().into())
 1528                        })
 1529                        .collect::<Vec<_>>();
 1530                    if code_action_kinds.is_empty() {
 1531                        zlog::trace!(logger => "No code action kinds enabled, skipping");
 1532                        continue;
 1533                    }
 1534                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kinds);
 1535
 1536                    let mut actions_and_servers = Vec::new();
 1537
 1538                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1539                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1540                            &lsp_store,
 1541                            language_server.server_id(),
 1542                            code_action_kinds.clone(),
 1543                            &buffer.handle,
 1544                            cx,
 1545                        )
 1546                        .await
 1547                        .with_context(
 1548                            || format!("Failed to resolve code actions with kinds {:?} for language server {}",
 1549                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1550                                language_server.name())
 1551                        );
 1552                        let Ok(actions) = actions_result else {
 1553                            // note: it may be better to set result to the error and break formatters here
 1554                            // but for now we try to execute the actions that we can resolve and skip the rest
 1555                            zlog::error!(
 1556                                logger =>
 1557                                "Failed to resolve code actions with kinds {:?} with language server {}",
 1558                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1559                                language_server.name()
 1560                            );
 1561                            continue;
 1562                        };
 1563                        for action in actions {
 1564                            actions_and_servers.push((action, index));
 1565                        }
 1566                    }
 1567
 1568                    if actions_and_servers.is_empty() {
 1569                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1570                        continue;
 1571                    }
 1572
 1573                    'actions: for (mut action, server_index) in actions_and_servers {
 1574                        let server = &adapters_and_servers[server_index].1;
 1575
 1576                        let describe_code_action = |action: &CodeAction| {
 1577                            format!(
 1578                                "code action '{}' with title \"{}\" on server {}",
 1579                                action
 1580                                    .lsp_action
 1581                                    .action_kind()
 1582                                    .unwrap_or("unknown".into())
 1583                                    .as_str(),
 1584                                action.lsp_action.title(),
 1585                                server.name(),
 1586                            )
 1587                        };
 1588
 1589                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1590
 1591                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1592                            zlog::error!(
 1593                                logger =>
 1594                                "Failed to resolve {}. Error: {}",
 1595                                describe_code_action(&action),
 1596                                err
 1597                            );
 1598                            continue;
 1599                        }
 1600
 1601                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1602                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1603                            // but filters out and logs warnings for code actions that cause unreasonably
 1604                            // difficult handling on our part, such as:
 1605                            // - applying edits that call commands
 1606                            //   which can result in arbitrary workspace edits being sent from the server that
 1607                            //   have no way of being tied back to the command that initiated them (i.e. we
 1608                            //   can't know which edits are part of the format request, or if the server is done sending
 1609                            //   actions in response to the command)
 1610                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1611                            //   as we then would need to handle such changes correctly in the local history as well
 1612                            //   as the remote history through the ProjectTransaction
 1613                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1614                            // Supporting these actions is not impossible, but not supported as of yet.
 1615                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1616                                zlog::trace!(
 1617                                    logger =>
 1618                                    "No changes for code action. Skipping {}",
 1619                                    describe_code_action(&action),
 1620                                );
 1621                                continue;
 1622                            }
 1623
 1624                            let mut operations = Vec::new();
 1625                            if let Some(document_changes) = edit.document_changes {
 1626                                match document_changes {
 1627                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1628                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1629                                    ),
 1630                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1631                                }
 1632                            } else if let Some(changes) = edit.changes {
 1633                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1634                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1635                                        text_document:
 1636                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1637                                                uri,
 1638                                                version: None,
 1639                                            },
 1640                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1641                                    })
 1642                                }));
 1643                            }
 1644
 1645                            let mut edits = Vec::with_capacity(operations.len());
 1646
 1647                            if operations.is_empty() {
 1648                                zlog::trace!(
 1649                                    logger =>
 1650                                    "No changes for code action. Skipping {}",
 1651                                    describe_code_action(&action),
 1652                                );
 1653                                continue;
 1654                            }
 1655                            for operation in operations {
 1656                                let op = match operation {
 1657                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1658                                    lsp::DocumentChangeOperation::Op(_) => {
 1659                                        zlog::warn!(
 1660                                            logger =>
 1661                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1662                                            describe_code_action(&action),
 1663                                        );
 1664                                        continue 'actions;
 1665                                    }
 1666                                };
 1667                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1668                                    zlog::warn!(
 1669                                        logger =>
 1670                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1671                                        &op.text_document.uri,
 1672                                        describe_code_action(&action),
 1673                                    );
 1674                                    continue 'actions;
 1675                                };
 1676                                if &file_path != buffer_path_abs {
 1677                                    zlog::warn!(
 1678                                        logger =>
 1679                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1680                                        file_path,
 1681                                        buffer_path_abs,
 1682                                        describe_code_action(&action),
 1683                                    );
 1684                                    continue 'actions;
 1685                                }
 1686
 1687                                let mut lsp_edits = Vec::new();
 1688                                for edit in op.edits {
 1689                                    match edit {
 1690                                        Edit::Plain(edit) => {
 1691                                            if !lsp_edits.contains(&edit) {
 1692                                                lsp_edits.push(edit);
 1693                                            }
 1694                                        }
 1695                                        Edit::Annotated(edit) => {
 1696                                            if !lsp_edits.contains(&edit.text_edit) {
 1697                                                lsp_edits.push(edit.text_edit);
 1698                                            }
 1699                                        }
 1700                                        Edit::Snippet(_) => {
 1701                                            zlog::warn!(
 1702                                                logger =>
 1703                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1704                                                describe_code_action(&action),
 1705                                            );
 1706                                            continue 'actions;
 1707                                        }
 1708                                    }
 1709                                }
 1710                                let edits_result = lsp_store
 1711                                    .update(cx, |lsp_store, cx| {
 1712                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1713                                            &buffer.handle,
 1714                                            lsp_edits,
 1715                                            server.server_id(),
 1716                                            op.text_document.version,
 1717                                            cx,
 1718                                        )
 1719                                    })?
 1720                                    .await;
 1721                                let Ok(resolved_edits) = edits_result else {
 1722                                    zlog::warn!(
 1723                                        logger =>
 1724                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1725                                        buffer_path_abs.as_path(),
 1726                                        describe_code_action(&action),
 1727                                    );
 1728                                    continue 'actions;
 1729                                };
 1730                                edits.extend(resolved_edits);
 1731                            }
 1732
 1733                            if edits.is_empty() {
 1734                                zlog::warn!(logger => "No edits resolved from LSP");
 1735                                continue;
 1736                            }
 1737
 1738                            extend_formatting_transaction(
 1739                                buffer,
 1740                                formatting_transaction_id,
 1741                                cx,
 1742                                |buffer, cx| {
 1743                                    buffer.edit(edits, None, cx);
 1744                                },
 1745                            )?;
 1746                        }
 1747
 1748                        if let Some(command) = action.lsp_action.command() {
 1749                            zlog::warn!(
 1750                                logger =>
 1751                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1752                                &command.command,
 1753                            );
 1754
 1755                            // bail early if command is invalid
 1756                            let server_capabilities = server.capabilities();
 1757                            let available_commands = server_capabilities
 1758                                .execute_command_provider
 1759                                .as_ref()
 1760                                .map(|options| options.commands.as_slice())
 1761                                .unwrap_or_default();
 1762                            if !available_commands.contains(&command.command) {
 1763                                zlog::warn!(
 1764                                    logger =>
 1765                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1766                                    command.command,
 1767                                    server.name(),
 1768                                );
 1769                                continue;
 1770                            }
 1771
 1772                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1773                            extend_formatting_transaction(
 1774                                buffer,
 1775                                formatting_transaction_id,
 1776                                cx,
 1777                                |_, _| {},
 1778                            )?;
 1779                            zlog::info!(logger => "Executing command {}", &command.command);
 1780
 1781                            lsp_store.update(cx, |this, _| {
 1782                                this.as_local_mut()
 1783                                    .unwrap()
 1784                                    .last_workspace_edits_by_language_server
 1785                                    .remove(&server.server_id());
 1786                            })?;
 1787
 1788                            let execute_command_result = server
 1789                                .request::<lsp::request::ExecuteCommand>(
 1790                                    lsp::ExecuteCommandParams {
 1791                                        command: command.command.clone(),
 1792                                        arguments: command.arguments.clone().unwrap_or_default(),
 1793                                        ..Default::default()
 1794                                    },
 1795                                )
 1796                                .await
 1797                                .into_response();
 1798
 1799                            if execute_command_result.is_err() {
 1800                                zlog::error!(
 1801                                    logger =>
 1802                                    "Failed to execute command '{}' as part of {}",
 1803                                    &command.command,
 1804                                    describe_code_action(&action),
 1805                                );
 1806                                continue 'actions;
 1807                            }
 1808
 1809                            let mut project_transaction_command =
 1810                                lsp_store.update(cx, |this, _| {
 1811                                    this.as_local_mut()
 1812                                        .unwrap()
 1813                                        .last_workspace_edits_by_language_server
 1814                                        .remove(&server.server_id())
 1815                                        .unwrap_or_default()
 1816                                })?;
 1817
 1818                            if let Some(transaction) =
 1819                                project_transaction_command.0.remove(&buffer.handle)
 1820                            {
 1821                                zlog::trace!(
 1822                                    logger =>
 1823                                    "Successfully captured {} edits that resulted from command {}",
 1824                                    transaction.edit_ids.len(),
 1825                                    &command.command,
 1826                                );
 1827                                let transaction_id_project_transaction = transaction.id;
 1828                                buffer.handle.update(cx, |buffer, _| {
 1829                                    // it may have been removed from history if push_to_history was
 1830                                    // false in deserialize_workspace_edit. If so push it so we
 1831                                    // can merge it with the format transaction
 1832                                    // and pop the combined transaction off the history stack
 1833                                    // later if push_to_history is false
 1834                                    if buffer.get_transaction(transaction.id).is_none() {
 1835                                        buffer.push_transaction(transaction, Instant::now());
 1836                                    }
 1837                                    buffer.merge_transactions(
 1838                                        transaction_id_project_transaction,
 1839                                        formatting_transaction_id,
 1840                                    );
 1841                                })?;
 1842                            }
 1843
 1844                            if !project_transaction_command.0.is_empty() {
 1845                                let mut extra_buffers = String::new();
 1846                                for buffer in project_transaction_command.0.keys() {
 1847                                    buffer
 1848                                        .read_with(cx, |b, cx| {
 1849                                            if let Some(path) = b.project_path(cx) {
 1850                                                if !extra_buffers.is_empty() {
 1851                                                    extra_buffers.push_str(", ");
 1852                                                }
 1853                                                extra_buffers.push_str(path.path.as_unix_str());
 1854                                            }
 1855                                        })
 1856                                        .ok();
 1857                                }
 1858                                zlog::warn!(
 1859                                    logger =>
 1860                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1861                                    &command.command,
 1862                                    extra_buffers,
 1863                                );
 1864                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1865                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1866                                // add it so it's included, and merge it into the format transaction when its created later
 1867                            }
 1868                        }
 1869                    }
 1870                }
 1871            }
 1872        }
 1873
 1874        Ok(())
 1875    }
 1876
 1877    pub async fn format_ranges_via_lsp(
 1878        this: &WeakEntity<LspStore>,
 1879        buffer_handle: &Entity<Buffer>,
 1880        ranges: &[Range<Anchor>],
 1881        abs_path: &Path,
 1882        language_server: &Arc<LanguageServer>,
 1883        settings: &LanguageSettings,
 1884        cx: &mut AsyncApp,
 1885    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1886        let capabilities = &language_server.capabilities();
 1887        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1888        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1889            anyhow::bail!(
 1890                "{} language server does not support range formatting",
 1891                language_server.name()
 1892            );
 1893        }
 1894
 1895        let uri = file_path_to_lsp_url(abs_path)?;
 1896        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1897
 1898        let lsp_edits = {
 1899            let mut lsp_ranges = Vec::new();
 1900            this.update(cx, |_this, cx| {
 1901                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1902                // not have been sent to the language server. This seems like a fairly systemic
 1903                // issue, though, the resolution probably is not specific to formatting.
 1904                //
 1905                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1906                // LSP.
 1907                let snapshot = buffer_handle.read(cx).snapshot();
 1908                for range in ranges {
 1909                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1910                }
 1911                anyhow::Ok(())
 1912            })??;
 1913
 1914            let mut edits = None;
 1915            for range in lsp_ranges {
 1916                if let Some(mut edit) = language_server
 1917                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1918                        text_document: text_document.clone(),
 1919                        range,
 1920                        options: lsp_command::lsp_formatting_options(settings),
 1921                        work_done_progress_params: Default::default(),
 1922                    })
 1923                    .await
 1924                    .into_response()?
 1925                {
 1926                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 1927                }
 1928            }
 1929            edits
 1930        };
 1931
 1932        if let Some(lsp_edits) = lsp_edits {
 1933            this.update(cx, |this, cx| {
 1934                this.as_local_mut().unwrap().edits_from_lsp(
 1935                    buffer_handle,
 1936                    lsp_edits,
 1937                    language_server.server_id(),
 1938                    None,
 1939                    cx,
 1940                )
 1941            })?
 1942            .await
 1943        } else {
 1944            Ok(Vec::with_capacity(0))
 1945        }
 1946    }
 1947
 1948    async fn format_via_lsp(
 1949        this: &WeakEntity<LspStore>,
 1950        buffer: &Entity<Buffer>,
 1951        abs_path: &Path,
 1952        language_server: &Arc<LanguageServer>,
 1953        settings: &LanguageSettings,
 1954        cx: &mut AsyncApp,
 1955    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1956        let logger = zlog::scoped!("lsp_format");
 1957        zlog::info!(logger => "Formatting via LSP");
 1958
 1959        let uri = file_path_to_lsp_url(abs_path)?;
 1960        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1961        let capabilities = &language_server.capabilities();
 1962
 1963        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 1964        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1965
 1966        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1967            let _timer = zlog::time!(logger => "format-full");
 1968            language_server
 1969                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 1970                    text_document,
 1971                    options: lsp_command::lsp_formatting_options(settings),
 1972                    work_done_progress_params: Default::default(),
 1973                })
 1974                .await
 1975                .into_response()?
 1976        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1977            let _timer = zlog::time!(logger => "format-range");
 1978            let buffer_start = lsp::Position::new(0, 0);
 1979            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 1980            language_server
 1981                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1982                    text_document: text_document.clone(),
 1983                    range: lsp::Range::new(buffer_start, buffer_end),
 1984                    options: lsp_command::lsp_formatting_options(settings),
 1985                    work_done_progress_params: Default::default(),
 1986                })
 1987                .await
 1988                .into_response()?
 1989        } else {
 1990            None
 1991        };
 1992
 1993        if let Some(lsp_edits) = lsp_edits {
 1994            this.update(cx, |this, cx| {
 1995                this.as_local_mut().unwrap().edits_from_lsp(
 1996                    buffer,
 1997                    lsp_edits,
 1998                    language_server.server_id(),
 1999                    None,
 2000                    cx,
 2001                )
 2002            })?
 2003            .await
 2004        } else {
 2005            Ok(Vec::with_capacity(0))
 2006        }
 2007    }
 2008
 2009    async fn format_via_external_command(
 2010        buffer: &FormattableBuffer,
 2011        command: &str,
 2012        arguments: Option<&[String]>,
 2013        cx: &mut AsyncApp,
 2014    ) -> Result<Option<Diff>> {
 2015        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2016            let file = File::from_dyn(buffer.file())?;
 2017            let worktree = file.worktree.read(cx);
 2018            let mut worktree_path = worktree.abs_path().to_path_buf();
 2019            if worktree.root_entry()?.is_file() {
 2020                worktree_path.pop();
 2021            }
 2022            Some(worktree_path)
 2023        })?;
 2024
 2025        let mut child = util::command::new_smol_command(command);
 2026
 2027        if let Some(buffer_env) = buffer.env.as_ref() {
 2028            child.envs(buffer_env);
 2029        }
 2030
 2031        if let Some(working_dir_path) = working_dir_path {
 2032            child.current_dir(working_dir_path);
 2033        }
 2034
 2035        if let Some(arguments) = arguments {
 2036            child.args(arguments.iter().map(|arg| {
 2037                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2038                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2039                } else {
 2040                    arg.replace("{buffer_path}", "Untitled")
 2041                }
 2042            }));
 2043        }
 2044
 2045        let mut child = child
 2046            .stdin(smol::process::Stdio::piped())
 2047            .stdout(smol::process::Stdio::piped())
 2048            .stderr(smol::process::Stdio::piped())
 2049            .spawn()?;
 2050
 2051        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2052        let text = buffer
 2053            .handle
 2054            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2055        for chunk in text.chunks() {
 2056            stdin.write_all(chunk.as_bytes()).await?;
 2057        }
 2058        stdin.flush().await?;
 2059
 2060        let output = child.output().await?;
 2061        anyhow::ensure!(
 2062            output.status.success(),
 2063            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2064            output.status.code(),
 2065            String::from_utf8_lossy(&output.stdout),
 2066            String::from_utf8_lossy(&output.stderr),
 2067        );
 2068
 2069        let stdout = String::from_utf8(output.stdout)?;
 2070        Ok(Some(
 2071            buffer
 2072                .handle
 2073                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2074                .await,
 2075        ))
 2076    }
 2077
 2078    async fn try_resolve_code_action(
 2079        lang_server: &LanguageServer,
 2080        action: &mut CodeAction,
 2081    ) -> anyhow::Result<()> {
 2082        match &mut action.lsp_action {
 2083            LspAction::Action(lsp_action) => {
 2084                if !action.resolved
 2085                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2086                    && lsp_action.data.is_some()
 2087                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2088                {
 2089                    *lsp_action = Box::new(
 2090                        lang_server
 2091                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2092                            .await
 2093                            .into_response()?,
 2094                    );
 2095                }
 2096            }
 2097            LspAction::CodeLens(lens) => {
 2098                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2099                    *lens = lang_server
 2100                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2101                        .await
 2102                        .into_response()?;
 2103                }
 2104            }
 2105            LspAction::Command(_) => {}
 2106        }
 2107
 2108        action.resolved = true;
 2109        anyhow::Ok(())
 2110    }
 2111
 2112    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2113        let buffer = buffer_handle.read(cx);
 2114
 2115        let file = buffer.file().cloned();
 2116
 2117        let Some(file) = File::from_dyn(file.as_ref()) else {
 2118            return;
 2119        };
 2120        if !file.is_local() {
 2121            return;
 2122        }
 2123        let path = ProjectPath::from_file(file, cx);
 2124        let worktree_id = file.worktree_id(cx);
 2125        let language = buffer.language().cloned();
 2126
 2127        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2128            for (server_id, diagnostics) in
 2129                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2130            {
 2131                self.update_buffer_diagnostics(
 2132                    buffer_handle,
 2133                    server_id,
 2134                    None,
 2135                    None,
 2136                    diagnostics,
 2137                    Vec::new(),
 2138                    cx,
 2139                )
 2140                .log_err();
 2141            }
 2142        }
 2143        let Some(language) = language else {
 2144            return;
 2145        };
 2146        let Some(snapshot) = self
 2147            .worktree_store
 2148            .read(cx)
 2149            .worktree_for_id(worktree_id, cx)
 2150            .map(|worktree| worktree.read(cx).snapshot())
 2151        else {
 2152            return;
 2153        };
 2154        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2155
 2156        for server_id in
 2157            self.lsp_tree
 2158                .get(path, language.name(), language.manifest(), &delegate, cx)
 2159        {
 2160            let server = self
 2161                .language_servers
 2162                .get(&server_id)
 2163                .and_then(|server_state| {
 2164                    if let LanguageServerState::Running { server, .. } = server_state {
 2165                        Some(server.clone())
 2166                    } else {
 2167                        None
 2168                    }
 2169                });
 2170            let server = match server {
 2171                Some(server) => server,
 2172                None => continue,
 2173            };
 2174
 2175            buffer_handle.update(cx, |buffer, cx| {
 2176                buffer.set_completion_triggers(
 2177                    server.server_id(),
 2178                    server
 2179                        .capabilities()
 2180                        .completion_provider
 2181                        .as_ref()
 2182                        .and_then(|provider| {
 2183                            provider
 2184                                .trigger_characters
 2185                                .as_ref()
 2186                                .map(|characters| characters.iter().cloned().collect())
 2187                        })
 2188                        .unwrap_or_default(),
 2189                    cx,
 2190                );
 2191            });
 2192        }
 2193    }
 2194
 2195    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2196        buffer.update(cx, |buffer, cx| {
 2197            let Some(language) = buffer.language() else {
 2198                return;
 2199            };
 2200            let path = ProjectPath {
 2201                worktree_id: old_file.worktree_id(cx),
 2202                path: old_file.path.clone(),
 2203            };
 2204            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2205                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2206                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2207            }
 2208        });
 2209    }
 2210
 2211    fn update_buffer_diagnostics(
 2212        &mut self,
 2213        buffer: &Entity<Buffer>,
 2214        server_id: LanguageServerId,
 2215        result_id: Option<String>,
 2216        version: Option<i32>,
 2217        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2218        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2219        cx: &mut Context<LspStore>,
 2220    ) -> Result<()> {
 2221        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2222            Ordering::Equal
 2223                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2224                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2225                .then_with(|| a.severity.cmp(&b.severity))
 2226                .then_with(|| a.message.cmp(&b.message))
 2227        }
 2228
 2229        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2230        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2231        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2232
 2233        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2234            Ordering::Equal
 2235                .then_with(|| a.range.start.cmp(&b.range.start))
 2236                .then_with(|| b.range.end.cmp(&a.range.end))
 2237                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2238        });
 2239
 2240        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2241
 2242        let edits_since_save = std::cell::LazyCell::new(|| {
 2243            let saved_version = buffer.read(cx).saved_version();
 2244            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2245        });
 2246
 2247        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2248
 2249        for (new_diagnostic, entry) in diagnostics {
 2250            let start;
 2251            let end;
 2252            if new_diagnostic && entry.diagnostic.is_disk_based {
 2253                // Some diagnostics are based on files on disk instead of buffers'
 2254                // current contents. Adjust these diagnostics' ranges to reflect
 2255                // any unsaved edits.
 2256                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2257                // and were properly adjusted on reuse.
 2258                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2259                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2260            } else {
 2261                start = entry.range.start;
 2262                end = entry.range.end;
 2263            }
 2264
 2265            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2266                ..snapshot.clip_point_utf16(end, Bias::Right);
 2267
 2268            // Expand empty ranges by one codepoint
 2269            if range.start == range.end {
 2270                // This will be go to the next boundary when being clipped
 2271                range.end.column += 1;
 2272                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2273                if range.start == range.end && range.end.column > 0 {
 2274                    range.start.column -= 1;
 2275                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2276                }
 2277            }
 2278
 2279            sanitized_diagnostics.push(DiagnosticEntry {
 2280                range,
 2281                diagnostic: entry.diagnostic,
 2282            });
 2283        }
 2284        drop(edits_since_save);
 2285
 2286        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2287        buffer.update(cx, |buffer, cx| {
 2288            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2289                self.buffer_pull_diagnostics_result_ids
 2290                    .entry(server_id)
 2291                    .or_default()
 2292                    .insert(abs_path, result_id);
 2293            }
 2294
 2295            buffer.update_diagnostics(server_id, set, cx)
 2296        });
 2297
 2298        Ok(())
 2299    }
 2300
 2301    fn register_language_server_for_invisible_worktree(
 2302        &mut self,
 2303        worktree: &Entity<Worktree>,
 2304        language_server_id: LanguageServerId,
 2305        cx: &mut App,
 2306    ) {
 2307        let worktree = worktree.read(cx);
 2308        let worktree_id = worktree.id();
 2309        debug_assert!(!worktree.is_visible());
 2310        let Some(mut origin_seed) = self
 2311            .language_server_ids
 2312            .iter()
 2313            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2314        else {
 2315            return;
 2316        };
 2317        origin_seed.worktree_id = worktree_id;
 2318        self.language_server_ids
 2319            .entry(origin_seed)
 2320            .or_insert_with(|| UnifiedLanguageServer {
 2321                id: language_server_id,
 2322                project_roots: Default::default(),
 2323            });
 2324    }
 2325
 2326    fn register_buffer_with_language_servers(
 2327        &mut self,
 2328        buffer_handle: &Entity<Buffer>,
 2329        only_register_servers: HashSet<LanguageServerSelector>,
 2330        cx: &mut Context<LspStore>,
 2331    ) {
 2332        let buffer = buffer_handle.read(cx);
 2333        let buffer_id = buffer.remote_id();
 2334
 2335        let Some(file) = File::from_dyn(buffer.file()) else {
 2336            return;
 2337        };
 2338        if !file.is_local() {
 2339            return;
 2340        }
 2341
 2342        let abs_path = file.abs_path(cx);
 2343        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2344            return;
 2345        };
 2346        let initial_snapshot = buffer.text_snapshot();
 2347        let worktree_id = file.worktree_id(cx);
 2348
 2349        let Some(language) = buffer.language().cloned() else {
 2350            return;
 2351        };
 2352        let path: Arc<RelPath> = file
 2353            .path()
 2354            .parent()
 2355            .map(Arc::from)
 2356            .unwrap_or_else(|| file.path().clone());
 2357        let Some(worktree) = self
 2358            .worktree_store
 2359            .read(cx)
 2360            .worktree_for_id(worktree_id, cx)
 2361        else {
 2362            return;
 2363        };
 2364        let language_name = language.name();
 2365        let (reused, delegate, servers) = self
 2366            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2367            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2368            .unwrap_or_else(|| {
 2369                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2370                let delegate: Arc<dyn ManifestDelegate> =
 2371                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2372
 2373                let servers = self
 2374                    .lsp_tree
 2375                    .walk(
 2376                        ProjectPath { worktree_id, path },
 2377                        language.name(),
 2378                        language.manifest(),
 2379                        &delegate,
 2380                        cx,
 2381                    )
 2382                    .collect::<Vec<_>>();
 2383                (false, lsp_delegate, servers)
 2384            });
 2385        let servers_and_adapters = servers
 2386            .into_iter()
 2387            .filter_map(|server_node| {
 2388                if reused && server_node.server_id().is_none() {
 2389                    return None;
 2390                }
 2391                if !only_register_servers.is_empty() {
 2392                    if let Some(server_id) = server_node.server_id()
 2393                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2394                    {
 2395                        return None;
 2396                    }
 2397                    if let Some(name) = server_node.name()
 2398                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2399                    {
 2400                        return None;
 2401                    }
 2402                }
 2403
 2404                let server_id = server_node.server_id_or_init(|disposition| {
 2405                    let path = &disposition.path;
 2406
 2407                    {
 2408                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2409
 2410                        let server_id = self.get_or_insert_language_server(
 2411                            &worktree,
 2412                            delegate.clone(),
 2413                            disposition,
 2414                            &language_name,
 2415                            cx,
 2416                        );
 2417
 2418                        if let Some(state) = self.language_servers.get(&server_id)
 2419                            && let Ok(uri) = uri
 2420                        {
 2421                            state.add_workspace_folder(uri);
 2422                        };
 2423                        server_id
 2424                    }
 2425                })?;
 2426                let server_state = self.language_servers.get(&server_id)?;
 2427                if let LanguageServerState::Running {
 2428                    server, adapter, ..
 2429                } = server_state
 2430                {
 2431                    Some((server.clone(), adapter.clone()))
 2432                } else {
 2433                    None
 2434                }
 2435            })
 2436            .collect::<Vec<_>>();
 2437        for (server, adapter) in servers_and_adapters {
 2438            buffer_handle.update(cx, |buffer, cx| {
 2439                buffer.set_completion_triggers(
 2440                    server.server_id(),
 2441                    server
 2442                        .capabilities()
 2443                        .completion_provider
 2444                        .as_ref()
 2445                        .and_then(|provider| {
 2446                            provider
 2447                                .trigger_characters
 2448                                .as_ref()
 2449                                .map(|characters| characters.iter().cloned().collect())
 2450                        })
 2451                        .unwrap_or_default(),
 2452                    cx,
 2453                );
 2454            });
 2455
 2456            let snapshot = LspBufferSnapshot {
 2457                version: 0,
 2458                snapshot: initial_snapshot.clone(),
 2459            };
 2460
 2461            let mut registered = false;
 2462            self.buffer_snapshots
 2463                .entry(buffer_id)
 2464                .or_default()
 2465                .entry(server.server_id())
 2466                .or_insert_with(|| {
 2467                    registered = true;
 2468                    server.register_buffer(
 2469                        uri.clone(),
 2470                        adapter.language_id(&language.name()),
 2471                        0,
 2472                        initial_snapshot.text(),
 2473                    );
 2474
 2475                    vec![snapshot]
 2476                });
 2477
 2478            self.buffers_opened_in_servers
 2479                .entry(buffer_id)
 2480                .or_default()
 2481                .insert(server.server_id());
 2482            if registered {
 2483                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2484                    language_server_id: server.server_id(),
 2485                    name: None,
 2486                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2487                        proto::RegisteredForBuffer {
 2488                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 2489                            buffer_id: buffer_id.to_proto(),
 2490                        },
 2491                    ),
 2492                });
 2493            }
 2494        }
 2495    }
 2496
 2497    fn reuse_existing_language_server<'lang_name>(
 2498        &self,
 2499        server_tree: &LanguageServerTree,
 2500        worktree: &Entity<Worktree>,
 2501        language_name: &'lang_name LanguageName,
 2502        cx: &mut App,
 2503    ) -> Option<(
 2504        Arc<LocalLspAdapterDelegate>,
 2505        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2506    )> {
 2507        if worktree.read(cx).is_visible() {
 2508            return None;
 2509        }
 2510
 2511        let worktree_store = self.worktree_store.read(cx);
 2512        let servers = server_tree
 2513            .instances
 2514            .iter()
 2515            .filter(|(worktree_id, _)| {
 2516                worktree_store
 2517                    .worktree_for_id(**worktree_id, cx)
 2518                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2519            })
 2520            .flat_map(|(worktree_id, servers)| {
 2521                servers
 2522                    .roots
 2523                    .iter()
 2524                    .flat_map(|(_, language_servers)| language_servers)
 2525                    .map(move |(_, (server_node, server_languages))| {
 2526                        (worktree_id, server_node, server_languages)
 2527                    })
 2528                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2529                    .map(|(worktree_id, server_node, _)| {
 2530                        (
 2531                            *worktree_id,
 2532                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2533                        )
 2534                    })
 2535            })
 2536            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2537                acc.entry(worktree_id)
 2538                    .or_insert_with(Vec::new)
 2539                    .push(server_node);
 2540                acc
 2541            })
 2542            .into_values()
 2543            .max_by_key(|servers| servers.len())?;
 2544
 2545        let worktree_id = worktree.read(cx).id();
 2546        let apply = move |tree: &mut LanguageServerTree| {
 2547            for server_node in &servers {
 2548                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2549            }
 2550            servers
 2551        };
 2552
 2553        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2554        Some((delegate, apply))
 2555    }
 2556
 2557    pub(crate) fn unregister_old_buffer_from_language_servers(
 2558        &mut self,
 2559        buffer: &Entity<Buffer>,
 2560        old_file: &File,
 2561        cx: &mut App,
 2562    ) {
 2563        let old_path = match old_file.as_local() {
 2564            Some(local) => local.abs_path(cx),
 2565            None => return,
 2566        };
 2567
 2568        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2569            debug_panic!("{old_path:?} is not parseable as an URI");
 2570            return;
 2571        };
 2572        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2573    }
 2574
 2575    pub(crate) fn unregister_buffer_from_language_servers(
 2576        &mut self,
 2577        buffer: &Entity<Buffer>,
 2578        file_url: &lsp::Uri,
 2579        cx: &mut App,
 2580    ) {
 2581        buffer.update(cx, |buffer, cx| {
 2582            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2583
 2584            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2585                language_server.unregister_buffer(file_url.clone());
 2586            }
 2587        });
 2588    }
 2589
 2590    fn buffer_snapshot_for_lsp_version(
 2591        &mut self,
 2592        buffer: &Entity<Buffer>,
 2593        server_id: LanguageServerId,
 2594        version: Option<i32>,
 2595        cx: &App,
 2596    ) -> Result<TextBufferSnapshot> {
 2597        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2598
 2599        if let Some(version) = version {
 2600            let buffer_id = buffer.read(cx).remote_id();
 2601            let snapshots = if let Some(snapshots) = self
 2602                .buffer_snapshots
 2603                .get_mut(&buffer_id)
 2604                .and_then(|m| m.get_mut(&server_id))
 2605            {
 2606                snapshots
 2607            } else if version == 0 {
 2608                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2609                // We detect this case and treat it as if the version was `None`.
 2610                return Ok(buffer.read(cx).text_snapshot());
 2611            } else {
 2612                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2613            };
 2614
 2615            let found_snapshot = snapshots
 2616                    .binary_search_by_key(&version, |e| e.version)
 2617                    .map(|ix| snapshots[ix].snapshot.clone())
 2618                    .map_err(|_| {
 2619                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2620                    })?;
 2621
 2622            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2623            Ok(found_snapshot)
 2624        } else {
 2625            Ok((buffer.read(cx)).text_snapshot())
 2626        }
 2627    }
 2628
 2629    async fn get_server_code_actions_from_action_kinds(
 2630        lsp_store: &WeakEntity<LspStore>,
 2631        language_server_id: LanguageServerId,
 2632        code_action_kinds: Vec<lsp::CodeActionKind>,
 2633        buffer: &Entity<Buffer>,
 2634        cx: &mut AsyncApp,
 2635    ) -> Result<Vec<CodeAction>> {
 2636        let actions = lsp_store
 2637            .update(cx, move |this, cx| {
 2638                let request = GetCodeActions {
 2639                    range: text::Anchor::MIN..text::Anchor::MAX,
 2640                    kinds: Some(code_action_kinds),
 2641                };
 2642                let server = LanguageServerToQuery::Other(language_server_id);
 2643                this.request_lsp(buffer.clone(), server, request, cx)
 2644            })?
 2645            .await?;
 2646        Ok(actions)
 2647    }
 2648
 2649    pub async fn execute_code_actions_on_server(
 2650        lsp_store: &WeakEntity<LspStore>,
 2651        language_server: &Arc<LanguageServer>,
 2652
 2653        actions: Vec<CodeAction>,
 2654        push_to_history: bool,
 2655        project_transaction: &mut ProjectTransaction,
 2656        cx: &mut AsyncApp,
 2657    ) -> anyhow::Result<()> {
 2658        for mut action in actions {
 2659            Self::try_resolve_code_action(language_server, &mut action)
 2660                .await
 2661                .context("resolving a formatting code action")?;
 2662
 2663            if let Some(edit) = action.lsp_action.edit() {
 2664                if edit.changes.is_none() && edit.document_changes.is_none() {
 2665                    continue;
 2666                }
 2667
 2668                let new = Self::deserialize_workspace_edit(
 2669                    lsp_store.upgrade().context("project dropped")?,
 2670                    edit.clone(),
 2671                    push_to_history,
 2672                    language_server.clone(),
 2673                    cx,
 2674                )
 2675                .await?;
 2676                project_transaction.0.extend(new.0);
 2677            }
 2678
 2679            if let Some(command) = action.lsp_action.command() {
 2680                let server_capabilities = language_server.capabilities();
 2681                let available_commands = server_capabilities
 2682                    .execute_command_provider
 2683                    .as_ref()
 2684                    .map(|options| options.commands.as_slice())
 2685                    .unwrap_or_default();
 2686                if available_commands.contains(&command.command) {
 2687                    lsp_store.update(cx, |lsp_store, _| {
 2688                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2689                            mode.last_workspace_edits_by_language_server
 2690                                .remove(&language_server.server_id());
 2691                        }
 2692                    })?;
 2693
 2694                    language_server
 2695                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2696                            command: command.command.clone(),
 2697                            arguments: command.arguments.clone().unwrap_or_default(),
 2698                            ..Default::default()
 2699                        })
 2700                        .await
 2701                        .into_response()
 2702                        .context("execute command")?;
 2703
 2704                    lsp_store.update(cx, |this, _| {
 2705                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2706                            project_transaction.0.extend(
 2707                                mode.last_workspace_edits_by_language_server
 2708                                    .remove(&language_server.server_id())
 2709                                    .unwrap_or_default()
 2710                                    .0,
 2711                            )
 2712                        }
 2713                    })?;
 2714                } else {
 2715                    log::warn!(
 2716                        "Cannot execute a command {} not listed in the language server capabilities",
 2717                        command.command
 2718                    )
 2719                }
 2720            }
 2721        }
 2722        Ok(())
 2723    }
 2724
 2725    pub async fn deserialize_text_edits(
 2726        this: Entity<LspStore>,
 2727        buffer_to_edit: Entity<Buffer>,
 2728        edits: Vec<lsp::TextEdit>,
 2729        push_to_history: bool,
 2730        _: Arc<CachedLspAdapter>,
 2731        language_server: Arc<LanguageServer>,
 2732        cx: &mut AsyncApp,
 2733    ) -> Result<Option<Transaction>> {
 2734        let edits = this
 2735            .update(cx, |this, cx| {
 2736                this.as_local_mut().unwrap().edits_from_lsp(
 2737                    &buffer_to_edit,
 2738                    edits,
 2739                    language_server.server_id(),
 2740                    None,
 2741                    cx,
 2742                )
 2743            })?
 2744            .await?;
 2745
 2746        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2747            buffer.finalize_last_transaction();
 2748            buffer.start_transaction();
 2749            for (range, text) in edits {
 2750                buffer.edit([(range, text)], None, cx);
 2751            }
 2752
 2753            if buffer.end_transaction(cx).is_some() {
 2754                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2755                if !push_to_history {
 2756                    buffer.forget_transaction(transaction.id);
 2757                }
 2758                Some(transaction)
 2759            } else {
 2760                None
 2761            }
 2762        })?;
 2763
 2764        Ok(transaction)
 2765    }
 2766
 2767    #[allow(clippy::type_complexity)]
 2768    pub(crate) fn edits_from_lsp(
 2769        &mut self,
 2770        buffer: &Entity<Buffer>,
 2771        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2772        server_id: LanguageServerId,
 2773        version: Option<i32>,
 2774        cx: &mut Context<LspStore>,
 2775    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2776        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2777        cx.background_spawn(async move {
 2778            let snapshot = snapshot?;
 2779            let mut lsp_edits = lsp_edits
 2780                .into_iter()
 2781                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2782                .collect::<Vec<_>>();
 2783
 2784            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2785
 2786            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2787            let mut edits = Vec::new();
 2788            while let Some((range, mut new_text)) = lsp_edits.next() {
 2789                // Clip invalid ranges provided by the language server.
 2790                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2791                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2792
 2793                // Combine any LSP edits that are adjacent.
 2794                //
 2795                // Also, combine LSP edits that are separated from each other by only
 2796                // a newline. This is important because for some code actions,
 2797                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2798                // are separated by unchanged newline characters.
 2799                //
 2800                // In order for the diffing logic below to work properly, any edits that
 2801                // cancel each other out must be combined into one.
 2802                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2803                    if next_range.start.0 > range.end {
 2804                        if next_range.start.0.row > range.end.row + 1
 2805                            || next_range.start.0.column > 0
 2806                            || snapshot.clip_point_utf16(
 2807                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2808                                Bias::Left,
 2809                            ) > range.end
 2810                        {
 2811                            break;
 2812                        }
 2813                        new_text.push('\n');
 2814                    }
 2815                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2816                    new_text.push_str(next_text);
 2817                    lsp_edits.next();
 2818                }
 2819
 2820                // For multiline edits, perform a diff of the old and new text so that
 2821                // we can identify the changes more precisely, preserving the locations
 2822                // of any anchors positioned in the unchanged regions.
 2823                if range.end.row > range.start.row {
 2824                    let offset = range.start.to_offset(&snapshot);
 2825                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2826                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2827                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2828                        (
 2829                            snapshot.anchor_after(offset + range.start)
 2830                                ..snapshot.anchor_before(offset + range.end),
 2831                            replacement,
 2832                        )
 2833                    }));
 2834                } else if range.end == range.start {
 2835                    let anchor = snapshot.anchor_after(range.start);
 2836                    edits.push((anchor..anchor, new_text.into()));
 2837                } else {
 2838                    let edit_start = snapshot.anchor_after(range.start);
 2839                    let edit_end = snapshot.anchor_before(range.end);
 2840                    edits.push((edit_start..edit_end, new_text.into()));
 2841                }
 2842            }
 2843
 2844            Ok(edits)
 2845        })
 2846    }
 2847
 2848    pub(crate) async fn deserialize_workspace_edit(
 2849        this: Entity<LspStore>,
 2850        edit: lsp::WorkspaceEdit,
 2851        push_to_history: bool,
 2852        language_server: Arc<LanguageServer>,
 2853        cx: &mut AsyncApp,
 2854    ) -> Result<ProjectTransaction> {
 2855        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2856
 2857        let mut operations = Vec::new();
 2858        if let Some(document_changes) = edit.document_changes {
 2859            match document_changes {
 2860                lsp::DocumentChanges::Edits(edits) => {
 2861                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2862                }
 2863                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2864            }
 2865        } else if let Some(changes) = edit.changes {
 2866            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2867                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2868                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2869                        uri,
 2870                        version: None,
 2871                    },
 2872                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2873                })
 2874            }));
 2875        }
 2876
 2877        let mut project_transaction = ProjectTransaction::default();
 2878        for operation in operations {
 2879            match operation {
 2880                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2881                    let abs_path = op
 2882                        .uri
 2883                        .to_file_path()
 2884                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2885
 2886                    if let Some(parent_path) = abs_path.parent() {
 2887                        fs.create_dir(parent_path).await?;
 2888                    }
 2889                    if abs_path.ends_with("/") {
 2890                        fs.create_dir(&abs_path).await?;
 2891                    } else {
 2892                        fs.create_file(
 2893                            &abs_path,
 2894                            op.options
 2895                                .map(|options| fs::CreateOptions {
 2896                                    overwrite: options.overwrite.unwrap_or(false),
 2897                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2898                                })
 2899                                .unwrap_or_default(),
 2900                        )
 2901                        .await?;
 2902                    }
 2903                }
 2904
 2905                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2906                    let source_abs_path = op
 2907                        .old_uri
 2908                        .to_file_path()
 2909                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2910                    let target_abs_path = op
 2911                        .new_uri
 2912                        .to_file_path()
 2913                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2914                    fs.rename(
 2915                        &source_abs_path,
 2916                        &target_abs_path,
 2917                        op.options
 2918                            .map(|options| fs::RenameOptions {
 2919                                overwrite: options.overwrite.unwrap_or(false),
 2920                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2921                            })
 2922                            .unwrap_or_default(),
 2923                    )
 2924                    .await?;
 2925                }
 2926
 2927                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 2928                    let abs_path = op
 2929                        .uri
 2930                        .to_file_path()
 2931                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2932                    let options = op
 2933                        .options
 2934                        .map(|options| fs::RemoveOptions {
 2935                            recursive: options.recursive.unwrap_or(false),
 2936                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 2937                        })
 2938                        .unwrap_or_default();
 2939                    if abs_path.ends_with("/") {
 2940                        fs.remove_dir(&abs_path, options).await?;
 2941                    } else {
 2942                        fs.remove_file(&abs_path, options).await?;
 2943                    }
 2944                }
 2945
 2946                lsp::DocumentChangeOperation::Edit(op) => {
 2947                    let buffer_to_edit = this
 2948                        .update(cx, |this, cx| {
 2949                            this.open_local_buffer_via_lsp(
 2950                                op.text_document.uri.clone(),
 2951                                language_server.server_id(),
 2952                                cx,
 2953                            )
 2954                        })?
 2955                        .await?;
 2956
 2957                    let edits = this
 2958                        .update(cx, |this, cx| {
 2959                            let path = buffer_to_edit.read(cx).project_path(cx);
 2960                            let active_entry = this.active_entry;
 2961                            let is_active_entry = path.is_some_and(|project_path| {
 2962                                this.worktree_store
 2963                                    .read(cx)
 2964                                    .entry_for_path(&project_path, cx)
 2965                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 2966                            });
 2967                            let local = this.as_local_mut().unwrap();
 2968
 2969                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 2970                            for edit in op.edits {
 2971                                match edit {
 2972                                    Edit::Plain(edit) => {
 2973                                        if !edits.contains(&edit) {
 2974                                            edits.push(edit)
 2975                                        }
 2976                                    }
 2977                                    Edit::Annotated(edit) => {
 2978                                        if !edits.contains(&edit.text_edit) {
 2979                                            edits.push(edit.text_edit)
 2980                                        }
 2981                                    }
 2982                                    Edit::Snippet(edit) => {
 2983                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 2984                                        else {
 2985                                            continue;
 2986                                        };
 2987
 2988                                        if is_active_entry {
 2989                                            snippet_edits.push((edit.range, snippet));
 2990                                        } else {
 2991                                            // Since this buffer is not focused, apply a normal edit.
 2992                                            let new_edit = TextEdit {
 2993                                                range: edit.range,
 2994                                                new_text: snippet.text,
 2995                                            };
 2996                                            if !edits.contains(&new_edit) {
 2997                                                edits.push(new_edit);
 2998                                            }
 2999                                        }
 3000                                    }
 3001                                }
 3002                            }
 3003                            if !snippet_edits.is_empty() {
 3004                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3005                                let version = if let Some(buffer_version) = op.text_document.version
 3006                                {
 3007                                    local
 3008                                        .buffer_snapshot_for_lsp_version(
 3009                                            &buffer_to_edit,
 3010                                            language_server.server_id(),
 3011                                            Some(buffer_version),
 3012                                            cx,
 3013                                        )
 3014                                        .ok()
 3015                                        .map(|snapshot| snapshot.version)
 3016                                } else {
 3017                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3018                                };
 3019
 3020                                let most_recent_edit = version.and_then(|version| {
 3021                                    version.iter().max_by_key(|timestamp| timestamp.value)
 3022                                });
 3023                                // Check if the edit that triggered that edit has been made by this participant.
 3024
 3025                                if let Some(most_recent_edit) = most_recent_edit {
 3026                                    cx.emit(LspStoreEvent::SnippetEdit {
 3027                                        buffer_id,
 3028                                        edits: snippet_edits,
 3029                                        most_recent_edit,
 3030                                    });
 3031                                }
 3032                            }
 3033
 3034                            local.edits_from_lsp(
 3035                                &buffer_to_edit,
 3036                                edits,
 3037                                language_server.server_id(),
 3038                                op.text_document.version,
 3039                                cx,
 3040                            )
 3041                        })?
 3042                        .await?;
 3043
 3044                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3045                        buffer.finalize_last_transaction();
 3046                        buffer.start_transaction();
 3047                        for (range, text) in edits {
 3048                            buffer.edit([(range, text)], None, cx);
 3049                        }
 3050
 3051                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3052                            if push_to_history {
 3053                                buffer.finalize_last_transaction();
 3054                                buffer.get_transaction(transaction_id).cloned()
 3055                            } else {
 3056                                buffer.forget_transaction(transaction_id)
 3057                            }
 3058                        })
 3059                    })?;
 3060                    if let Some(transaction) = transaction {
 3061                        project_transaction.0.insert(buffer_to_edit, transaction);
 3062                    }
 3063                }
 3064            }
 3065        }
 3066
 3067        Ok(project_transaction)
 3068    }
 3069
 3070    async fn on_lsp_workspace_edit(
 3071        this: WeakEntity<LspStore>,
 3072        params: lsp::ApplyWorkspaceEditParams,
 3073        server_id: LanguageServerId,
 3074        cx: &mut AsyncApp,
 3075    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3076        let this = this.upgrade().context("project project closed")?;
 3077        let language_server = this
 3078            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3079            .context("language server not found")?;
 3080        let transaction = Self::deserialize_workspace_edit(
 3081            this.clone(),
 3082            params.edit,
 3083            true,
 3084            language_server.clone(),
 3085            cx,
 3086        )
 3087        .await
 3088        .log_err();
 3089        this.update(cx, |this, _| {
 3090            if let Some(transaction) = transaction {
 3091                this.as_local_mut()
 3092                    .unwrap()
 3093                    .last_workspace_edits_by_language_server
 3094                    .insert(server_id, transaction);
 3095            }
 3096        })?;
 3097        Ok(lsp::ApplyWorkspaceEditResponse {
 3098            applied: true,
 3099            failed_change: None,
 3100            failure_reason: None,
 3101        })
 3102    }
 3103
 3104    fn remove_worktree(
 3105        &mut self,
 3106        id_to_remove: WorktreeId,
 3107        cx: &mut Context<LspStore>,
 3108    ) -> Vec<LanguageServerId> {
 3109        self.diagnostics.remove(&id_to_remove);
 3110        self.prettier_store.update(cx, |prettier_store, cx| {
 3111            prettier_store.remove_worktree(id_to_remove, cx);
 3112        });
 3113
 3114        let mut servers_to_remove = BTreeSet::default();
 3115        let mut servers_to_preserve = HashSet::default();
 3116        for (seed, state) in &self.language_server_ids {
 3117            if seed.worktree_id == id_to_remove {
 3118                servers_to_remove.insert(state.id);
 3119            } else {
 3120                servers_to_preserve.insert(state.id);
 3121            }
 3122        }
 3123        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3124        self.language_server_ids
 3125            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3126        for server_id_to_remove in &servers_to_remove {
 3127            self.language_server_watched_paths
 3128                .remove(server_id_to_remove);
 3129            self.language_server_paths_watched_for_rename
 3130                .remove(server_id_to_remove);
 3131            self.last_workspace_edits_by_language_server
 3132                .remove(server_id_to_remove);
 3133            self.language_servers.remove(server_id_to_remove);
 3134            self.buffer_pull_diagnostics_result_ids
 3135                .remove(server_id_to_remove);
 3136            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3137                buffer_servers.remove(server_id_to_remove);
 3138            }
 3139            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3140        }
 3141        servers_to_remove.into_iter().collect()
 3142    }
 3143
 3144    fn rebuild_watched_paths_inner<'a>(
 3145        &'a self,
 3146        language_server_id: LanguageServerId,
 3147        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3148        cx: &mut Context<LspStore>,
 3149    ) -> LanguageServerWatchedPathsBuilder {
 3150        let worktrees = self
 3151            .worktree_store
 3152            .read(cx)
 3153            .worktrees()
 3154            .filter_map(|worktree| {
 3155                self.language_servers_for_worktree(worktree.read(cx).id())
 3156                    .find(|server| server.server_id() == language_server_id)
 3157                    .map(|_| worktree)
 3158            })
 3159            .collect::<Vec<_>>();
 3160
 3161        let mut worktree_globs = HashMap::default();
 3162        let mut abs_globs = HashMap::default();
 3163        log::trace!(
 3164            "Processing new watcher paths for language server with id {}",
 3165            language_server_id
 3166        );
 3167
 3168        for watcher in watchers {
 3169            if let Some((worktree, literal_prefix, pattern)) =
 3170                self.worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3171            {
 3172                worktree.update(cx, |worktree, _| {
 3173                    if let Some((tree, glob)) =
 3174                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3175                    {
 3176                        tree.add_path_prefix_to_scan(literal_prefix);
 3177                        worktree_globs
 3178                            .entry(tree.id())
 3179                            .or_insert_with(GlobSetBuilder::new)
 3180                            .add(glob);
 3181                    }
 3182                });
 3183            } else {
 3184                let (path, pattern) = match &watcher.glob_pattern {
 3185                    lsp::GlobPattern::String(s) => {
 3186                        let watcher_path = SanitizedPath::new(s);
 3187                        let path = glob_literal_prefix(watcher_path.as_path());
 3188                        let pattern = watcher_path
 3189                            .as_path()
 3190                            .strip_prefix(&path)
 3191                            .map(|p| p.to_string_lossy().to_string())
 3192                            .unwrap_or_else(|e| {
 3193                                debug_panic!(
 3194                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3195                                    s,
 3196                                    path.display(),
 3197                                    e
 3198                                );
 3199                                watcher_path.as_path().to_string_lossy().to_string()
 3200                            });
 3201                        (path, pattern)
 3202                    }
 3203                    lsp::GlobPattern::Relative(rp) => {
 3204                        let Ok(mut base_uri) = match &rp.base_uri {
 3205                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3206                            lsp::OneOf::Right(base_uri) => base_uri,
 3207                        }
 3208                        .to_file_path() else {
 3209                            continue;
 3210                        };
 3211
 3212                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3213                        let pattern = Path::new(&rp.pattern)
 3214                            .strip_prefix(&path)
 3215                            .map(|p| p.to_string_lossy().to_string())
 3216                            .unwrap_or_else(|e| {
 3217                                debug_panic!(
 3218                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3219                                    rp.pattern,
 3220                                    path.display(),
 3221                                    e
 3222                                );
 3223                                rp.pattern.clone()
 3224                            });
 3225                        base_uri.push(path);
 3226                        (base_uri, pattern)
 3227                    }
 3228                };
 3229
 3230                if let Some(glob) = Glob::new(&pattern).log_err() {
 3231                    if !path
 3232                        .components()
 3233                        .any(|c| matches!(c, path::Component::Normal(_)))
 3234                    {
 3235                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3236                        // rather than adding a new watcher for `/`.
 3237                        for worktree in &worktrees {
 3238                            worktree_globs
 3239                                .entry(worktree.read(cx).id())
 3240                                .or_insert_with(GlobSetBuilder::new)
 3241                                .add(glob.clone());
 3242                        }
 3243                    } else {
 3244                        abs_globs
 3245                            .entry(path.into())
 3246                            .or_insert_with(GlobSetBuilder::new)
 3247                            .add(glob);
 3248                    }
 3249                }
 3250            }
 3251        }
 3252
 3253        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3254        for (worktree_id, builder) in worktree_globs {
 3255            if let Ok(globset) = builder.build() {
 3256                watch_builder.watch_worktree(worktree_id, globset);
 3257            }
 3258        }
 3259        for (abs_path, builder) in abs_globs {
 3260            if let Ok(globset) = builder.build() {
 3261                watch_builder.watch_abs_path(abs_path, globset);
 3262            }
 3263        }
 3264        watch_builder
 3265    }
 3266
 3267    fn worktree_and_path_for_file_watcher(
 3268        &self,
 3269        worktrees: &[Entity<Worktree>],
 3270        watcher: &FileSystemWatcher,
 3271        cx: &App,
 3272    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3273        worktrees.iter().find_map(|worktree| {
 3274            let tree = worktree.read(cx);
 3275            let worktree_root_path = tree.abs_path();
 3276            let path_style = tree.path_style();
 3277            match &watcher.glob_pattern {
 3278                lsp::GlobPattern::String(s) => {
 3279                    let watcher_path = SanitizedPath::new(s);
 3280                    let relative = watcher_path
 3281                        .as_path()
 3282                        .strip_prefix(&worktree_root_path)
 3283                        .ok()?;
 3284                    let literal_prefix = glob_literal_prefix(relative);
 3285                    Some((
 3286                        worktree.clone(),
 3287                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3288                        relative.to_string_lossy().to_string(),
 3289                    ))
 3290                }
 3291                lsp::GlobPattern::Relative(rp) => {
 3292                    let base_uri = match &rp.base_uri {
 3293                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3294                        lsp::OneOf::Right(base_uri) => base_uri,
 3295                    }
 3296                    .to_file_path()
 3297                    .ok()?;
 3298                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3299                    let mut literal_prefix = relative.to_owned();
 3300                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3301                    Some((
 3302                        worktree.clone(),
 3303                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3304                        rp.pattern.clone(),
 3305                    ))
 3306                }
 3307            }
 3308        })
 3309    }
 3310
 3311    fn rebuild_watched_paths(
 3312        &mut self,
 3313        language_server_id: LanguageServerId,
 3314        cx: &mut Context<LspStore>,
 3315    ) {
 3316        let Some(watchers) = self
 3317            .language_server_watcher_registrations
 3318            .get(&language_server_id)
 3319        else {
 3320            return;
 3321        };
 3322
 3323        let watch_builder =
 3324            self.rebuild_watched_paths_inner(language_server_id, watchers.values().flatten(), cx);
 3325        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3326        self.language_server_watched_paths
 3327            .insert(language_server_id, watcher);
 3328
 3329        cx.notify();
 3330    }
 3331
 3332    fn on_lsp_did_change_watched_files(
 3333        &mut self,
 3334        language_server_id: LanguageServerId,
 3335        registration_id: &str,
 3336        params: DidChangeWatchedFilesRegistrationOptions,
 3337        cx: &mut Context<LspStore>,
 3338    ) {
 3339        let registrations = self
 3340            .language_server_watcher_registrations
 3341            .entry(language_server_id)
 3342            .or_default();
 3343
 3344        registrations.insert(registration_id.to_string(), params.watchers);
 3345
 3346        self.rebuild_watched_paths(language_server_id, cx);
 3347    }
 3348
 3349    fn on_lsp_unregister_did_change_watched_files(
 3350        &mut self,
 3351        language_server_id: LanguageServerId,
 3352        registration_id: &str,
 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        if registrations.remove(registration_id).is_some() {
 3361            log::info!(
 3362                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3363                language_server_id,
 3364                registration_id
 3365            );
 3366        } else {
 3367            log::warn!(
 3368                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3369                language_server_id,
 3370                registration_id
 3371            );
 3372        }
 3373
 3374        self.rebuild_watched_paths(language_server_id, cx);
 3375    }
 3376
 3377    async fn initialization_options_for_adapter(
 3378        adapter: Arc<dyn LspAdapter>,
 3379        delegate: &Arc<dyn LspAdapterDelegate>,
 3380    ) -> Result<Option<serde_json::Value>> {
 3381        let Some(mut initialization_config) =
 3382            adapter.clone().initialization_options(delegate).await?
 3383        else {
 3384            return Ok(None);
 3385        };
 3386
 3387        for other_adapter in delegate.registered_lsp_adapters() {
 3388            if other_adapter.name() == adapter.name() {
 3389                continue;
 3390            }
 3391            if let Ok(Some(target_config)) = other_adapter
 3392                .clone()
 3393                .additional_initialization_options(adapter.name(), delegate)
 3394                .await
 3395            {
 3396                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3397            }
 3398        }
 3399
 3400        Ok(Some(initialization_config))
 3401    }
 3402
 3403    async fn workspace_configuration_for_adapter(
 3404        adapter: Arc<dyn LspAdapter>,
 3405        delegate: &Arc<dyn LspAdapterDelegate>,
 3406        toolchain: Option<Toolchain>,
 3407        cx: &mut AsyncApp,
 3408    ) -> Result<serde_json::Value> {
 3409        let mut workspace_config = adapter
 3410            .clone()
 3411            .workspace_configuration(delegate, toolchain, cx)
 3412            .await?;
 3413
 3414        for other_adapter in delegate.registered_lsp_adapters() {
 3415            if other_adapter.name() == adapter.name() {
 3416                continue;
 3417            }
 3418            if let Ok(Some(target_config)) = other_adapter
 3419                .clone()
 3420                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3421                .await
 3422            {
 3423                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3424            }
 3425        }
 3426
 3427        Ok(workspace_config)
 3428    }
 3429
 3430    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3431        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3432            Some(server.clone())
 3433        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3434            Some(Arc::clone(server))
 3435        } else {
 3436            None
 3437        }
 3438    }
 3439}
 3440
 3441fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3442    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3443        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3444            language_server_id: server.server_id(),
 3445            name: Some(server.name()),
 3446            message: proto::update_language_server::Variant::MetadataUpdated(
 3447                proto::ServerMetadataUpdated {
 3448                    capabilities: Some(capabilities),
 3449                },
 3450            ),
 3451        });
 3452    }
 3453}
 3454
 3455#[derive(Debug)]
 3456pub struct FormattableBuffer {
 3457    handle: Entity<Buffer>,
 3458    abs_path: Option<PathBuf>,
 3459    env: Option<HashMap<String, String>>,
 3460    ranges: Option<Vec<Range<Anchor>>>,
 3461}
 3462
 3463pub struct RemoteLspStore {
 3464    upstream_client: Option<AnyProtoClient>,
 3465    upstream_project_id: u64,
 3466}
 3467
 3468pub(crate) enum LspStoreMode {
 3469    Local(LocalLspStore),   // ssh host and collab host
 3470    Remote(RemoteLspStore), // collab guest
 3471}
 3472
 3473impl LspStoreMode {
 3474    fn is_local(&self) -> bool {
 3475        matches!(self, LspStoreMode::Local(_))
 3476    }
 3477}
 3478
 3479pub struct LspStore {
 3480    mode: LspStoreMode,
 3481    last_formatting_failure: Option<String>,
 3482    downstream_client: Option<(AnyProtoClient, u64)>,
 3483    nonce: u128,
 3484    buffer_store: Entity<BufferStore>,
 3485    worktree_store: Entity<WorktreeStore>,
 3486    pub languages: Arc<LanguageRegistry>,
 3487    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3488    active_entry: Option<ProjectEntryId>,
 3489    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3490    _maintain_buffer_languages: Task<()>,
 3491    diagnostic_summaries:
 3492        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3493    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3494    lsp_document_colors: HashMap<BufferId, DocumentColorData>,
 3495    lsp_code_lens: HashMap<BufferId, CodeLensData>,
 3496    running_lsp_requests: HashMap<TypeId, (Global, HashMap<LspRequestId, Task<()>>)>,
 3497}
 3498
 3499#[derive(Debug, Default, Clone)]
 3500pub struct DocumentColors {
 3501    pub colors: HashSet<DocumentColor>,
 3502    pub cache_version: Option<usize>,
 3503}
 3504
 3505type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3506type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3507
 3508#[derive(Debug, Default)]
 3509struct DocumentColorData {
 3510    colors_for_version: Global,
 3511    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3512    cache_version: usize,
 3513    colors_update: Option<(Global, DocumentColorTask)>,
 3514}
 3515
 3516#[derive(Debug, Default)]
 3517struct CodeLensData {
 3518    lens_for_version: Global,
 3519    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3520    update: Option<(Global, CodeLensTask)>,
 3521}
 3522
 3523#[derive(Debug, PartialEq, Eq, Clone, Copy)]
 3524pub enum LspFetchStrategy {
 3525    IgnoreCache,
 3526    UseCache { known_cache_version: Option<usize> },
 3527}
 3528
 3529#[derive(Debug)]
 3530pub enum LspStoreEvent {
 3531    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3532    LanguageServerRemoved(LanguageServerId),
 3533    LanguageServerUpdate {
 3534        language_server_id: LanguageServerId,
 3535        name: Option<LanguageServerName>,
 3536        message: proto::update_language_server::Variant,
 3537    },
 3538    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3539    LanguageServerPrompt(LanguageServerPromptRequest),
 3540    LanguageDetected {
 3541        buffer: Entity<Buffer>,
 3542        new_language: Option<Arc<Language>>,
 3543    },
 3544    Notification(String),
 3545    RefreshInlayHints,
 3546    RefreshCodeLens,
 3547    DiagnosticsUpdated {
 3548        server_id: LanguageServerId,
 3549        paths: Vec<ProjectPath>,
 3550    },
 3551    DiskBasedDiagnosticsStarted {
 3552        language_server_id: LanguageServerId,
 3553    },
 3554    DiskBasedDiagnosticsFinished {
 3555        language_server_id: LanguageServerId,
 3556    },
 3557    SnippetEdit {
 3558        buffer_id: BufferId,
 3559        edits: Vec<(lsp::Range, Snippet)>,
 3560        most_recent_edit: clock::Lamport,
 3561    },
 3562}
 3563
 3564#[derive(Clone, Debug, Serialize)]
 3565pub struct LanguageServerStatus {
 3566    pub name: LanguageServerName,
 3567    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 3568    pub has_pending_diagnostic_updates: bool,
 3569    progress_tokens: HashSet<String>,
 3570    pub worktree: Option<WorktreeId>,
 3571}
 3572
 3573#[derive(Clone, Debug)]
 3574struct CoreSymbol {
 3575    pub language_server_name: LanguageServerName,
 3576    pub source_worktree_id: WorktreeId,
 3577    pub source_language_server_id: LanguageServerId,
 3578    pub path: SymbolLocation,
 3579    pub name: String,
 3580    pub kind: lsp::SymbolKind,
 3581    pub range: Range<Unclipped<PointUtf16>>,
 3582}
 3583
 3584#[derive(Clone, Debug, PartialEq, Eq)]
 3585pub enum SymbolLocation {
 3586    InProject(ProjectPath),
 3587    OutsideProject {
 3588        abs_path: Arc<Path>,
 3589        signature: [u8; 32],
 3590    },
 3591}
 3592
 3593impl SymbolLocation {
 3594    fn file_name(&self) -> Option<&str> {
 3595        match self {
 3596            Self::InProject(path) => path.path.file_name(),
 3597            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3598        }
 3599    }
 3600}
 3601
 3602impl LspStore {
 3603    pub fn init(client: &AnyProtoClient) {
 3604        client.add_entity_request_handler(Self::handle_lsp_query);
 3605        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3606        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3607        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3608        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3609        client.add_entity_message_handler(Self::handle_start_language_server);
 3610        client.add_entity_message_handler(Self::handle_update_language_server);
 3611        client.add_entity_message_handler(Self::handle_language_server_log);
 3612        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3613        client.add_entity_request_handler(Self::handle_format_buffers);
 3614        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3615        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3616        client.add_entity_request_handler(Self::handle_apply_code_action);
 3617        client.add_entity_request_handler(Self::handle_inlay_hints);
 3618        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3619        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3620        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3621        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3622        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3623        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3624        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3625        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3626        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3627        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3628        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3629        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3630        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3631        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3632        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3633        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3634        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3635
 3636        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3637        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3638        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3639        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3640        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3641        client.add_entity_request_handler(
 3642            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3643        );
 3644        client.add_entity_request_handler(
 3645            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3646        );
 3647        client.add_entity_request_handler(
 3648            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3649        );
 3650    }
 3651
 3652    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3653        match &self.mode {
 3654            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3655            _ => None,
 3656        }
 3657    }
 3658
 3659    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3660        match &self.mode {
 3661            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3662            _ => None,
 3663        }
 3664    }
 3665
 3666    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3667        match &mut self.mode {
 3668            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3669            _ => None,
 3670        }
 3671    }
 3672
 3673    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3674        match &self.mode {
 3675            LspStoreMode::Remote(RemoteLspStore {
 3676                upstream_client: Some(upstream_client),
 3677                upstream_project_id,
 3678                ..
 3679            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3680
 3681            LspStoreMode::Remote(RemoteLspStore {
 3682                upstream_client: None,
 3683                ..
 3684            }) => None,
 3685            LspStoreMode::Local(_) => None,
 3686        }
 3687    }
 3688
 3689    pub fn new_local(
 3690        buffer_store: Entity<BufferStore>,
 3691        worktree_store: Entity<WorktreeStore>,
 3692        prettier_store: Entity<PrettierStore>,
 3693        toolchain_store: Entity<LocalToolchainStore>,
 3694        environment: Entity<ProjectEnvironment>,
 3695        manifest_tree: Entity<ManifestTree>,
 3696        languages: Arc<LanguageRegistry>,
 3697        http_client: Arc<dyn HttpClient>,
 3698        fs: Arc<dyn Fs>,
 3699        cx: &mut Context<Self>,
 3700    ) -> Self {
 3701        let yarn = YarnPathStore::new(fs.clone(), cx);
 3702        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3703            .detach();
 3704        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3705            .detach();
 3706        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3707            .detach();
 3708        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3709            .detach();
 3710        if let Some(extension_events) = extension::ExtensionEvents::try_global(cx).as_ref() {
 3711            cx.subscribe(
 3712                extension_events,
 3713                Self::reload_zed_json_schemas_on_extensions_changed,
 3714            )
 3715            .detach();
 3716        } else {
 3717            log::debug!("No extension events global found. Skipping JSON schema auto-reload setup");
 3718        }
 3719        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3720            .detach();
 3721        subscribe_to_binary_statuses(&languages, cx).detach();
 3722
 3723        let _maintain_workspace_config = {
 3724            let (sender, receiver) = watch::channel();
 3725            (Self::maintain_workspace_config(receiver, cx), sender)
 3726        };
 3727
 3728        Self {
 3729            mode: LspStoreMode::Local(LocalLspStore {
 3730                weak: cx.weak_entity(),
 3731                worktree_store: worktree_store.clone(),
 3732
 3733                supplementary_language_servers: Default::default(),
 3734                languages: languages.clone(),
 3735                language_server_ids: Default::default(),
 3736                language_servers: Default::default(),
 3737                last_workspace_edits_by_language_server: Default::default(),
 3738                language_server_watched_paths: Default::default(),
 3739                language_server_paths_watched_for_rename: Default::default(),
 3740                language_server_watcher_registrations: Default::default(),
 3741                buffers_being_formatted: Default::default(),
 3742                buffer_snapshots: Default::default(),
 3743                prettier_store,
 3744                environment,
 3745                http_client,
 3746                fs,
 3747                yarn,
 3748                next_diagnostic_group_id: Default::default(),
 3749                diagnostics: Default::default(),
 3750                _subscription: cx.on_app_quit(|this, cx| {
 3751                    this.as_local_mut()
 3752                        .unwrap()
 3753                        .shutdown_language_servers_on_quit(cx)
 3754                }),
 3755                lsp_tree: LanguageServerTree::new(
 3756                    manifest_tree,
 3757                    languages.clone(),
 3758                    toolchain_store.clone(),
 3759                ),
 3760                toolchain_store,
 3761                registered_buffers: HashMap::default(),
 3762                buffers_opened_in_servers: HashMap::default(),
 3763                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3764                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3765                    .manifest_file_names(),
 3766            }),
 3767            last_formatting_failure: None,
 3768            downstream_client: None,
 3769            buffer_store,
 3770            worktree_store,
 3771            languages: languages.clone(),
 3772            language_server_statuses: Default::default(),
 3773            nonce: StdRng::from_os_rng().random(),
 3774            diagnostic_summaries: HashMap::default(),
 3775            lsp_server_capabilities: HashMap::default(),
 3776            lsp_document_colors: HashMap::default(),
 3777            lsp_code_lens: HashMap::default(),
 3778            running_lsp_requests: HashMap::default(),
 3779            active_entry: None,
 3780            _maintain_workspace_config,
 3781            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3782        }
 3783    }
 3784
 3785    fn send_lsp_proto_request<R: LspCommand>(
 3786        &self,
 3787        buffer: Entity<Buffer>,
 3788        client: AnyProtoClient,
 3789        upstream_project_id: u64,
 3790        request: R,
 3791        cx: &mut Context<LspStore>,
 3792    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3793        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3794            return Task::ready(Ok(R::Response::default()));
 3795        }
 3796        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3797        cx.spawn(async move |this, cx| {
 3798            let response = client.request(message).await?;
 3799            let this = this.upgrade().context("project dropped")?;
 3800            request
 3801                .response_from_proto(response, this, buffer, cx.clone())
 3802                .await
 3803        })
 3804    }
 3805
 3806    pub(super) fn new_remote(
 3807        buffer_store: Entity<BufferStore>,
 3808        worktree_store: Entity<WorktreeStore>,
 3809        languages: Arc<LanguageRegistry>,
 3810        upstream_client: AnyProtoClient,
 3811        project_id: u64,
 3812        cx: &mut Context<Self>,
 3813    ) -> Self {
 3814        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3815            .detach();
 3816        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3817            .detach();
 3818        subscribe_to_binary_statuses(&languages, cx).detach();
 3819        let _maintain_workspace_config = {
 3820            let (sender, receiver) = watch::channel();
 3821            (Self::maintain_workspace_config(receiver, cx), sender)
 3822        };
 3823        Self {
 3824            mode: LspStoreMode::Remote(RemoteLspStore {
 3825                upstream_client: Some(upstream_client),
 3826                upstream_project_id: project_id,
 3827            }),
 3828            downstream_client: None,
 3829            last_formatting_failure: None,
 3830            buffer_store,
 3831            worktree_store,
 3832            languages: languages.clone(),
 3833            language_server_statuses: Default::default(),
 3834            nonce: StdRng::from_os_rng().random(),
 3835            diagnostic_summaries: HashMap::default(),
 3836            lsp_server_capabilities: HashMap::default(),
 3837            lsp_document_colors: HashMap::default(),
 3838            lsp_code_lens: HashMap::default(),
 3839            running_lsp_requests: HashMap::default(),
 3840            active_entry: None,
 3841
 3842            _maintain_workspace_config,
 3843            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3844        }
 3845    }
 3846
 3847    fn on_buffer_store_event(
 3848        &mut self,
 3849        _: Entity<BufferStore>,
 3850        event: &BufferStoreEvent,
 3851        cx: &mut Context<Self>,
 3852    ) {
 3853        match event {
 3854            BufferStoreEvent::BufferAdded(buffer) => {
 3855                self.on_buffer_added(buffer, cx).log_err();
 3856            }
 3857            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3858                let buffer_id = buffer.read(cx).remote_id();
 3859                if let Some(local) = self.as_local_mut()
 3860                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3861                {
 3862                    local.reset_buffer(buffer, old_file, cx);
 3863
 3864                    if local.registered_buffers.contains_key(&buffer_id) {
 3865                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3866                    }
 3867                }
 3868
 3869                self.detect_language_for_buffer(buffer, cx);
 3870                if let Some(local) = self.as_local_mut() {
 3871                    local.initialize_buffer(buffer, cx);
 3872                    if local.registered_buffers.contains_key(&buffer_id) {
 3873                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3874                    }
 3875                }
 3876            }
 3877            _ => {}
 3878        }
 3879    }
 3880
 3881    fn on_worktree_store_event(
 3882        &mut self,
 3883        _: Entity<WorktreeStore>,
 3884        event: &WorktreeStoreEvent,
 3885        cx: &mut Context<Self>,
 3886    ) {
 3887        match event {
 3888            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3889                if !worktree.read(cx).is_local() {
 3890                    return;
 3891                }
 3892                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3893                    worktree::Event::UpdatedEntries(changes) => {
 3894                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 3895                    }
 3896                    worktree::Event::UpdatedGitRepositories(_)
 3897                    | worktree::Event::DeletedEntry(_) => {}
 3898                })
 3899                .detach()
 3900            }
 3901            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 3902            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 3903                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 3904            }
 3905            WorktreeStoreEvent::WorktreeReleased(..)
 3906            | WorktreeStoreEvent::WorktreeOrderChanged
 3907            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 3908            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 3909            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 3910        }
 3911    }
 3912
 3913    fn on_prettier_store_event(
 3914        &mut self,
 3915        _: Entity<PrettierStore>,
 3916        event: &PrettierStoreEvent,
 3917        cx: &mut Context<Self>,
 3918    ) {
 3919        match event {
 3920            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 3921                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 3922            }
 3923            PrettierStoreEvent::LanguageServerAdded {
 3924                new_server_id,
 3925                name,
 3926                prettier_server,
 3927            } => {
 3928                self.register_supplementary_language_server(
 3929                    *new_server_id,
 3930                    name.clone(),
 3931                    prettier_server.clone(),
 3932                    cx,
 3933                );
 3934            }
 3935        }
 3936    }
 3937
 3938    fn on_toolchain_store_event(
 3939        &mut self,
 3940        _: Entity<LocalToolchainStore>,
 3941        event: &ToolchainStoreEvent,
 3942        _: &mut Context<Self>,
 3943    ) {
 3944        if let ToolchainStoreEvent::ToolchainActivated = event {
 3945            self.request_workspace_config_refresh()
 3946        }
 3947    }
 3948
 3949    fn request_workspace_config_refresh(&mut self) {
 3950        *self._maintain_workspace_config.1.borrow_mut() = ();
 3951    }
 3952
 3953    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 3954        self.as_local().map(|local| local.prettier_store.clone())
 3955    }
 3956
 3957    fn on_buffer_event(
 3958        &mut self,
 3959        buffer: Entity<Buffer>,
 3960        event: &language::BufferEvent,
 3961        cx: &mut Context<Self>,
 3962    ) {
 3963        match event {
 3964            language::BufferEvent::Edited => {
 3965                self.on_buffer_edited(buffer, cx);
 3966            }
 3967
 3968            language::BufferEvent::Saved => {
 3969                self.on_buffer_saved(buffer, cx);
 3970            }
 3971
 3972            _ => {}
 3973        }
 3974    }
 3975
 3976    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 3977        buffer
 3978            .read(cx)
 3979            .set_language_registry(self.languages.clone());
 3980
 3981        cx.subscribe(buffer, |this, buffer, event, cx| {
 3982            this.on_buffer_event(buffer, event, cx);
 3983        })
 3984        .detach();
 3985
 3986        self.detect_language_for_buffer(buffer, cx);
 3987        if let Some(local) = self.as_local_mut() {
 3988            local.initialize_buffer(buffer, cx);
 3989        }
 3990
 3991        Ok(())
 3992    }
 3993
 3994    pub fn reload_zed_json_schemas_on_extensions_changed(
 3995        &mut self,
 3996        _: Entity<extension::ExtensionEvents>,
 3997        evt: &extension::Event,
 3998        cx: &mut Context<Self>,
 3999    ) {
 4000        match evt {
 4001            extension::Event::ExtensionInstalled(_)
 4002            | extension::Event::ExtensionUninstalled(_)
 4003            | extension::Event::ConfigureExtensionRequested(_) => return,
 4004            extension::Event::ExtensionsInstalledChanged => {}
 4005        }
 4006        if self.as_local().is_none() {
 4007            return;
 4008        }
 4009        cx.spawn(async move |this, cx| {
 4010            let weak_ref = this.clone();
 4011
 4012            let servers = this
 4013                .update(cx, |this, cx| {
 4014                    let local = this.as_local()?;
 4015
 4016                    let mut servers = Vec::new();
 4017                    for (seed, state) in &local.language_server_ids {
 4018
 4019                            let Some(states) = local.language_servers.get(&state.id) else {
 4020                                continue;
 4021                            };
 4022                            let (json_adapter, json_server) = match states {
 4023                                LanguageServerState::Running {
 4024                                    adapter, server, ..
 4025                                } if adapter.adapter.is_primary_zed_json_schema_adapter() => {
 4026                                    (adapter.adapter.clone(), server.clone())
 4027                                }
 4028                                _ => continue,
 4029                            };
 4030
 4031                            let Some(worktree) = this
 4032                                .worktree_store
 4033                                .read(cx)
 4034                                .worktree_for_id(seed.worktree_id, cx)
 4035                            else {
 4036                                continue;
 4037                            };
 4038                            let json_delegate: Arc<dyn LspAdapterDelegate> =
 4039                                LocalLspAdapterDelegate::new(
 4040                                    local.languages.clone(),
 4041                                    &local.environment,
 4042                                    weak_ref.clone(),
 4043                                    &worktree,
 4044                                    local.http_client.clone(),
 4045                                    local.fs.clone(),
 4046                                    cx,
 4047                                );
 4048
 4049                            servers.push((json_adapter, json_server, json_delegate));
 4050
 4051                    }
 4052                    Some(servers)
 4053                })
 4054                .ok()
 4055                .flatten();
 4056
 4057            let Some(servers) = servers else {
 4058                return;
 4059            };
 4060
 4061            for (adapter, server, delegate) in servers {
 4062                adapter.clear_zed_json_schema_cache().await;
 4063
 4064                let Some(json_workspace_config) = LocalLspStore::workspace_configuration_for_adapter(
 4065                        adapter,
 4066                        &delegate,
 4067                        None,
 4068                        cx,
 4069                    )
 4070                    .await
 4071                    .context("generate new workspace configuration for JSON language server while trying to refresh JSON Schemas")
 4072                    .ok()
 4073                else {
 4074                    continue;
 4075                };
 4076                server
 4077                    .notify::<lsp::notification::DidChangeConfiguration>(
 4078                        &lsp::DidChangeConfigurationParams {
 4079                            settings: json_workspace_config,
 4080                        },
 4081                    )
 4082                    .ok();
 4083            }
 4084        })
 4085        .detach();
 4086    }
 4087
 4088    pub(crate) fn register_buffer_with_language_servers(
 4089        &mut self,
 4090        buffer: &Entity<Buffer>,
 4091        only_register_servers: HashSet<LanguageServerSelector>,
 4092        ignore_refcounts: bool,
 4093        cx: &mut Context<Self>,
 4094    ) -> OpenLspBufferHandle {
 4095        let buffer_id = buffer.read(cx).remote_id();
 4096        let handle = cx.new(|_| buffer.clone());
 4097        if let Some(local) = self.as_local_mut() {
 4098            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4099            if !ignore_refcounts {
 4100                *refcount += 1;
 4101            }
 4102
 4103            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4104            // 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
 4105            // 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
 4106            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4107            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4108                return handle;
 4109            };
 4110            if !file.is_local() {
 4111                return handle;
 4112            }
 4113
 4114            if ignore_refcounts || *refcount == 1 {
 4115                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4116            }
 4117            if !ignore_refcounts {
 4118                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4119                    let refcount = {
 4120                        let local = lsp_store.as_local_mut().unwrap();
 4121                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4122                            debug_panic!("bad refcounting");
 4123                            return;
 4124                        };
 4125
 4126                        *refcount -= 1;
 4127                        *refcount
 4128                    };
 4129                    if refcount == 0 {
 4130                        lsp_store.lsp_document_colors.remove(&buffer_id);
 4131                        lsp_store.lsp_code_lens.remove(&buffer_id);
 4132                        let local = lsp_store.as_local_mut().unwrap();
 4133                        local.registered_buffers.remove(&buffer_id);
 4134                        local.buffers_opened_in_servers.remove(&buffer_id);
 4135                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4136                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4137                        }
 4138                    }
 4139                })
 4140                .detach();
 4141            }
 4142        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4143            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4144            cx.background_spawn(async move {
 4145                upstream_client
 4146                    .request(proto::RegisterBufferWithLanguageServers {
 4147                        project_id: upstream_project_id,
 4148                        buffer_id,
 4149                        only_servers: only_register_servers
 4150                            .into_iter()
 4151                            .map(|selector| {
 4152                                let selector = match selector {
 4153                                    LanguageServerSelector::Id(language_server_id) => {
 4154                                        proto::language_server_selector::Selector::ServerId(
 4155                                            language_server_id.to_proto(),
 4156                                        )
 4157                                    }
 4158                                    LanguageServerSelector::Name(language_server_name) => {
 4159                                        proto::language_server_selector::Selector::Name(
 4160                                            language_server_name.to_string(),
 4161                                        )
 4162                                    }
 4163                                };
 4164                                proto::LanguageServerSelector {
 4165                                    selector: Some(selector),
 4166                                }
 4167                            })
 4168                            .collect(),
 4169                    })
 4170                    .await
 4171            })
 4172            .detach();
 4173        } else {
 4174            panic!("oops!");
 4175        }
 4176        handle
 4177    }
 4178
 4179    fn maintain_buffer_languages(
 4180        languages: Arc<LanguageRegistry>,
 4181        cx: &mut Context<Self>,
 4182    ) -> Task<()> {
 4183        let mut subscription = languages.subscribe();
 4184        let mut prev_reload_count = languages.reload_count();
 4185        cx.spawn(async move |this, cx| {
 4186            while let Some(()) = subscription.next().await {
 4187                if let Some(this) = this.upgrade() {
 4188                    // If the language registry has been reloaded, then remove and
 4189                    // re-assign the languages on all open buffers.
 4190                    let reload_count = languages.reload_count();
 4191                    if reload_count > prev_reload_count {
 4192                        prev_reload_count = reload_count;
 4193                        this.update(cx, |this, cx| {
 4194                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4195                                for buffer in buffer_store.buffers() {
 4196                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4197                                    {
 4198                                        buffer
 4199                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4200                                        if let Some(local) = this.as_local_mut() {
 4201                                            local.reset_buffer(&buffer, &f, cx);
 4202
 4203                                            if local
 4204                                                .registered_buffers
 4205                                                .contains_key(&buffer.read(cx).remote_id())
 4206                                                && let Some(file_url) =
 4207                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4208                                            {
 4209                                                local.unregister_buffer_from_language_servers(
 4210                                                    &buffer, &file_url, cx,
 4211                                                );
 4212                                            }
 4213                                        }
 4214                                    }
 4215                                }
 4216                            });
 4217                        })
 4218                        .ok();
 4219                    }
 4220
 4221                    this.update(cx, |this, cx| {
 4222                        let mut plain_text_buffers = Vec::new();
 4223                        let mut buffers_with_unknown_injections = Vec::new();
 4224                        for handle in this.buffer_store.read(cx).buffers() {
 4225                            let buffer = handle.read(cx);
 4226                            if buffer.language().is_none()
 4227                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4228                            {
 4229                                plain_text_buffers.push(handle);
 4230                            } else if buffer.contains_unknown_injections() {
 4231                                buffers_with_unknown_injections.push(handle);
 4232                            }
 4233                        }
 4234
 4235                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4236                        // and reused later in the invisible worktrees.
 4237                        plain_text_buffers.sort_by_key(|buffer| {
 4238                            Reverse(
 4239                                File::from_dyn(buffer.read(cx).file())
 4240                                    .map(|file| file.worktree.read(cx).is_visible()),
 4241                            )
 4242                        });
 4243
 4244                        for buffer in plain_text_buffers {
 4245                            this.detect_language_for_buffer(&buffer, cx);
 4246                            if let Some(local) = this.as_local_mut() {
 4247                                local.initialize_buffer(&buffer, cx);
 4248                                if local
 4249                                    .registered_buffers
 4250                                    .contains_key(&buffer.read(cx).remote_id())
 4251                                {
 4252                                    local.register_buffer_with_language_servers(
 4253                                        &buffer,
 4254                                        HashSet::default(),
 4255                                        cx,
 4256                                    );
 4257                                }
 4258                            }
 4259                        }
 4260
 4261                        for buffer in buffers_with_unknown_injections {
 4262                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4263                        }
 4264                    })
 4265                    .ok();
 4266                }
 4267            }
 4268        })
 4269    }
 4270
 4271    fn detect_language_for_buffer(
 4272        &mut self,
 4273        buffer_handle: &Entity<Buffer>,
 4274        cx: &mut Context<Self>,
 4275    ) -> Option<language::AvailableLanguage> {
 4276        // If the buffer has a language, set it and start the language server if we haven't already.
 4277        let buffer = buffer_handle.read(cx);
 4278        let file = buffer.file()?;
 4279
 4280        let content = buffer.as_rope();
 4281        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4282        if let Some(available_language) = &available_language {
 4283            if let Some(Ok(Ok(new_language))) = self
 4284                .languages
 4285                .load_language(available_language)
 4286                .now_or_never()
 4287            {
 4288                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4289            }
 4290        } else {
 4291            cx.emit(LspStoreEvent::LanguageDetected {
 4292                buffer: buffer_handle.clone(),
 4293                new_language: None,
 4294            });
 4295        }
 4296
 4297        available_language
 4298    }
 4299
 4300    pub(crate) fn set_language_for_buffer(
 4301        &mut self,
 4302        buffer_entity: &Entity<Buffer>,
 4303        new_language: Arc<Language>,
 4304        cx: &mut Context<Self>,
 4305    ) {
 4306        let buffer = buffer_entity.read(cx);
 4307        let buffer_file = buffer.file().cloned();
 4308        let buffer_id = buffer.remote_id();
 4309        if let Some(local_store) = self.as_local_mut()
 4310            && local_store.registered_buffers.contains_key(&buffer_id)
 4311            && let Some(abs_path) =
 4312                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4313            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4314        {
 4315            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4316        }
 4317        buffer_entity.update(cx, |buffer, cx| {
 4318            if buffer
 4319                .language()
 4320                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4321            {
 4322                buffer.set_language(Some(new_language.clone()), cx);
 4323            }
 4324        });
 4325
 4326        let settings =
 4327            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4328        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4329
 4330        let worktree_id = if let Some(file) = buffer_file {
 4331            let worktree = file.worktree.clone();
 4332
 4333            if let Some(local) = self.as_local_mut()
 4334                && local.registered_buffers.contains_key(&buffer_id)
 4335            {
 4336                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4337            }
 4338            Some(worktree.read(cx).id())
 4339        } else {
 4340            None
 4341        };
 4342
 4343        if settings.prettier.allowed
 4344            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4345        {
 4346            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4347            if let Some(prettier_store) = prettier_store {
 4348                prettier_store.update(cx, |prettier_store, cx| {
 4349                    prettier_store.install_default_prettier(
 4350                        worktree_id,
 4351                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4352                        cx,
 4353                    )
 4354                })
 4355            }
 4356        }
 4357
 4358        cx.emit(LspStoreEvent::LanguageDetected {
 4359            buffer: buffer_entity.clone(),
 4360            new_language: Some(new_language),
 4361        })
 4362    }
 4363
 4364    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4365        self.buffer_store.clone()
 4366    }
 4367
 4368    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4369        self.active_entry = active_entry;
 4370    }
 4371
 4372    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4373        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4374            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4375        {
 4376            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4377                summaries
 4378                    .iter()
 4379                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4380            });
 4381            if let Some(summary) = summaries.next() {
 4382                client
 4383                    .send(proto::UpdateDiagnosticSummary {
 4384                        project_id: downstream_project_id,
 4385                        worktree_id: worktree.id().to_proto(),
 4386                        summary: Some(summary),
 4387                        more_summaries: summaries.collect(),
 4388                    })
 4389                    .log_err();
 4390            }
 4391        }
 4392    }
 4393
 4394    fn is_capable_for_proto_request<R>(
 4395        &self,
 4396        buffer: &Entity<Buffer>,
 4397        request: &R,
 4398        cx: &Context<Self>,
 4399    ) -> bool
 4400    where
 4401        R: LspCommand,
 4402    {
 4403        self.check_if_capable_for_proto_request(
 4404            buffer,
 4405            |capabilities| {
 4406                request.check_capabilities(AdapterServerCapabilities {
 4407                    server_capabilities: capabilities.clone(),
 4408                    code_action_kinds: None,
 4409                })
 4410            },
 4411            cx,
 4412        )
 4413    }
 4414
 4415    fn check_if_capable_for_proto_request<F>(
 4416        &self,
 4417        buffer: &Entity<Buffer>,
 4418        check: F,
 4419        cx: &Context<Self>,
 4420    ) -> bool
 4421    where
 4422        F: Fn(&lsp::ServerCapabilities) -> bool,
 4423    {
 4424        let Some(language) = buffer.read(cx).language().cloned() else {
 4425            return false;
 4426        };
 4427        let relevant_language_servers = self
 4428            .languages
 4429            .lsp_adapters(&language.name())
 4430            .into_iter()
 4431            .map(|lsp_adapter| lsp_adapter.name())
 4432            .collect::<HashSet<_>>();
 4433        self.language_server_statuses
 4434            .iter()
 4435            .filter_map(|(server_id, server_status)| {
 4436                relevant_language_servers
 4437                    .contains(&server_status.name)
 4438                    .then_some(server_id)
 4439            })
 4440            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4441            .any(check)
 4442    }
 4443
 4444    pub fn request_lsp<R>(
 4445        &mut self,
 4446        buffer: Entity<Buffer>,
 4447        server: LanguageServerToQuery,
 4448        request: R,
 4449        cx: &mut Context<Self>,
 4450    ) -> Task<Result<R::Response>>
 4451    where
 4452        R: LspCommand,
 4453        <R::LspRequest as lsp::request::Request>::Result: Send,
 4454        <R::LspRequest as lsp::request::Request>::Params: Send,
 4455    {
 4456        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4457            return self.send_lsp_proto_request(
 4458                buffer,
 4459                upstream_client,
 4460                upstream_project_id,
 4461                request,
 4462                cx,
 4463            );
 4464        }
 4465
 4466        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4467            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4468                local
 4469                    .language_servers_for_buffer(buffer, cx)
 4470                    .find(|(_, server)| {
 4471                        request.check_capabilities(server.adapter_server_capabilities())
 4472                    })
 4473                    .map(|(_, server)| server.clone())
 4474            }),
 4475            LanguageServerToQuery::Other(id) => self
 4476                .language_server_for_local_buffer(buffer, id, cx)
 4477                .and_then(|(_, server)| {
 4478                    request
 4479                        .check_capabilities(server.adapter_server_capabilities())
 4480                        .then(|| Arc::clone(server))
 4481                }),
 4482        }) else {
 4483            return Task::ready(Ok(Default::default()));
 4484        };
 4485
 4486        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4487
 4488        let Some(file) = file else {
 4489            return Task::ready(Ok(Default::default()));
 4490        };
 4491
 4492        let lsp_params = match request.to_lsp_params_or_response(
 4493            &file.abs_path(cx),
 4494            buffer.read(cx),
 4495            &language_server,
 4496            cx,
 4497        ) {
 4498            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4499            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4500
 4501            Err(err) => {
 4502                let message = format!(
 4503                    "{} via {} failed: {}",
 4504                    request.display_name(),
 4505                    language_server.name(),
 4506                    err
 4507                );
 4508                log::warn!("{message}");
 4509                return Task::ready(Err(anyhow!(message)));
 4510            }
 4511        };
 4512
 4513        let status = request.status();
 4514        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4515            return Task::ready(Ok(Default::default()));
 4516        }
 4517        cx.spawn(async move |this, cx| {
 4518            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4519
 4520            let id = lsp_request.id();
 4521            let _cleanup = if status.is_some() {
 4522                cx.update(|cx| {
 4523                    this.update(cx, |this, cx| {
 4524                        this.on_lsp_work_start(
 4525                            language_server.server_id(),
 4526                            id.to_string(),
 4527                            LanguageServerProgress {
 4528                                is_disk_based_diagnostics_progress: false,
 4529                                is_cancellable: false,
 4530                                title: None,
 4531                                message: status.clone(),
 4532                                percentage: None,
 4533                                last_update_at: cx.background_executor().now(),
 4534                            },
 4535                            cx,
 4536                        );
 4537                    })
 4538                })
 4539                .log_err();
 4540
 4541                Some(defer(|| {
 4542                    cx.update(|cx| {
 4543                        this.update(cx, |this, cx| {
 4544                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
 4545                        })
 4546                    })
 4547                    .log_err();
 4548                }))
 4549            } else {
 4550                None
 4551            };
 4552
 4553            let result = lsp_request.await.into_response();
 4554
 4555            let response = result.map_err(|err| {
 4556                let message = format!(
 4557                    "{} via {} failed: {}",
 4558                    request.display_name(),
 4559                    language_server.name(),
 4560                    err
 4561                );
 4562                log::warn!("{message}");
 4563                anyhow::anyhow!(message)
 4564            })?;
 4565
 4566            request
 4567                .response_from_lsp(
 4568                    response,
 4569                    this.upgrade().context("no app context")?,
 4570                    buffer,
 4571                    language_server.server_id(),
 4572                    cx.clone(),
 4573                )
 4574                .await
 4575        })
 4576    }
 4577
 4578    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4579        let mut language_formatters_to_check = Vec::new();
 4580        for buffer in self.buffer_store.read(cx).buffers() {
 4581            let buffer = buffer.read(cx);
 4582            let buffer_file = File::from_dyn(buffer.file());
 4583            let buffer_language = buffer.language();
 4584            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4585            if buffer_language.is_some() {
 4586                language_formatters_to_check.push((
 4587                    buffer_file.map(|f| f.worktree_id(cx)),
 4588                    settings.into_owned(),
 4589                ));
 4590            }
 4591        }
 4592
 4593        self.request_workspace_config_refresh();
 4594
 4595        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4596            prettier_store.update(cx, |prettier_store, cx| {
 4597                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4598            })
 4599        }
 4600
 4601        cx.notify();
 4602    }
 4603
 4604    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4605        let buffer_store = self.buffer_store.clone();
 4606        let Some(local) = self.as_local_mut() else {
 4607            return;
 4608        };
 4609        let mut adapters = BTreeMap::default();
 4610        let get_adapter = {
 4611            let languages = local.languages.clone();
 4612            let environment = local.environment.clone();
 4613            let weak = local.weak.clone();
 4614            let worktree_store = local.worktree_store.clone();
 4615            let http_client = local.http_client.clone();
 4616            let fs = local.fs.clone();
 4617            move |worktree_id, cx: &mut App| {
 4618                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4619                Some(LocalLspAdapterDelegate::new(
 4620                    languages.clone(),
 4621                    &environment,
 4622                    weak.clone(),
 4623                    &worktree,
 4624                    http_client.clone(),
 4625                    fs.clone(),
 4626                    cx,
 4627                ))
 4628            }
 4629        };
 4630
 4631        let mut messages_to_report = Vec::new();
 4632        let (new_tree, to_stop) = {
 4633            let mut rebase = local.lsp_tree.rebase();
 4634            let buffers = buffer_store
 4635                .read(cx)
 4636                .buffers()
 4637                .filter_map(|buffer| {
 4638                    let raw_buffer = buffer.read(cx);
 4639                    if !local
 4640                        .registered_buffers
 4641                        .contains_key(&raw_buffer.remote_id())
 4642                    {
 4643                        return None;
 4644                    }
 4645                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4646                    let language = raw_buffer.language().cloned()?;
 4647                    Some((file, language, raw_buffer.remote_id()))
 4648                })
 4649                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4650            for (file, language, buffer_id) in buffers {
 4651                let worktree_id = file.worktree_id(cx);
 4652                let Some(worktree) = local
 4653                    .worktree_store
 4654                    .read(cx)
 4655                    .worktree_for_id(worktree_id, cx)
 4656                else {
 4657                    continue;
 4658                };
 4659
 4660                if let Some((_, apply)) = local.reuse_existing_language_server(
 4661                    rebase.server_tree(),
 4662                    &worktree,
 4663                    &language.name(),
 4664                    cx,
 4665                ) {
 4666                    (apply)(rebase.server_tree());
 4667                } else if let Some(lsp_delegate) = adapters
 4668                    .entry(worktree_id)
 4669                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4670                    .clone()
 4671                {
 4672                    let delegate =
 4673                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4674                    let path = file
 4675                        .path()
 4676                        .parent()
 4677                        .map(Arc::from)
 4678                        .unwrap_or_else(|| file.path().clone());
 4679                    let worktree_path = ProjectPath { worktree_id, path };
 4680                    let abs_path = file.abs_path(cx);
 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.read(cx).absolutize(&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                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 6991            }
 6992
 6993            let mut requests = Vec::new();
 6994            let mut requested_servers = BTreeSet::new();
 6995            for (seed, state) in local.language_server_ids.iter() {
 6996                let Some(worktree_handle) = self
 6997                    .worktree_store
 6998                    .read(cx)
 6999                    .worktree_for_id(seed.worktree_id, cx)
 7000                else {
 7001                    continue;
 7002                };
 7003                let worktree = worktree_handle.read(cx);
 7004                if !worktree.is_visible() {
 7005                    continue;
 7006                }
 7007
 7008                if !requested_servers.insert(state.id) {
 7009                    continue;
 7010                }
 7011
 7012                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7013                    Some(LanguageServerState::Running {
 7014                        adapter, server, ..
 7015                    }) => (adapter.clone(), server),
 7016
 7017                    _ => continue,
 7018                };
 7019                let supports_workspace_symbol_request =
 7020                    match server.capabilities().workspace_symbol_provider {
 7021                        Some(OneOf::Left(supported)) => supported,
 7022                        Some(OneOf::Right(_)) => true,
 7023                        None => false,
 7024                    };
 7025                if !supports_workspace_symbol_request {
 7026                    continue;
 7027                }
 7028                let worktree_handle = worktree_handle.clone();
 7029                let server_id = server.server_id();
 7030                requests.push(
 7031                        server
 7032                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7033                                lsp::WorkspaceSymbolParams {
 7034                                    query: query.to_string(),
 7035                                    ..Default::default()
 7036                                },
 7037                            )
 7038                            .map(move |response| {
 7039                                let lsp_symbols = response.into_response()
 7040                                    .context("workspace symbols request")
 7041                                    .log_err()
 7042                                    .flatten()
 7043                                    .map(|symbol_response| match symbol_response {
 7044                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7045                                            flat_responses.into_iter().map(|lsp_symbol| {
 7046                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7047                                            }).collect::<Vec<_>>()
 7048                                        }
 7049                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7050                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7051                                                let location = match lsp_symbol.location {
 7052                                                    OneOf::Left(location) => location,
 7053                                                    OneOf::Right(_) => {
 7054                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7055                                                        return None
 7056                                                    }
 7057                                                };
 7058                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7059                                            }).collect::<Vec<_>>()
 7060                                        }
 7061                                    }).unwrap_or_default();
 7062
 7063                                WorkspaceSymbolsResult {
 7064                                    server_id,
 7065                                    lsp_adapter,
 7066                                    worktree: worktree_handle.downgrade(),
 7067                                    lsp_symbols,
 7068                                }
 7069                            }),
 7070                    );
 7071            }
 7072
 7073            cx.spawn(async move |this, cx| {
 7074                let responses = futures::future::join_all(requests).await;
 7075                let this = match this.upgrade() {
 7076                    Some(this) => this,
 7077                    None => return Ok(Vec::new()),
 7078                };
 7079
 7080                let mut symbols = Vec::new();
 7081                for result in responses {
 7082                    let core_symbols = this.update(cx, |this, cx| {
 7083                        result
 7084                            .lsp_symbols
 7085                            .into_iter()
 7086                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7087                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7088                                let source_worktree = result.worktree.upgrade()?;
 7089                                let source_worktree_id = source_worktree.read(cx).id();
 7090
 7091                                let path = if let Some((tree, rel_path)) =
 7092                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7093                                {
 7094                                    let worktree_id = tree.read(cx).id();
 7095                                    SymbolLocation::InProject(ProjectPath {
 7096                                        worktree_id,
 7097                                        path: rel_path,
 7098                                    })
 7099                                } else {
 7100                                    SymbolLocation::OutsideProject {
 7101                                        signature: this.symbol_signature(&abs_path),
 7102                                        abs_path: abs_path.into(),
 7103                                    }
 7104                                };
 7105
 7106                                Some(CoreSymbol {
 7107                                    source_language_server_id: result.server_id,
 7108                                    language_server_name: result.lsp_adapter.name.clone(),
 7109                                    source_worktree_id,
 7110                                    path,
 7111                                    kind: symbol_kind,
 7112                                    name: symbol_name,
 7113                                    range: range_from_lsp(symbol_location.range),
 7114                                })
 7115                            })
 7116                            .collect()
 7117                    })?;
 7118
 7119                    populate_labels_for_symbols(
 7120                        core_symbols,
 7121                        &language_registry,
 7122                        Some(result.lsp_adapter),
 7123                        &mut symbols,
 7124                    )
 7125                    .await;
 7126                }
 7127
 7128                Ok(symbols)
 7129            })
 7130        } else {
 7131            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7132        }
 7133    }
 7134
 7135    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7136        let mut summary = DiagnosticSummary::default();
 7137        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7138            summary.error_count += path_summary.error_count;
 7139            summary.warning_count += path_summary.warning_count;
 7140        }
 7141        summary
 7142    }
 7143
 7144    /// Returns the diagnostic summary for a specific project path.
 7145    pub fn diagnostic_summary_for_path(
 7146        &self,
 7147        project_path: &ProjectPath,
 7148        _: &App,
 7149    ) -> DiagnosticSummary {
 7150        if let Some(summaries) = self
 7151            .diagnostic_summaries
 7152            .get(&project_path.worktree_id)
 7153            .and_then(|map| map.get(&project_path.path))
 7154        {
 7155            let (error_count, warning_count) = summaries.iter().fold(
 7156                (0, 0),
 7157                |(error_count, warning_count), (_language_server_id, summary)| {
 7158                    (
 7159                        error_count + summary.error_count,
 7160                        warning_count + summary.warning_count,
 7161                    )
 7162                },
 7163            );
 7164
 7165            DiagnosticSummary {
 7166                error_count,
 7167                warning_count,
 7168            }
 7169        } else {
 7170            DiagnosticSummary::default()
 7171        }
 7172    }
 7173
 7174    pub fn diagnostic_summaries<'a>(
 7175        &'a self,
 7176        include_ignored: bool,
 7177        cx: &'a App,
 7178    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7179        self.worktree_store
 7180            .read(cx)
 7181            .visible_worktrees(cx)
 7182            .filter_map(|worktree| {
 7183                let worktree = worktree.read(cx);
 7184                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7185            })
 7186            .flat_map(move |(worktree, summaries)| {
 7187                let worktree_id = worktree.id();
 7188                summaries
 7189                    .iter()
 7190                    .filter(move |(path, _)| {
 7191                        include_ignored
 7192                            || worktree
 7193                                .entry_for_path(path.as_ref())
 7194                                .is_some_and(|entry| !entry.is_ignored)
 7195                    })
 7196                    .flat_map(move |(path, summaries)| {
 7197                        summaries.iter().map(move |(server_id, summary)| {
 7198                            (
 7199                                ProjectPath {
 7200                                    worktree_id,
 7201                                    path: path.clone(),
 7202                                },
 7203                                *server_id,
 7204                                *summary,
 7205                            )
 7206                        })
 7207                    })
 7208            })
 7209    }
 7210
 7211    pub fn on_buffer_edited(
 7212        &mut self,
 7213        buffer: Entity<Buffer>,
 7214        cx: &mut Context<Self>,
 7215    ) -> Option<()> {
 7216        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7217            Some(
 7218                self.as_local()?
 7219                    .language_servers_for_buffer(buffer, cx)
 7220                    .map(|i| i.1.clone())
 7221                    .collect(),
 7222            )
 7223        })?;
 7224
 7225        let buffer = buffer.read(cx);
 7226        let file = File::from_dyn(buffer.file())?;
 7227        let abs_path = file.as_local()?.abs_path(cx);
 7228        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7229        let next_snapshot = buffer.text_snapshot();
 7230        for language_server in language_servers {
 7231            let language_server = language_server.clone();
 7232
 7233            let buffer_snapshots = self
 7234                .as_local_mut()
 7235                .unwrap()
 7236                .buffer_snapshots
 7237                .get_mut(&buffer.remote_id())
 7238                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7239            let previous_snapshot = buffer_snapshots.last()?;
 7240
 7241            let build_incremental_change = || {
 7242                buffer
 7243                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7244                        previous_snapshot.snapshot.version(),
 7245                    )
 7246                    .map(|edit| {
 7247                        let edit_start = edit.new.start.0;
 7248                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7249                        let new_text = next_snapshot
 7250                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7251                            .collect();
 7252                        lsp::TextDocumentContentChangeEvent {
 7253                            range: Some(lsp::Range::new(
 7254                                point_to_lsp(edit_start),
 7255                                point_to_lsp(edit_end),
 7256                            )),
 7257                            range_length: None,
 7258                            text: new_text,
 7259                        }
 7260                    })
 7261                    .collect()
 7262            };
 7263
 7264            let document_sync_kind = language_server
 7265                .capabilities()
 7266                .text_document_sync
 7267                .as_ref()
 7268                .and_then(|sync| match sync {
 7269                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7270                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7271                });
 7272
 7273            let content_changes: Vec<_> = match document_sync_kind {
 7274                Some(lsp::TextDocumentSyncKind::FULL) => {
 7275                    vec![lsp::TextDocumentContentChangeEvent {
 7276                        range: None,
 7277                        range_length: None,
 7278                        text: next_snapshot.text(),
 7279                    }]
 7280                }
 7281                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7282                _ => {
 7283                    #[cfg(any(test, feature = "test-support"))]
 7284                    {
 7285                        build_incremental_change()
 7286                    }
 7287
 7288                    #[cfg(not(any(test, feature = "test-support")))]
 7289                    {
 7290                        continue;
 7291                    }
 7292                }
 7293            };
 7294
 7295            let next_version = previous_snapshot.version + 1;
 7296            buffer_snapshots.push(LspBufferSnapshot {
 7297                version: next_version,
 7298                snapshot: next_snapshot.clone(),
 7299            });
 7300
 7301            language_server
 7302                .notify::<lsp::notification::DidChangeTextDocument>(
 7303                    &lsp::DidChangeTextDocumentParams {
 7304                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7305                            uri.clone(),
 7306                            next_version,
 7307                        ),
 7308                        content_changes,
 7309                    },
 7310                )
 7311                .ok();
 7312            self.pull_workspace_diagnostics(language_server.server_id());
 7313        }
 7314
 7315        None
 7316    }
 7317
 7318    pub fn on_buffer_saved(
 7319        &mut self,
 7320        buffer: Entity<Buffer>,
 7321        cx: &mut Context<Self>,
 7322    ) -> Option<()> {
 7323        let file = File::from_dyn(buffer.read(cx).file())?;
 7324        let worktree_id = file.worktree_id(cx);
 7325        let abs_path = file.as_local()?.abs_path(cx);
 7326        let text_document = lsp::TextDocumentIdentifier {
 7327            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7328        };
 7329        let local = self.as_local()?;
 7330
 7331        for server in local.language_servers_for_worktree(worktree_id) {
 7332            if let Some(include_text) = include_text(server.as_ref()) {
 7333                let text = if include_text {
 7334                    Some(buffer.read(cx).text())
 7335                } else {
 7336                    None
 7337                };
 7338                server
 7339                    .notify::<lsp::notification::DidSaveTextDocument>(
 7340                        &lsp::DidSaveTextDocumentParams {
 7341                            text_document: text_document.clone(),
 7342                            text,
 7343                        },
 7344                    )
 7345                    .ok();
 7346            }
 7347        }
 7348
 7349        let language_servers = buffer.update(cx, |buffer, cx| {
 7350            local.language_server_ids_for_buffer(buffer, cx)
 7351        });
 7352        for language_server_id in language_servers {
 7353            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7354        }
 7355
 7356        None
 7357    }
 7358
 7359    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7360        maybe!(async move {
 7361            let mut refreshed_servers = HashSet::default();
 7362            let servers = lsp_store
 7363                .update(cx, |lsp_store, cx| {
 7364                    let local = lsp_store.as_local()?;
 7365
 7366                    let servers = local
 7367                        .language_server_ids
 7368                        .iter()
 7369                        .filter_map(|(seed, state)| {
 7370                            let worktree = lsp_store
 7371                                .worktree_store
 7372                                .read(cx)
 7373                                .worktree_for_id(seed.worktree_id, cx);
 7374                            let delegate: Arc<dyn LspAdapterDelegate> =
 7375                                worktree.map(|worktree| {
 7376                                    LocalLspAdapterDelegate::new(
 7377                                        local.languages.clone(),
 7378                                        &local.environment,
 7379                                        cx.weak_entity(),
 7380                                        &worktree,
 7381                                        local.http_client.clone(),
 7382                                        local.fs.clone(),
 7383                                        cx,
 7384                                    )
 7385                                })?;
 7386                            let server_id = state.id;
 7387
 7388                            let states = local.language_servers.get(&server_id)?;
 7389
 7390                            match states {
 7391                                LanguageServerState::Starting { .. } => None,
 7392                                LanguageServerState::Running {
 7393                                    adapter, server, ..
 7394                                } => {
 7395                                    let adapter = adapter.clone();
 7396                                    let server = server.clone();
 7397                                    refreshed_servers.insert(server.name());
 7398                                    let toolchain = seed.toolchain.clone();
 7399                                    Some(cx.spawn(async move |_, cx| {
 7400                                        let settings =
 7401                                            LocalLspStore::workspace_configuration_for_adapter(
 7402                                                adapter.adapter.clone(),
 7403                                                &delegate,
 7404                                                toolchain,
 7405                                                cx,
 7406                                            )
 7407                                            .await
 7408                                            .ok()?;
 7409                                        server
 7410                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7411                                                &lsp::DidChangeConfigurationParams { settings },
 7412                                            )
 7413                                            .ok()?;
 7414                                        Some(())
 7415                                    }))
 7416                                }
 7417                            }
 7418                        })
 7419                        .collect::<Vec<_>>();
 7420
 7421                    Some(servers)
 7422                })
 7423                .ok()
 7424                .flatten()?;
 7425
 7426            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7427            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7428            // to stop and unregister its language server wrapper.
 7429            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7430            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7431            let _: Vec<Option<()>> = join_all(servers).await;
 7432
 7433            Some(())
 7434        })
 7435        .await;
 7436    }
 7437
 7438    fn maintain_workspace_config(
 7439        external_refresh_requests: watch::Receiver<()>,
 7440        cx: &mut Context<Self>,
 7441    ) -> Task<Result<()>> {
 7442        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7443        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7444
 7445        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7446            *settings_changed_tx.borrow_mut() = ();
 7447        });
 7448
 7449        let mut joint_future =
 7450            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7451        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7452        // - 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).
 7453        // - 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.
 7454        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7455        // - 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,
 7456        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7457        cx.spawn(async move |this, cx| {
 7458            while let Some(()) = joint_future.next().await {
 7459                this.update(cx, |this, cx| {
 7460                    this.refresh_server_tree(cx);
 7461                })
 7462                .ok();
 7463
 7464                Self::refresh_workspace_configurations(&this, cx).await;
 7465            }
 7466
 7467            drop(settings_observation);
 7468            anyhow::Ok(())
 7469        })
 7470    }
 7471
 7472    pub fn language_servers_for_local_buffer<'a>(
 7473        &'a self,
 7474        buffer: &Buffer,
 7475        cx: &mut App,
 7476    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7477        let local = self.as_local();
 7478        let language_server_ids = local
 7479            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7480            .unwrap_or_default();
 7481
 7482        language_server_ids
 7483            .into_iter()
 7484            .filter_map(
 7485                move |server_id| match local?.language_servers.get(&server_id)? {
 7486                    LanguageServerState::Running {
 7487                        adapter, server, ..
 7488                    } => Some((adapter, server)),
 7489                    _ => None,
 7490                },
 7491            )
 7492    }
 7493
 7494    pub fn language_server_for_local_buffer<'a>(
 7495        &'a self,
 7496        buffer: &'a Buffer,
 7497        server_id: LanguageServerId,
 7498        cx: &'a mut App,
 7499    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7500        self.as_local()?
 7501            .language_servers_for_buffer(buffer, cx)
 7502            .find(|(_, s)| s.server_id() == server_id)
 7503    }
 7504
 7505    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7506        self.diagnostic_summaries.remove(&id_to_remove);
 7507        if let Some(local) = self.as_local_mut() {
 7508            let to_remove = local.remove_worktree(id_to_remove, cx);
 7509            for server in to_remove {
 7510                self.language_server_statuses.remove(&server);
 7511            }
 7512        }
 7513    }
 7514
 7515    pub fn shared(
 7516        &mut self,
 7517        project_id: u64,
 7518        downstream_client: AnyProtoClient,
 7519        _: &mut Context<Self>,
 7520    ) {
 7521        self.downstream_client = Some((downstream_client.clone(), project_id));
 7522
 7523        for (server_id, status) in &self.language_server_statuses {
 7524            if let Some(server) = self.language_server_for_id(*server_id) {
 7525                downstream_client
 7526                    .send(proto::StartLanguageServer {
 7527                        project_id,
 7528                        server: Some(proto::LanguageServer {
 7529                            id: server_id.to_proto(),
 7530                            name: status.name.to_string(),
 7531                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7532                        }),
 7533                        capabilities: serde_json::to_string(&server.capabilities())
 7534                            .expect("serializing server LSP capabilities"),
 7535                    })
 7536                    .log_err();
 7537            }
 7538        }
 7539    }
 7540
 7541    pub fn disconnected_from_host(&mut self) {
 7542        self.downstream_client.take();
 7543    }
 7544
 7545    pub fn disconnected_from_ssh_remote(&mut self) {
 7546        if let LspStoreMode::Remote(RemoteLspStore {
 7547            upstream_client, ..
 7548        }) = &mut self.mode
 7549        {
 7550            upstream_client.take();
 7551        }
 7552    }
 7553
 7554    pub(crate) fn set_language_server_statuses_from_proto(
 7555        &mut self,
 7556        project: WeakEntity<Project>,
 7557        language_servers: Vec<proto::LanguageServer>,
 7558        server_capabilities: Vec<String>,
 7559        cx: &mut Context<Self>,
 7560    ) {
 7561        let lsp_logs = cx
 7562            .try_global::<GlobalLogStore>()
 7563            .map(|lsp_store| lsp_store.0.clone());
 7564
 7565        self.language_server_statuses = language_servers
 7566            .into_iter()
 7567            .zip(server_capabilities)
 7568            .map(|(server, server_capabilities)| {
 7569                let server_id = LanguageServerId(server.id as usize);
 7570                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7571                    self.lsp_server_capabilities
 7572                        .insert(server_id, server_capabilities);
 7573                }
 7574
 7575                let name = LanguageServerName::from_proto(server.name);
 7576                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7577
 7578                if let Some(lsp_logs) = &lsp_logs {
 7579                    lsp_logs.update(cx, |lsp_logs, cx| {
 7580                        lsp_logs.add_language_server(
 7581                            // Only remote clients get their language servers set from proto
 7582                            LanguageServerKind::Remote {
 7583                                project: project.clone(),
 7584                            },
 7585                            server_id,
 7586                            Some(name.clone()),
 7587                            worktree,
 7588                            None,
 7589                            cx,
 7590                        );
 7591                    });
 7592                }
 7593
 7594                (
 7595                    server_id,
 7596                    LanguageServerStatus {
 7597                        name,
 7598                        pending_work: Default::default(),
 7599                        has_pending_diagnostic_updates: false,
 7600                        progress_tokens: Default::default(),
 7601                        worktree,
 7602                    },
 7603                )
 7604            })
 7605            .collect();
 7606    }
 7607
 7608    #[cfg(test)]
 7609    pub fn update_diagnostic_entries(
 7610        &mut self,
 7611        server_id: LanguageServerId,
 7612        abs_path: PathBuf,
 7613        result_id: Option<String>,
 7614        version: Option<i32>,
 7615        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7616        cx: &mut Context<Self>,
 7617    ) -> anyhow::Result<()> {
 7618        self.merge_diagnostic_entries(
 7619            vec![DocumentDiagnosticsUpdate {
 7620                diagnostics: DocumentDiagnostics {
 7621                    diagnostics,
 7622                    document_abs_path: abs_path,
 7623                    version,
 7624                },
 7625                result_id,
 7626                server_id,
 7627                disk_based_sources: Cow::Borrowed(&[]),
 7628            }],
 7629            |_, _, _| false,
 7630            cx,
 7631        )?;
 7632        Ok(())
 7633    }
 7634
 7635    pub fn merge_diagnostic_entries<'a>(
 7636        &mut self,
 7637        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7638        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7639        cx: &mut Context<Self>,
 7640    ) -> anyhow::Result<()> {
 7641        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7642        let mut updated_diagnostics_paths = HashMap::default();
 7643        for mut update in diagnostic_updates {
 7644            let abs_path = &update.diagnostics.document_abs_path;
 7645            let server_id = update.server_id;
 7646            let Some((worktree, relative_path)) =
 7647                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7648            else {
 7649                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7650                return Ok(());
 7651            };
 7652
 7653            let worktree_id = worktree.read(cx).id();
 7654            let project_path = ProjectPath {
 7655                worktree_id,
 7656                path: relative_path,
 7657            };
 7658
 7659            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7660                let snapshot = buffer_handle.read(cx).snapshot();
 7661                let buffer = buffer_handle.read(cx);
 7662                let reused_diagnostics = buffer
 7663                    .buffer_diagnostics(Some(server_id))
 7664                    .iter()
 7665                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 7666                    .map(|v| {
 7667                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 7668                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 7669                        DiagnosticEntry {
 7670                            range: start..end,
 7671                            diagnostic: v.diagnostic.clone(),
 7672                        }
 7673                    })
 7674                    .collect::<Vec<_>>();
 7675
 7676                self.as_local_mut()
 7677                    .context("cannot merge diagnostics on a remote LspStore")?
 7678                    .update_buffer_diagnostics(
 7679                        &buffer_handle,
 7680                        server_id,
 7681                        update.result_id,
 7682                        update.diagnostics.version,
 7683                        update.diagnostics.diagnostics.clone(),
 7684                        reused_diagnostics.clone(),
 7685                        cx,
 7686                    )?;
 7687
 7688                update.diagnostics.diagnostics.extend(reused_diagnostics);
 7689            }
 7690
 7691            let updated = worktree.update(cx, |worktree, cx| {
 7692                self.update_worktree_diagnostics(
 7693                    worktree.id(),
 7694                    server_id,
 7695                    project_path.path.clone(),
 7696                    update.diagnostics.diagnostics,
 7697                    cx,
 7698                )
 7699            })?;
 7700            match updated {
 7701                ControlFlow::Continue(new_summary) => {
 7702                    if let Some((project_id, new_summary)) = new_summary {
 7703                        match &mut diagnostics_summary {
 7704                            Some(diagnostics_summary) => {
 7705                                diagnostics_summary
 7706                                    .more_summaries
 7707                                    .push(proto::DiagnosticSummary {
 7708                                        path: project_path.path.as_ref().to_proto(),
 7709                                        language_server_id: server_id.0 as u64,
 7710                                        error_count: new_summary.error_count,
 7711                                        warning_count: new_summary.warning_count,
 7712                                    })
 7713                            }
 7714                            None => {
 7715                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 7716                                    project_id,
 7717                                    worktree_id: worktree_id.to_proto(),
 7718                                    summary: Some(proto::DiagnosticSummary {
 7719                                        path: project_path.path.as_ref().to_proto(),
 7720                                        language_server_id: server_id.0 as u64,
 7721                                        error_count: new_summary.error_count,
 7722                                        warning_count: new_summary.warning_count,
 7723                                    }),
 7724                                    more_summaries: Vec::new(),
 7725                                })
 7726                            }
 7727                        }
 7728                    }
 7729                    updated_diagnostics_paths
 7730                        .entry(server_id)
 7731                        .or_insert_with(Vec::new)
 7732                        .push(project_path);
 7733                }
 7734                ControlFlow::Break(()) => {}
 7735            }
 7736        }
 7737
 7738        if let Some((diagnostics_summary, (downstream_client, _))) =
 7739            diagnostics_summary.zip(self.downstream_client.as_ref())
 7740        {
 7741            downstream_client.send(diagnostics_summary).log_err();
 7742        }
 7743        for (server_id, paths) in updated_diagnostics_paths {
 7744            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 7745        }
 7746        Ok(())
 7747    }
 7748
 7749    fn update_worktree_diagnostics(
 7750        &mut self,
 7751        worktree_id: WorktreeId,
 7752        server_id: LanguageServerId,
 7753        path_in_worktree: Arc<RelPath>,
 7754        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7755        _: &mut Context<Worktree>,
 7756    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 7757        let local = match &mut self.mode {
 7758            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 7759            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 7760        };
 7761
 7762        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 7763        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 7764        let summaries_by_server_id = summaries_for_tree
 7765            .entry(path_in_worktree.clone())
 7766            .or_default();
 7767
 7768        let old_summary = summaries_by_server_id
 7769            .remove(&server_id)
 7770            .unwrap_or_default();
 7771
 7772        let new_summary = DiagnosticSummary::new(&diagnostics);
 7773        if new_summary.is_empty() {
 7774            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 7775            {
 7776                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7777                    diagnostics_by_server_id.remove(ix);
 7778                }
 7779                if diagnostics_by_server_id.is_empty() {
 7780                    diagnostics_for_tree.remove(&path_in_worktree);
 7781                }
 7782            }
 7783        } else {
 7784            summaries_by_server_id.insert(server_id, new_summary);
 7785            let diagnostics_by_server_id = diagnostics_for_tree
 7786                .entry(path_in_worktree.clone())
 7787                .or_default();
 7788            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7789                Ok(ix) => {
 7790                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 7791                }
 7792                Err(ix) => {
 7793                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 7794                }
 7795            }
 7796        }
 7797
 7798        if !old_summary.is_empty() || !new_summary.is_empty() {
 7799            if let Some((_, project_id)) = &self.downstream_client {
 7800                Ok(ControlFlow::Continue(Some((
 7801                    *project_id,
 7802                    proto::DiagnosticSummary {
 7803                        path: path_in_worktree.to_proto(),
 7804                        language_server_id: server_id.0 as u64,
 7805                        error_count: new_summary.error_count as u32,
 7806                        warning_count: new_summary.warning_count as u32,
 7807                    },
 7808                ))))
 7809            } else {
 7810                Ok(ControlFlow::Continue(None))
 7811            }
 7812        } else {
 7813            Ok(ControlFlow::Break(()))
 7814        }
 7815    }
 7816
 7817    pub fn open_buffer_for_symbol(
 7818        &mut self,
 7819        symbol: &Symbol,
 7820        cx: &mut Context<Self>,
 7821    ) -> Task<Result<Entity<Buffer>>> {
 7822        if let Some((client, project_id)) = self.upstream_client() {
 7823            let request = client.request(proto::OpenBufferForSymbol {
 7824                project_id,
 7825                symbol: Some(Self::serialize_symbol(symbol)),
 7826            });
 7827            cx.spawn(async move |this, cx| {
 7828                let response = request.await?;
 7829                let buffer_id = BufferId::new(response.buffer_id)?;
 7830                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 7831                    .await
 7832            })
 7833        } else if let Some(local) = self.as_local() {
 7834            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 7835                seed.worktree_id == symbol.source_worktree_id
 7836                    && state.id == symbol.source_language_server_id
 7837                    && symbol.language_server_name == seed.name
 7838            });
 7839            if !is_valid {
 7840                return Task::ready(Err(anyhow!(
 7841                    "language server for worktree and language not found"
 7842                )));
 7843            };
 7844
 7845            let symbol_abs_path = match &symbol.path {
 7846                SymbolLocation::InProject(project_path) => self
 7847                    .worktree_store
 7848                    .read(cx)
 7849                    .absolutize(&project_path, cx)
 7850                    .context("no such worktree"),
 7851                SymbolLocation::OutsideProject {
 7852                    abs_path,
 7853                    signature: _,
 7854                } => Ok(abs_path.to_path_buf()),
 7855            };
 7856            let symbol_abs_path = match symbol_abs_path {
 7857                Ok(abs_path) => abs_path,
 7858                Err(err) => return Task::ready(Err(err)),
 7859            };
 7860            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 7861                uri
 7862            } else {
 7863                return Task::ready(Err(anyhow!("invalid symbol path")));
 7864            };
 7865
 7866            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 7867        } else {
 7868            Task::ready(Err(anyhow!("no upstream client or local store")))
 7869        }
 7870    }
 7871
 7872    pub(crate) fn open_local_buffer_via_lsp(
 7873        &mut self,
 7874        abs_path: lsp::Uri,
 7875        language_server_id: LanguageServerId,
 7876        cx: &mut Context<Self>,
 7877    ) -> Task<Result<Entity<Buffer>>> {
 7878        cx.spawn(async move |lsp_store, cx| {
 7879            // Escape percent-encoded string.
 7880            let current_scheme = abs_path.scheme().to_owned();
 7881            // Uri is immutable, so we can't modify the scheme
 7882
 7883            let abs_path = abs_path
 7884                .to_file_path()
 7885                .map_err(|()| anyhow!("can't convert URI to path"))?;
 7886            let p = abs_path.clone();
 7887            let yarn_worktree = lsp_store
 7888                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 7889                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 7890                        cx.spawn(async move |this, cx| {
 7891                            let t = this
 7892                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 7893                                .ok()?;
 7894                            t.await
 7895                        })
 7896                    }),
 7897                    None => Task::ready(None),
 7898                })?
 7899                .await;
 7900            let (worktree_root_target, known_relative_path) =
 7901                if let Some((zip_root, relative_path)) = yarn_worktree {
 7902                    (zip_root, Some(relative_path))
 7903                } else {
 7904                    (Arc::<Path>::from(abs_path.as_path()), None)
 7905                };
 7906            let (worktree, relative_path) = if let Some(result) =
 7907                lsp_store.update(cx, |lsp_store, cx| {
 7908                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7909                        worktree_store.find_worktree(&worktree_root_target, cx)
 7910                    })
 7911                })? {
 7912                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 7913                (result.0, relative_path)
 7914            } else {
 7915                let worktree = lsp_store
 7916                    .update(cx, |lsp_store, cx| {
 7917                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7918                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 7919                        })
 7920                    })?
 7921                    .await?;
 7922                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 7923                    lsp_store
 7924                        .update(cx, |lsp_store, cx| {
 7925                            if let Some(local) = lsp_store.as_local_mut() {
 7926                                local.register_language_server_for_invisible_worktree(
 7927                                    &worktree,
 7928                                    language_server_id,
 7929                                    cx,
 7930                                )
 7931                            }
 7932                        })
 7933                        .ok();
 7934                }
 7935                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 7936                let relative_path = if let Some(known_path) = known_relative_path {
 7937                    known_path
 7938                } else {
 7939                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 7940                        .into_arc()
 7941                };
 7942                (worktree, relative_path)
 7943            };
 7944            let project_path = ProjectPath {
 7945                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 7946                path: relative_path,
 7947            };
 7948            lsp_store
 7949                .update(cx, |lsp_store, cx| {
 7950                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 7951                        buffer_store.open_buffer(project_path, cx)
 7952                    })
 7953                })?
 7954                .await
 7955        })
 7956    }
 7957
 7958    fn request_multiple_lsp_locally<P, R>(
 7959        &mut self,
 7960        buffer: &Entity<Buffer>,
 7961        position: Option<P>,
 7962        request: R,
 7963        cx: &mut Context<Self>,
 7964    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 7965    where
 7966        P: ToOffset,
 7967        R: LspCommand + Clone,
 7968        <R::LspRequest as lsp::request::Request>::Result: Send,
 7969        <R::LspRequest as lsp::request::Request>::Params: Send,
 7970    {
 7971        let Some(local) = self.as_local() else {
 7972            return Task::ready(Vec::new());
 7973        };
 7974
 7975        let snapshot = buffer.read(cx).snapshot();
 7976        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 7977
 7978        let server_ids = buffer.update(cx, |buffer, cx| {
 7979            local
 7980                .language_servers_for_buffer(buffer, cx)
 7981                .filter(|(adapter, _)| {
 7982                    scope
 7983                        .as_ref()
 7984                        .map(|scope| scope.language_allowed(&adapter.name))
 7985                        .unwrap_or(true)
 7986                })
 7987                .map(|(_, server)| server.server_id())
 7988                .filter(|server_id| {
 7989                    self.as_local().is_none_or(|local| {
 7990                        local
 7991                            .buffers_opened_in_servers
 7992                            .get(&snapshot.remote_id())
 7993                            .is_some_and(|servers| servers.contains(server_id))
 7994                    })
 7995                })
 7996                .collect::<Vec<_>>()
 7997        });
 7998
 7999        let mut response_results = server_ids
 8000            .into_iter()
 8001            .map(|server_id| {
 8002                let task = self.request_lsp(
 8003                    buffer.clone(),
 8004                    LanguageServerToQuery::Other(server_id),
 8005                    request.clone(),
 8006                    cx,
 8007                );
 8008                async move { (server_id, task.await) }
 8009            })
 8010            .collect::<FuturesUnordered<_>>();
 8011
 8012        cx.background_spawn(async move {
 8013            let mut responses = Vec::with_capacity(response_results.len());
 8014            while let Some((server_id, response_result)) = response_results.next().await {
 8015                if let Some(response) = response_result.log_err() {
 8016                    responses.push((server_id, response));
 8017                }
 8018            }
 8019            responses
 8020        })
 8021    }
 8022
 8023    async fn handle_lsp_command<T: LspCommand>(
 8024        this: Entity<Self>,
 8025        envelope: TypedEnvelope<T::ProtoRequest>,
 8026        mut cx: AsyncApp,
 8027    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8028    where
 8029        <T::LspRequest as lsp::request::Request>::Params: Send,
 8030        <T::LspRequest as lsp::request::Request>::Result: Send,
 8031    {
 8032        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8033        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8034        let buffer_handle = this.update(&mut cx, |this, cx| {
 8035            this.buffer_store.read(cx).get_existing(buffer_id)
 8036        })??;
 8037        let request = T::from_proto(
 8038            envelope.payload,
 8039            this.clone(),
 8040            buffer_handle.clone(),
 8041            cx.clone(),
 8042        )
 8043        .await?;
 8044        let response = this
 8045            .update(&mut cx, |this, cx| {
 8046                this.request_lsp(
 8047                    buffer_handle.clone(),
 8048                    LanguageServerToQuery::FirstCapable,
 8049                    request,
 8050                    cx,
 8051                )
 8052            })?
 8053            .await?;
 8054        this.update(&mut cx, |this, cx| {
 8055            Ok(T::response_to_proto(
 8056                response,
 8057                this,
 8058                sender_id,
 8059                &buffer_handle.read(cx).version(),
 8060                cx,
 8061            ))
 8062        })?
 8063    }
 8064
 8065    async fn handle_lsp_query(
 8066        lsp_store: Entity<Self>,
 8067        envelope: TypedEnvelope<proto::LspQuery>,
 8068        mut cx: AsyncApp,
 8069    ) -> Result<proto::Ack> {
 8070        use proto::lsp_query::Request;
 8071        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8072        let lsp_query = envelope.payload;
 8073        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8074        match lsp_query.request.context("invalid LSP query request")? {
 8075            Request::GetReferences(get_references) => {
 8076                let position = get_references.position.clone().and_then(deserialize_anchor);
 8077                Self::query_lsp_locally::<GetReferences>(
 8078                    lsp_store,
 8079                    sender_id,
 8080                    lsp_request_id,
 8081                    get_references,
 8082                    position,
 8083                    cx.clone(),
 8084                )
 8085                .await?;
 8086            }
 8087            Request::GetDocumentColor(get_document_color) => {
 8088                Self::query_lsp_locally::<GetDocumentColor>(
 8089                    lsp_store,
 8090                    sender_id,
 8091                    lsp_request_id,
 8092                    get_document_color,
 8093                    None,
 8094                    cx.clone(),
 8095                )
 8096                .await?;
 8097            }
 8098            Request::GetHover(get_hover) => {
 8099                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8100                Self::query_lsp_locally::<GetHover>(
 8101                    lsp_store,
 8102                    sender_id,
 8103                    lsp_request_id,
 8104                    get_hover,
 8105                    position,
 8106                    cx.clone(),
 8107                )
 8108                .await?;
 8109            }
 8110            Request::GetCodeActions(get_code_actions) => {
 8111                Self::query_lsp_locally::<GetCodeActions>(
 8112                    lsp_store,
 8113                    sender_id,
 8114                    lsp_request_id,
 8115                    get_code_actions,
 8116                    None,
 8117                    cx.clone(),
 8118                )
 8119                .await?;
 8120            }
 8121            Request::GetSignatureHelp(get_signature_help) => {
 8122                let position = get_signature_help
 8123                    .position
 8124                    .clone()
 8125                    .and_then(deserialize_anchor);
 8126                Self::query_lsp_locally::<GetSignatureHelp>(
 8127                    lsp_store,
 8128                    sender_id,
 8129                    lsp_request_id,
 8130                    get_signature_help,
 8131                    position,
 8132                    cx.clone(),
 8133                )
 8134                .await?;
 8135            }
 8136            Request::GetCodeLens(get_code_lens) => {
 8137                Self::query_lsp_locally::<GetCodeLens>(
 8138                    lsp_store,
 8139                    sender_id,
 8140                    lsp_request_id,
 8141                    get_code_lens,
 8142                    None,
 8143                    cx.clone(),
 8144                )
 8145                .await?;
 8146            }
 8147            Request::GetDefinition(get_definition) => {
 8148                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8149                Self::query_lsp_locally::<GetDefinitions>(
 8150                    lsp_store,
 8151                    sender_id,
 8152                    lsp_request_id,
 8153                    get_definition,
 8154                    position,
 8155                    cx.clone(),
 8156                )
 8157                .await?;
 8158            }
 8159            Request::GetDeclaration(get_declaration) => {
 8160                let position = get_declaration
 8161                    .position
 8162                    .clone()
 8163                    .and_then(deserialize_anchor);
 8164                Self::query_lsp_locally::<GetDeclarations>(
 8165                    lsp_store,
 8166                    sender_id,
 8167                    lsp_request_id,
 8168                    get_declaration,
 8169                    position,
 8170                    cx.clone(),
 8171                )
 8172                .await?;
 8173            }
 8174            Request::GetTypeDefinition(get_type_definition) => {
 8175                let position = get_type_definition
 8176                    .position
 8177                    .clone()
 8178                    .and_then(deserialize_anchor);
 8179                Self::query_lsp_locally::<GetTypeDefinitions>(
 8180                    lsp_store,
 8181                    sender_id,
 8182                    lsp_request_id,
 8183                    get_type_definition,
 8184                    position,
 8185                    cx.clone(),
 8186                )
 8187                .await?;
 8188            }
 8189            Request::GetImplementation(get_implementation) => {
 8190                let position = get_implementation
 8191                    .position
 8192                    .clone()
 8193                    .and_then(deserialize_anchor);
 8194                Self::query_lsp_locally::<GetImplementations>(
 8195                    lsp_store,
 8196                    sender_id,
 8197                    lsp_request_id,
 8198                    get_implementation,
 8199                    position,
 8200                    cx.clone(),
 8201                )
 8202                .await?;
 8203            }
 8204            // Diagnostics pull synchronizes internally via the buffer state, and cannot be handled generically as the other requests.
 8205            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8206                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8207                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8208                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8209                    this.buffer_store.read(cx).get_existing(buffer_id)
 8210                })??;
 8211                buffer
 8212                    .update(&mut cx, |buffer, _| {
 8213                        buffer.wait_for_version(version.clone())
 8214                    })?
 8215                    .await?;
 8216                lsp_store.update(&mut cx, |lsp_store, cx| {
 8217                    let existing_queries = lsp_store
 8218                        .running_lsp_requests
 8219                        .entry(TypeId::of::<GetDocumentDiagnostics>())
 8220                        .or_default();
 8221                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8222                    ) || buffer.read(cx).version.changed_since(&existing_queries.0)
 8223                    {
 8224                        existing_queries.1.clear();
 8225                    }
 8226                    existing_queries.1.insert(
 8227                        lsp_request_id,
 8228                        cx.spawn(async move |lsp_store, cx| {
 8229                            let diagnostics_pull = lsp_store
 8230                                .update(cx, |lsp_store, cx| {
 8231                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8232                                })
 8233                                .ok();
 8234                            if let Some(diagnostics_pull) = diagnostics_pull {
 8235                                match diagnostics_pull.await {
 8236                                    Ok(()) => {}
 8237                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8238                                };
 8239                            }
 8240                        }),
 8241                    );
 8242                })?;
 8243            }
 8244        }
 8245        Ok(proto::Ack {})
 8246    }
 8247
 8248    async fn handle_lsp_query_response(
 8249        lsp_store: Entity<Self>,
 8250        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8251        cx: AsyncApp,
 8252    ) -> Result<()> {
 8253        lsp_store.read_with(&cx, |lsp_store, _| {
 8254            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8255                upstream_client.handle_lsp_response(envelope.clone());
 8256            }
 8257        })?;
 8258        Ok(())
 8259    }
 8260
 8261    async fn handle_apply_code_action(
 8262        this: Entity<Self>,
 8263        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8264        mut cx: AsyncApp,
 8265    ) -> Result<proto::ApplyCodeActionResponse> {
 8266        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8267        let action =
 8268            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8269        let apply_code_action = this.update(&mut cx, |this, cx| {
 8270            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8271            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8272            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8273        })??;
 8274
 8275        let project_transaction = apply_code_action.await?;
 8276        let project_transaction = this.update(&mut cx, |this, cx| {
 8277            this.buffer_store.update(cx, |buffer_store, cx| {
 8278                buffer_store.serialize_project_transaction_for_peer(
 8279                    project_transaction,
 8280                    sender_id,
 8281                    cx,
 8282                )
 8283            })
 8284        })?;
 8285        Ok(proto::ApplyCodeActionResponse {
 8286            transaction: Some(project_transaction),
 8287        })
 8288    }
 8289
 8290    async fn handle_register_buffer_with_language_servers(
 8291        this: Entity<Self>,
 8292        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8293        mut cx: AsyncApp,
 8294    ) -> Result<proto::Ack> {
 8295        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8296        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8297        this.update(&mut cx, |this, cx| {
 8298            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8299                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8300                    project_id: upstream_project_id,
 8301                    buffer_id: buffer_id.to_proto(),
 8302                    only_servers: envelope.payload.only_servers,
 8303                });
 8304            }
 8305
 8306            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8307                anyhow::bail!("buffer is not open");
 8308            };
 8309
 8310            let handle = this.register_buffer_with_language_servers(
 8311                &buffer,
 8312                envelope
 8313                    .payload
 8314                    .only_servers
 8315                    .into_iter()
 8316                    .filter_map(|selector| {
 8317                        Some(match selector.selector? {
 8318                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8319                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8320                            }
 8321                            proto::language_server_selector::Selector::Name(name) => {
 8322                                LanguageServerSelector::Name(LanguageServerName(
 8323                                    SharedString::from(name),
 8324                                ))
 8325                            }
 8326                        })
 8327                    })
 8328                    .collect(),
 8329                false,
 8330                cx,
 8331            );
 8332            this.buffer_store().update(cx, |buffer_store, _| {
 8333                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8334            });
 8335
 8336            Ok(())
 8337        })??;
 8338        Ok(proto::Ack {})
 8339    }
 8340
 8341    async fn handle_rename_project_entry(
 8342        this: Entity<Self>,
 8343        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8344        mut cx: AsyncApp,
 8345    ) -> Result<proto::ProjectEntryResponse> {
 8346        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8347        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8348        let new_path =
 8349            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8350
 8351        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8352            .update(&mut cx, |this, cx| {
 8353                let (worktree, entry) = this
 8354                    .worktree_store
 8355                    .read(cx)
 8356                    .worktree_and_entry_for_id(entry_id, cx)?;
 8357                let new_worktree = this
 8358                    .worktree_store
 8359                    .read(cx)
 8360                    .worktree_for_id(new_worktree_id, cx)?;
 8361                Some((
 8362                    this.worktree_store.clone(),
 8363                    worktree,
 8364                    new_worktree,
 8365                    entry.clone(),
 8366                ))
 8367            })?
 8368            .context("worktree not found")?;
 8369        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8370            (worktree.absolutize(&old_entry.path), worktree.id())
 8371        })?;
 8372        let new_abs_path =
 8373            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8374
 8375        let _transaction = Self::will_rename_entry(
 8376            this.downgrade(),
 8377            old_worktree_id,
 8378            &old_abs_path,
 8379            &new_abs_path,
 8380            old_entry.is_dir(),
 8381            cx.clone(),
 8382        )
 8383        .await;
 8384        let response = WorktreeStore::handle_rename_project_entry(
 8385            worktree_store,
 8386            envelope.payload,
 8387            cx.clone(),
 8388        )
 8389        .await;
 8390        this.read_with(&cx, |this, _| {
 8391            this.did_rename_entry(
 8392                old_worktree_id,
 8393                &old_abs_path,
 8394                &new_abs_path,
 8395                old_entry.is_dir(),
 8396            );
 8397        })
 8398        .ok();
 8399        response
 8400    }
 8401
 8402    async fn handle_update_diagnostic_summary(
 8403        this: Entity<Self>,
 8404        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8405        mut cx: AsyncApp,
 8406    ) -> Result<()> {
 8407        this.update(&mut cx, |lsp_store, cx| {
 8408            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8409            let mut updated_diagnostics_paths = HashMap::default();
 8410            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8411            for message_summary in envelope
 8412                .payload
 8413                .summary
 8414                .into_iter()
 8415                .chain(envelope.payload.more_summaries)
 8416            {
 8417                let project_path = ProjectPath {
 8418                    worktree_id,
 8419                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8420                };
 8421                let path = project_path.path.clone();
 8422                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8423                let summary = DiagnosticSummary {
 8424                    error_count: message_summary.error_count as usize,
 8425                    warning_count: message_summary.warning_count as usize,
 8426                };
 8427
 8428                if summary.is_empty() {
 8429                    if let Some(worktree_summaries) =
 8430                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8431                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8432                    {
 8433                        summaries.remove(&server_id);
 8434                        if summaries.is_empty() {
 8435                            worktree_summaries.remove(&path);
 8436                        }
 8437                    }
 8438                } else {
 8439                    lsp_store
 8440                        .diagnostic_summaries
 8441                        .entry(worktree_id)
 8442                        .or_default()
 8443                        .entry(path)
 8444                        .or_default()
 8445                        .insert(server_id, summary);
 8446                }
 8447
 8448                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8449                    match &mut diagnostics_summary {
 8450                        Some(diagnostics_summary) => {
 8451                            diagnostics_summary
 8452                                .more_summaries
 8453                                .push(proto::DiagnosticSummary {
 8454                                    path: project_path.path.as_ref().to_proto(),
 8455                                    language_server_id: server_id.0 as u64,
 8456                                    error_count: summary.error_count as u32,
 8457                                    warning_count: summary.warning_count as u32,
 8458                                })
 8459                        }
 8460                        None => {
 8461                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8462                                project_id: *project_id,
 8463                                worktree_id: worktree_id.to_proto(),
 8464                                summary: Some(proto::DiagnosticSummary {
 8465                                    path: project_path.path.as_ref().to_proto(),
 8466                                    language_server_id: server_id.0 as u64,
 8467                                    error_count: summary.error_count as u32,
 8468                                    warning_count: summary.warning_count as u32,
 8469                                }),
 8470                                more_summaries: Vec::new(),
 8471                            })
 8472                        }
 8473                    }
 8474                }
 8475                updated_diagnostics_paths
 8476                    .entry(server_id)
 8477                    .or_insert_with(Vec::new)
 8478                    .push(project_path);
 8479            }
 8480
 8481            if let Some((diagnostics_summary, (downstream_client, _))) =
 8482                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8483            {
 8484                downstream_client.send(diagnostics_summary).log_err();
 8485            }
 8486            for (server_id, paths) in updated_diagnostics_paths {
 8487                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8488            }
 8489            Ok(())
 8490        })?
 8491    }
 8492
 8493    async fn handle_start_language_server(
 8494        lsp_store: Entity<Self>,
 8495        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8496        mut cx: AsyncApp,
 8497    ) -> Result<()> {
 8498        let server = envelope.payload.server.context("invalid server")?;
 8499        let server_capabilities =
 8500            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8501                .with_context(|| {
 8502                    format!(
 8503                        "incorrect server capabilities {}",
 8504                        envelope.payload.capabilities
 8505                    )
 8506                })?;
 8507        lsp_store.update(&mut cx, |lsp_store, cx| {
 8508            let server_id = LanguageServerId(server.id as usize);
 8509            let server_name = LanguageServerName::from_proto(server.name.clone());
 8510            lsp_store
 8511                .lsp_server_capabilities
 8512                .insert(server_id, server_capabilities);
 8513            lsp_store.language_server_statuses.insert(
 8514                server_id,
 8515                LanguageServerStatus {
 8516                    name: server_name.clone(),
 8517                    pending_work: Default::default(),
 8518                    has_pending_diagnostic_updates: false,
 8519                    progress_tokens: Default::default(),
 8520                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8521                },
 8522            );
 8523            cx.emit(LspStoreEvent::LanguageServerAdded(
 8524                server_id,
 8525                server_name,
 8526                server.worktree_id.map(WorktreeId::from_proto),
 8527            ));
 8528            cx.notify();
 8529        })?;
 8530        Ok(())
 8531    }
 8532
 8533    async fn handle_update_language_server(
 8534        lsp_store: Entity<Self>,
 8535        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8536        mut cx: AsyncApp,
 8537    ) -> Result<()> {
 8538        lsp_store.update(&mut cx, |lsp_store, cx| {
 8539            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8540
 8541            match envelope.payload.variant.context("invalid variant")? {
 8542                proto::update_language_server::Variant::WorkStart(payload) => {
 8543                    lsp_store.on_lsp_work_start(
 8544                        language_server_id,
 8545                        payload.token,
 8546                        LanguageServerProgress {
 8547                            title: payload.title,
 8548                            is_disk_based_diagnostics_progress: false,
 8549                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8550                            message: payload.message,
 8551                            percentage: payload.percentage.map(|p| p as usize),
 8552                            last_update_at: cx.background_executor().now(),
 8553                        },
 8554                        cx,
 8555                    );
 8556                }
 8557                proto::update_language_server::Variant::WorkProgress(payload) => {
 8558                    lsp_store.on_lsp_work_progress(
 8559                        language_server_id,
 8560                        payload.token,
 8561                        LanguageServerProgress {
 8562                            title: None,
 8563                            is_disk_based_diagnostics_progress: false,
 8564                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8565                            message: payload.message,
 8566                            percentage: payload.percentage.map(|p| p as usize),
 8567                            last_update_at: cx.background_executor().now(),
 8568                        },
 8569                        cx,
 8570                    );
 8571                }
 8572
 8573                proto::update_language_server::Variant::WorkEnd(payload) => {
 8574                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8575                }
 8576
 8577                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8578                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8579                }
 8580
 8581                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8582                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8583                }
 8584
 8585                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8586                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8587                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8588                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 8589                        language_server_id,
 8590                        name: envelope
 8591                            .payload
 8592                            .server_name
 8593                            .map(SharedString::new)
 8594                            .map(LanguageServerName),
 8595                        message: non_lsp,
 8596                    });
 8597                }
 8598            }
 8599
 8600            Ok(())
 8601        })?
 8602    }
 8603
 8604    async fn handle_language_server_log(
 8605        this: Entity<Self>,
 8606        envelope: TypedEnvelope<proto::LanguageServerLog>,
 8607        mut cx: AsyncApp,
 8608    ) -> Result<()> {
 8609        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8610        let log_type = envelope
 8611            .payload
 8612            .log_type
 8613            .map(LanguageServerLogType::from_proto)
 8614            .context("invalid language server log type")?;
 8615
 8616        let message = envelope.payload.message;
 8617
 8618        this.update(&mut cx, |_, cx| {
 8619            cx.emit(LspStoreEvent::LanguageServerLog(
 8620                language_server_id,
 8621                log_type,
 8622                message,
 8623            ));
 8624        })
 8625    }
 8626
 8627    async fn handle_lsp_ext_cancel_flycheck(
 8628        lsp_store: Entity<Self>,
 8629        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 8630        cx: AsyncApp,
 8631    ) -> Result<proto::Ack> {
 8632        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8633        lsp_store.read_with(&cx, |lsp_store, _| {
 8634            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8635                server
 8636                    .notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())
 8637                    .context("handling lsp ext cancel flycheck")
 8638            } else {
 8639                anyhow::Ok(())
 8640            }
 8641        })??;
 8642
 8643        Ok(proto::Ack {})
 8644    }
 8645
 8646    async fn handle_lsp_ext_run_flycheck(
 8647        lsp_store: Entity<Self>,
 8648        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 8649        mut cx: AsyncApp,
 8650    ) -> Result<proto::Ack> {
 8651        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8652        lsp_store.update(&mut cx, |lsp_store, cx| {
 8653            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8654                let text_document = if envelope.payload.current_file_only {
 8655                    let buffer_id = envelope
 8656                        .payload
 8657                        .buffer_id
 8658                        .map(|id| BufferId::new(id))
 8659                        .transpose()?;
 8660                    buffer_id
 8661                        .and_then(|buffer_id| {
 8662                            lsp_store
 8663                                .buffer_store()
 8664                                .read(cx)
 8665                                .get(buffer_id)
 8666                                .and_then(|buffer| {
 8667                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 8668                                })
 8669                                .map(|path| make_text_document_identifier(&path))
 8670                        })
 8671                        .transpose()?
 8672                } else {
 8673                    None
 8674                };
 8675                server
 8676                    .notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 8677                        &lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 8678                    )
 8679                    .context("handling lsp ext run flycheck")
 8680            } else {
 8681                anyhow::Ok(())
 8682            }
 8683        })??;
 8684
 8685        Ok(proto::Ack {})
 8686    }
 8687
 8688    async fn handle_lsp_ext_clear_flycheck(
 8689        lsp_store: Entity<Self>,
 8690        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 8691        cx: AsyncApp,
 8692    ) -> Result<proto::Ack> {
 8693        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8694        lsp_store.read_with(&cx, |lsp_store, _| {
 8695            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8696                server
 8697                    .notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())
 8698                    .context("handling lsp ext clear flycheck")
 8699            } else {
 8700                anyhow::Ok(())
 8701            }
 8702        })??;
 8703
 8704        Ok(proto::Ack {})
 8705    }
 8706
 8707    pub fn disk_based_diagnostics_started(
 8708        &mut self,
 8709        language_server_id: LanguageServerId,
 8710        cx: &mut Context<Self>,
 8711    ) {
 8712        if let Some(language_server_status) =
 8713            self.language_server_statuses.get_mut(&language_server_id)
 8714        {
 8715            language_server_status.has_pending_diagnostic_updates = true;
 8716        }
 8717
 8718        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 8719        cx.emit(LspStoreEvent::LanguageServerUpdate {
 8720            language_server_id,
 8721            name: self
 8722                .language_server_adapter_for_id(language_server_id)
 8723                .map(|adapter| adapter.name()),
 8724            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 8725                Default::default(),
 8726            ),
 8727        })
 8728    }
 8729
 8730    pub fn disk_based_diagnostics_finished(
 8731        &mut self,
 8732        language_server_id: LanguageServerId,
 8733        cx: &mut Context<Self>,
 8734    ) {
 8735        if let Some(language_server_status) =
 8736            self.language_server_statuses.get_mut(&language_server_id)
 8737        {
 8738            language_server_status.has_pending_diagnostic_updates = false;
 8739        }
 8740
 8741        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 8742        cx.emit(LspStoreEvent::LanguageServerUpdate {
 8743            language_server_id,
 8744            name: self
 8745                .language_server_adapter_for_id(language_server_id)
 8746                .map(|adapter| adapter.name()),
 8747            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 8748                Default::default(),
 8749            ),
 8750        })
 8751    }
 8752
 8753    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 8754    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 8755    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 8756    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 8757    // the language server might take some time to publish diagnostics.
 8758    fn simulate_disk_based_diagnostics_events_if_needed(
 8759        &mut self,
 8760        language_server_id: LanguageServerId,
 8761        cx: &mut Context<Self>,
 8762    ) {
 8763        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 8764
 8765        let Some(LanguageServerState::Running {
 8766            simulate_disk_based_diagnostics_completion,
 8767            adapter,
 8768            ..
 8769        }) = self
 8770            .as_local_mut()
 8771            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 8772        else {
 8773            return;
 8774        };
 8775
 8776        if adapter.disk_based_diagnostics_progress_token.is_some() {
 8777            return;
 8778        }
 8779
 8780        let prev_task =
 8781            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 8782                cx.background_executor()
 8783                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 8784                    .await;
 8785
 8786                this.update(cx, |this, cx| {
 8787                    this.disk_based_diagnostics_finished(language_server_id, cx);
 8788
 8789                    if let Some(LanguageServerState::Running {
 8790                        simulate_disk_based_diagnostics_completion,
 8791                        ..
 8792                    }) = this.as_local_mut().and_then(|local_store| {
 8793                        local_store.language_servers.get_mut(&language_server_id)
 8794                    }) {
 8795                        *simulate_disk_based_diagnostics_completion = None;
 8796                    }
 8797                })
 8798                .ok();
 8799            }));
 8800
 8801        if prev_task.is_none() {
 8802            self.disk_based_diagnostics_started(language_server_id, cx);
 8803        }
 8804    }
 8805
 8806    pub fn language_server_statuses(
 8807        &self,
 8808    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 8809        self.language_server_statuses
 8810            .iter()
 8811            .map(|(key, value)| (*key, value))
 8812    }
 8813
 8814    pub(super) fn did_rename_entry(
 8815        &self,
 8816        worktree_id: WorktreeId,
 8817        old_path: &Path,
 8818        new_path: &Path,
 8819        is_dir: bool,
 8820    ) {
 8821        maybe!({
 8822            let local_store = self.as_local()?;
 8823
 8824            let old_uri = lsp::Uri::from_file_path(old_path)
 8825                .ok()
 8826                .map(|uri| uri.to_string())?;
 8827            let new_uri = lsp::Uri::from_file_path(new_path)
 8828                .ok()
 8829                .map(|uri| uri.to_string())?;
 8830
 8831            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 8832                let Some(filter) = local_store
 8833                    .language_server_paths_watched_for_rename
 8834                    .get(&language_server.server_id())
 8835                else {
 8836                    continue;
 8837                };
 8838
 8839                if filter.should_send_did_rename(&old_uri, is_dir) {
 8840                    language_server
 8841                        .notify::<DidRenameFiles>(&RenameFilesParams {
 8842                            files: vec![FileRename {
 8843                                old_uri: old_uri.clone(),
 8844                                new_uri: new_uri.clone(),
 8845                            }],
 8846                        })
 8847                        .ok();
 8848                }
 8849            }
 8850            Some(())
 8851        });
 8852    }
 8853
 8854    pub(super) fn will_rename_entry(
 8855        this: WeakEntity<Self>,
 8856        worktree_id: WorktreeId,
 8857        old_path: &Path,
 8858        new_path: &Path,
 8859        is_dir: bool,
 8860        cx: AsyncApp,
 8861    ) -> Task<ProjectTransaction> {
 8862        let old_uri = lsp::Uri::from_file_path(old_path)
 8863            .ok()
 8864            .map(|uri| uri.to_string());
 8865        let new_uri = lsp::Uri::from_file_path(new_path)
 8866            .ok()
 8867            .map(|uri| uri.to_string());
 8868        cx.spawn(async move |cx| {
 8869            let mut tasks = vec![];
 8870            this.update(cx, |this, cx| {
 8871                let local_store = this.as_local()?;
 8872                let old_uri = old_uri?;
 8873                let new_uri = new_uri?;
 8874                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 8875                    let Some(filter) = local_store
 8876                        .language_server_paths_watched_for_rename
 8877                        .get(&language_server.server_id())
 8878                    else {
 8879                        continue;
 8880                    };
 8881
 8882                    if filter.should_send_will_rename(&old_uri, is_dir) {
 8883                        let apply_edit = cx.spawn({
 8884                            let old_uri = old_uri.clone();
 8885                            let new_uri = new_uri.clone();
 8886                            let language_server = language_server.clone();
 8887                            async move |this, cx| {
 8888                                let edit = language_server
 8889                                    .request::<WillRenameFiles>(RenameFilesParams {
 8890                                        files: vec![FileRename { old_uri, new_uri }],
 8891                                    })
 8892                                    .await
 8893                                    .into_response()
 8894                                    .context("will rename files")
 8895                                    .log_err()
 8896                                    .flatten()?;
 8897
 8898                                let transaction = LocalLspStore::deserialize_workspace_edit(
 8899                                    this.upgrade()?,
 8900                                    edit,
 8901                                    false,
 8902                                    language_server.clone(),
 8903                                    cx,
 8904                                )
 8905                                .await
 8906                                .ok()?;
 8907                                Some(transaction)
 8908                            }
 8909                        });
 8910                        tasks.push(apply_edit);
 8911                    }
 8912                }
 8913                Some(())
 8914            })
 8915            .ok()
 8916            .flatten();
 8917            let mut merged_transaction = ProjectTransaction::default();
 8918            for task in tasks {
 8919                // Await on tasks sequentially so that the order of application of edits is deterministic
 8920                // (at least with regards to the order of registration of language servers)
 8921                if let Some(transaction) = task.await {
 8922                    for (buffer, buffer_transaction) in transaction.0 {
 8923                        merged_transaction.0.insert(buffer, buffer_transaction);
 8924                    }
 8925                }
 8926            }
 8927            merged_transaction
 8928        })
 8929    }
 8930
 8931    fn lsp_notify_abs_paths_changed(
 8932        &mut self,
 8933        server_id: LanguageServerId,
 8934        changes: Vec<PathEvent>,
 8935    ) {
 8936        maybe!({
 8937            let server = self.language_server_for_id(server_id)?;
 8938            let changes = changes
 8939                .into_iter()
 8940                .filter_map(|event| {
 8941                    let typ = match event.kind? {
 8942                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 8943                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 8944                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 8945                    };
 8946                    Some(lsp::FileEvent {
 8947                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 8948                        typ,
 8949                    })
 8950                })
 8951                .collect::<Vec<_>>();
 8952            if !changes.is_empty() {
 8953                server
 8954                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 8955                        &lsp::DidChangeWatchedFilesParams { changes },
 8956                    )
 8957                    .ok();
 8958            }
 8959            Some(())
 8960        });
 8961    }
 8962
 8963    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 8964        self.as_local()?.language_server_for_id(id)
 8965    }
 8966
 8967    fn on_lsp_progress(
 8968        &mut self,
 8969        progress: lsp::ProgressParams,
 8970        language_server_id: LanguageServerId,
 8971        disk_based_diagnostics_progress_token: Option<String>,
 8972        cx: &mut Context<Self>,
 8973    ) {
 8974        let token = match progress.token {
 8975            lsp::NumberOrString::String(token) => token,
 8976            lsp::NumberOrString::Number(token) => {
 8977                log::info!("skipping numeric progress token {}", token);
 8978                return;
 8979            }
 8980        };
 8981
 8982        match progress.value {
 8983            lsp::ProgressParamsValue::WorkDone(progress) => {
 8984                self.handle_work_done_progress(
 8985                    progress,
 8986                    language_server_id,
 8987                    disk_based_diagnostics_progress_token,
 8988                    token,
 8989                    cx,
 8990                );
 8991            }
 8992            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 8993                if let Some(LanguageServerState::Running {
 8994                    workspace_refresh_task: Some(workspace_refresh_task),
 8995                    ..
 8996                }) = self
 8997                    .as_local_mut()
 8998                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 8999                {
 9000                    workspace_refresh_task.progress_tx.try_send(()).ok();
 9001                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9002                }
 9003            }
 9004        }
 9005    }
 9006
 9007    fn handle_work_done_progress(
 9008        &mut self,
 9009        progress: lsp::WorkDoneProgress,
 9010        language_server_id: LanguageServerId,
 9011        disk_based_diagnostics_progress_token: Option<String>,
 9012        token: String,
 9013        cx: &mut Context<Self>,
 9014    ) {
 9015        let language_server_status =
 9016            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9017                status
 9018            } else {
 9019                return;
 9020            };
 9021
 9022        if !language_server_status.progress_tokens.contains(&token) {
 9023            return;
 9024        }
 9025
 9026        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9027            .as_ref()
 9028            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9029
 9030        match progress {
 9031            lsp::WorkDoneProgress::Begin(report) => {
 9032                if is_disk_based_diagnostics_progress {
 9033                    self.disk_based_diagnostics_started(language_server_id, cx);
 9034                }
 9035                self.on_lsp_work_start(
 9036                    language_server_id,
 9037                    token.clone(),
 9038                    LanguageServerProgress {
 9039                        title: Some(report.title),
 9040                        is_disk_based_diagnostics_progress,
 9041                        is_cancellable: report.cancellable.unwrap_or(false),
 9042                        message: report.message.clone(),
 9043                        percentage: report.percentage.map(|p| p as usize),
 9044                        last_update_at: cx.background_executor().now(),
 9045                    },
 9046                    cx,
 9047                );
 9048            }
 9049            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9050                language_server_id,
 9051                token,
 9052                LanguageServerProgress {
 9053                    title: None,
 9054                    is_disk_based_diagnostics_progress,
 9055                    is_cancellable: report.cancellable.unwrap_or(false),
 9056                    message: report.message,
 9057                    percentage: report.percentage.map(|p| p as usize),
 9058                    last_update_at: cx.background_executor().now(),
 9059                },
 9060                cx,
 9061            ),
 9062            lsp::WorkDoneProgress::End(_) => {
 9063                language_server_status.progress_tokens.remove(&token);
 9064                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9065                if is_disk_based_diagnostics_progress {
 9066                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9067                }
 9068            }
 9069        }
 9070    }
 9071
 9072    fn on_lsp_work_start(
 9073        &mut self,
 9074        language_server_id: LanguageServerId,
 9075        token: String,
 9076        progress: LanguageServerProgress,
 9077        cx: &mut Context<Self>,
 9078    ) {
 9079        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9080            status.pending_work.insert(token.clone(), progress.clone());
 9081            cx.notify();
 9082        }
 9083        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9084            language_server_id,
 9085            name: self
 9086                .language_server_adapter_for_id(language_server_id)
 9087                .map(|adapter| adapter.name()),
 9088            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9089                token,
 9090                title: progress.title,
 9091                message: progress.message,
 9092                percentage: progress.percentage.map(|p| p as u32),
 9093                is_cancellable: Some(progress.is_cancellable),
 9094            }),
 9095        })
 9096    }
 9097
 9098    fn on_lsp_work_progress(
 9099        &mut self,
 9100        language_server_id: LanguageServerId,
 9101        token: String,
 9102        progress: LanguageServerProgress,
 9103        cx: &mut Context<Self>,
 9104    ) {
 9105        let mut did_update = false;
 9106        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9107            match status.pending_work.entry(token.clone()) {
 9108                btree_map::Entry::Vacant(entry) => {
 9109                    entry.insert(progress.clone());
 9110                    did_update = true;
 9111                }
 9112                btree_map::Entry::Occupied(mut entry) => {
 9113                    let entry = entry.get_mut();
 9114                    if (progress.last_update_at - entry.last_update_at)
 9115                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9116                    {
 9117                        entry.last_update_at = progress.last_update_at;
 9118                        if progress.message.is_some() {
 9119                            entry.message = progress.message.clone();
 9120                        }
 9121                        if progress.percentage.is_some() {
 9122                            entry.percentage = progress.percentage;
 9123                        }
 9124                        if progress.is_cancellable != entry.is_cancellable {
 9125                            entry.is_cancellable = progress.is_cancellable;
 9126                        }
 9127                        did_update = true;
 9128                    }
 9129                }
 9130            }
 9131        }
 9132
 9133        if did_update {
 9134            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9135                language_server_id,
 9136                name: self
 9137                    .language_server_adapter_for_id(language_server_id)
 9138                    .map(|adapter| adapter.name()),
 9139                message: proto::update_language_server::Variant::WorkProgress(
 9140                    proto::LspWorkProgress {
 9141                        token,
 9142                        message: progress.message,
 9143                        percentage: progress.percentage.map(|p| p as u32),
 9144                        is_cancellable: Some(progress.is_cancellable),
 9145                    },
 9146                ),
 9147            })
 9148        }
 9149    }
 9150
 9151    fn on_lsp_work_end(
 9152        &mut self,
 9153        language_server_id: LanguageServerId,
 9154        token: String,
 9155        cx: &mut Context<Self>,
 9156    ) {
 9157        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9158            if let Some(work) = status.pending_work.remove(&token)
 9159                && !work.is_disk_based_diagnostics_progress
 9160            {
 9161                cx.emit(LspStoreEvent::RefreshInlayHints);
 9162            }
 9163            cx.notify();
 9164        }
 9165
 9166        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9167            language_server_id,
 9168            name: self
 9169                .language_server_adapter_for_id(language_server_id)
 9170                .map(|adapter| adapter.name()),
 9171            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9172        })
 9173    }
 9174
 9175    pub async fn handle_resolve_completion_documentation(
 9176        this: Entity<Self>,
 9177        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9178        mut cx: AsyncApp,
 9179    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9180        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9181
 9182        let completion = this
 9183            .read_with(&cx, |this, cx| {
 9184                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9185                let server = this
 9186                    .language_server_for_id(id)
 9187                    .with_context(|| format!("No language server {id}"))?;
 9188
 9189                anyhow::Ok(cx.background_spawn(async move {
 9190                    let can_resolve = server
 9191                        .capabilities()
 9192                        .completion_provider
 9193                        .as_ref()
 9194                        .and_then(|options| options.resolve_provider)
 9195                        .unwrap_or(false);
 9196                    if can_resolve {
 9197                        server
 9198                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9199                            .await
 9200                            .into_response()
 9201                            .context("resolve completion item")
 9202                    } else {
 9203                        anyhow::Ok(lsp_completion)
 9204                    }
 9205                }))
 9206            })??
 9207            .await?;
 9208
 9209        let mut documentation_is_markdown = false;
 9210        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9211        let documentation = match completion.documentation {
 9212            Some(lsp::Documentation::String(text)) => text,
 9213
 9214            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9215                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9216                value
 9217            }
 9218
 9219            _ => String::new(),
 9220        };
 9221
 9222        // If we have a new buffer_id, that means we're talking to a new client
 9223        // and want to check for new text_edits in the completion too.
 9224        let mut old_replace_start = None;
 9225        let mut old_replace_end = None;
 9226        let mut old_insert_start = None;
 9227        let mut old_insert_end = None;
 9228        let mut new_text = String::default();
 9229        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9230            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9231                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9232                anyhow::Ok(buffer.read(cx).snapshot())
 9233            })??;
 9234
 9235            if let Some(text_edit) = completion.text_edit.as_ref() {
 9236                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9237
 9238                if let Some(mut edit) = edit {
 9239                    LineEnding::normalize(&mut edit.new_text);
 9240
 9241                    new_text = edit.new_text;
 9242                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9243                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9244                    if let Some(insert_range) = edit.insert_range {
 9245                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9246                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9247                    }
 9248                }
 9249            }
 9250        }
 9251
 9252        Ok(proto::ResolveCompletionDocumentationResponse {
 9253            documentation,
 9254            documentation_is_markdown,
 9255            old_replace_start,
 9256            old_replace_end,
 9257            new_text,
 9258            lsp_completion,
 9259            old_insert_start,
 9260            old_insert_end,
 9261        })
 9262    }
 9263
 9264    async fn handle_on_type_formatting(
 9265        this: Entity<Self>,
 9266        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9267        mut cx: AsyncApp,
 9268    ) -> Result<proto::OnTypeFormattingResponse> {
 9269        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9270            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9271            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9272            let position = envelope
 9273                .payload
 9274                .position
 9275                .and_then(deserialize_anchor)
 9276                .context("invalid position")?;
 9277            anyhow::Ok(this.apply_on_type_formatting(
 9278                buffer,
 9279                position,
 9280                envelope.payload.trigger.clone(),
 9281                cx,
 9282            ))
 9283        })??;
 9284
 9285        let transaction = on_type_formatting
 9286            .await?
 9287            .as_ref()
 9288            .map(language::proto::serialize_transaction);
 9289        Ok(proto::OnTypeFormattingResponse { transaction })
 9290    }
 9291
 9292    async fn handle_refresh_inlay_hints(
 9293        this: Entity<Self>,
 9294        _: TypedEnvelope<proto::RefreshInlayHints>,
 9295        mut cx: AsyncApp,
 9296    ) -> Result<proto::Ack> {
 9297        this.update(&mut cx, |_, cx| {
 9298            cx.emit(LspStoreEvent::RefreshInlayHints);
 9299        })?;
 9300        Ok(proto::Ack {})
 9301    }
 9302
 9303    async fn handle_pull_workspace_diagnostics(
 9304        lsp_store: Entity<Self>,
 9305        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9306        mut cx: AsyncApp,
 9307    ) -> Result<proto::Ack> {
 9308        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9309        lsp_store.update(&mut cx, |lsp_store, _| {
 9310            lsp_store.pull_workspace_diagnostics(server_id);
 9311        })?;
 9312        Ok(proto::Ack {})
 9313    }
 9314
 9315    async fn handle_inlay_hints(
 9316        this: Entity<Self>,
 9317        envelope: TypedEnvelope<proto::InlayHints>,
 9318        mut cx: AsyncApp,
 9319    ) -> Result<proto::InlayHintsResponse> {
 9320        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9321        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9322        let buffer = this.update(&mut cx, |this, cx| {
 9323            this.buffer_store.read(cx).get_existing(buffer_id)
 9324        })??;
 9325        buffer
 9326            .update(&mut cx, |buffer, _| {
 9327                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9328            })?
 9329            .await
 9330            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9331
 9332        let start = envelope
 9333            .payload
 9334            .start
 9335            .and_then(deserialize_anchor)
 9336            .context("missing range start")?;
 9337        let end = envelope
 9338            .payload
 9339            .end
 9340            .and_then(deserialize_anchor)
 9341            .context("missing range end")?;
 9342        let buffer_hints = this
 9343            .update(&mut cx, |lsp_store, cx| {
 9344                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9345            })?
 9346            .await
 9347            .context("inlay hints fetch")?;
 9348
 9349        this.update(&mut cx, |project, cx| {
 9350            InlayHints::response_to_proto(
 9351                buffer_hints,
 9352                project,
 9353                sender_id,
 9354                &buffer.read(cx).version(),
 9355                cx,
 9356            )
 9357        })
 9358    }
 9359
 9360    async fn handle_get_color_presentation(
 9361        lsp_store: Entity<Self>,
 9362        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9363        mut cx: AsyncApp,
 9364    ) -> Result<proto::GetColorPresentationResponse> {
 9365        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9366        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9367            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9368        })??;
 9369
 9370        let color = envelope
 9371            .payload
 9372            .color
 9373            .context("invalid color resolve request")?;
 9374        let start = color
 9375            .lsp_range_start
 9376            .context("invalid color resolve request")?;
 9377        let end = color
 9378            .lsp_range_end
 9379            .context("invalid color resolve request")?;
 9380
 9381        let color = DocumentColor {
 9382            lsp_range: lsp::Range {
 9383                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9384                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9385            },
 9386            color: lsp::Color {
 9387                red: color.red,
 9388                green: color.green,
 9389                blue: color.blue,
 9390                alpha: color.alpha,
 9391            },
 9392            resolved: false,
 9393            color_presentations: Vec::new(),
 9394        };
 9395        let resolved_color = lsp_store
 9396            .update(&mut cx, |lsp_store, cx| {
 9397                lsp_store.resolve_color_presentation(
 9398                    color,
 9399                    buffer.clone(),
 9400                    LanguageServerId(envelope.payload.server_id as usize),
 9401                    cx,
 9402                )
 9403            })?
 9404            .await
 9405            .context("resolving color presentation")?;
 9406
 9407        Ok(proto::GetColorPresentationResponse {
 9408            presentations: resolved_color
 9409                .color_presentations
 9410                .into_iter()
 9411                .map(|presentation| proto::ColorPresentation {
 9412                    label: presentation.label.to_string(),
 9413                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9414                    additional_text_edits: presentation
 9415                        .additional_text_edits
 9416                        .into_iter()
 9417                        .map(serialize_lsp_edit)
 9418                        .collect(),
 9419                })
 9420                .collect(),
 9421        })
 9422    }
 9423
 9424    async fn handle_resolve_inlay_hint(
 9425        this: Entity<Self>,
 9426        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9427        mut cx: AsyncApp,
 9428    ) -> Result<proto::ResolveInlayHintResponse> {
 9429        let proto_hint = envelope
 9430            .payload
 9431            .hint
 9432            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9433        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9434            .context("resolved proto inlay hint conversion")?;
 9435        let buffer = this.update(&mut cx, |this, cx| {
 9436            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9437            this.buffer_store.read(cx).get_existing(buffer_id)
 9438        })??;
 9439        let response_hint = this
 9440            .update(&mut cx, |this, cx| {
 9441                this.resolve_inlay_hint(
 9442                    hint,
 9443                    buffer,
 9444                    LanguageServerId(envelope.payload.language_server_id as usize),
 9445                    cx,
 9446                )
 9447            })?
 9448            .await
 9449            .context("inlay hints fetch")?;
 9450        Ok(proto::ResolveInlayHintResponse {
 9451            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9452        })
 9453    }
 9454
 9455    async fn handle_refresh_code_lens(
 9456        this: Entity<Self>,
 9457        _: TypedEnvelope<proto::RefreshCodeLens>,
 9458        mut cx: AsyncApp,
 9459    ) -> Result<proto::Ack> {
 9460        this.update(&mut cx, |_, cx| {
 9461            cx.emit(LspStoreEvent::RefreshCodeLens);
 9462        })?;
 9463        Ok(proto::Ack {})
 9464    }
 9465
 9466    async fn handle_open_buffer_for_symbol(
 9467        this: Entity<Self>,
 9468        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9469        mut cx: AsyncApp,
 9470    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9471        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9472        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9473        let symbol = Self::deserialize_symbol(symbol)?;
 9474        this.read_with(&cx, |this, _| {
 9475            if let SymbolLocation::OutsideProject {
 9476                abs_path,
 9477                signature,
 9478            } = &symbol.path
 9479            {
 9480                let new_signature = this.symbol_signature(&abs_path);
 9481                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9482            }
 9483            Ok(())
 9484        })??;
 9485        let buffer = this
 9486            .update(&mut cx, |this, cx| {
 9487                this.open_buffer_for_symbol(
 9488                    &Symbol {
 9489                        language_server_name: symbol.language_server_name,
 9490                        source_worktree_id: symbol.source_worktree_id,
 9491                        source_language_server_id: symbol.source_language_server_id,
 9492                        path: symbol.path,
 9493                        name: symbol.name,
 9494                        kind: symbol.kind,
 9495                        range: symbol.range,
 9496                        label: CodeLabel {
 9497                            text: Default::default(),
 9498                            runs: Default::default(),
 9499                            filter_range: Default::default(),
 9500                        },
 9501                    },
 9502                    cx,
 9503                )
 9504            })?
 9505            .await?;
 9506
 9507        this.update(&mut cx, |this, cx| {
 9508            let is_private = buffer
 9509                .read(cx)
 9510                .file()
 9511                .map(|f| f.is_private())
 9512                .unwrap_or_default();
 9513            if is_private {
 9514                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9515            } else {
 9516                this.buffer_store
 9517                    .update(cx, |buffer_store, cx| {
 9518                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9519                    })
 9520                    .detach_and_log_err(cx);
 9521                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9522                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9523            }
 9524        })?
 9525    }
 9526
 9527    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9528        let mut hasher = Sha256::new();
 9529        hasher.update(abs_path.to_string_lossy().as_bytes());
 9530        hasher.update(self.nonce.to_be_bytes());
 9531        hasher.finalize().as_slice().try_into().unwrap()
 9532    }
 9533
 9534    pub async fn handle_get_project_symbols(
 9535        this: Entity<Self>,
 9536        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9537        mut cx: AsyncApp,
 9538    ) -> Result<proto::GetProjectSymbolsResponse> {
 9539        let symbols = this
 9540            .update(&mut cx, |this, cx| {
 9541                this.symbols(&envelope.payload.query, cx)
 9542            })?
 9543            .await?;
 9544
 9545        Ok(proto::GetProjectSymbolsResponse {
 9546            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9547        })
 9548    }
 9549
 9550    pub async fn handle_restart_language_servers(
 9551        this: Entity<Self>,
 9552        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9553        mut cx: AsyncApp,
 9554    ) -> Result<proto::Ack> {
 9555        this.update(&mut cx, |lsp_store, cx| {
 9556            let buffers =
 9557                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9558            lsp_store.restart_language_servers_for_buffers(
 9559                buffers,
 9560                envelope
 9561                    .payload
 9562                    .only_servers
 9563                    .into_iter()
 9564                    .filter_map(|selector| {
 9565                        Some(match selector.selector? {
 9566                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9567                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9568                            }
 9569                            proto::language_server_selector::Selector::Name(name) => {
 9570                                LanguageServerSelector::Name(LanguageServerName(
 9571                                    SharedString::from(name),
 9572                                ))
 9573                            }
 9574                        })
 9575                    })
 9576                    .collect(),
 9577                cx,
 9578            );
 9579        })?;
 9580
 9581        Ok(proto::Ack {})
 9582    }
 9583
 9584    pub async fn handle_stop_language_servers(
 9585        lsp_store: Entity<Self>,
 9586        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9587        mut cx: AsyncApp,
 9588    ) -> Result<proto::Ack> {
 9589        lsp_store.update(&mut cx, |lsp_store, cx| {
 9590            if envelope.payload.all
 9591                && envelope.payload.also_servers.is_empty()
 9592                && envelope.payload.buffer_ids.is_empty()
 9593            {
 9594                lsp_store.stop_all_language_servers(cx);
 9595            } else {
 9596                let buffers =
 9597                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9598                lsp_store
 9599                    .stop_language_servers_for_buffers(
 9600                        buffers,
 9601                        envelope
 9602                            .payload
 9603                            .also_servers
 9604                            .into_iter()
 9605                            .filter_map(|selector| {
 9606                                Some(match selector.selector? {
 9607                                    proto::language_server_selector::Selector::ServerId(
 9608                                        server_id,
 9609                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9610                                        server_id,
 9611                                    )),
 9612                                    proto::language_server_selector::Selector::Name(name) => {
 9613                                        LanguageServerSelector::Name(LanguageServerName(
 9614                                            SharedString::from(name),
 9615                                        ))
 9616                                    }
 9617                                })
 9618                            })
 9619                            .collect(),
 9620                        cx,
 9621                    )
 9622                    .detach_and_log_err(cx);
 9623            }
 9624        })?;
 9625
 9626        Ok(proto::Ack {})
 9627    }
 9628
 9629    pub async fn handle_cancel_language_server_work(
 9630        this: Entity<Self>,
 9631        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
 9632        mut cx: AsyncApp,
 9633    ) -> Result<proto::Ack> {
 9634        this.update(&mut cx, |this, cx| {
 9635            if let Some(work) = envelope.payload.work {
 9636                match work {
 9637                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
 9638                        let buffers =
 9639                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
 9640                        this.cancel_language_server_work_for_buffers(buffers, cx);
 9641                    }
 9642                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
 9643                        let server_id = LanguageServerId::from_proto(work.language_server_id);
 9644                        this.cancel_language_server_work(server_id, work.token, cx);
 9645                    }
 9646                }
 9647            }
 9648        })?;
 9649
 9650        Ok(proto::Ack {})
 9651    }
 9652
 9653    fn buffer_ids_to_buffers(
 9654        &mut self,
 9655        buffer_ids: impl Iterator<Item = u64>,
 9656        cx: &mut Context<Self>,
 9657    ) -> Vec<Entity<Buffer>> {
 9658        buffer_ids
 9659            .into_iter()
 9660            .flat_map(|buffer_id| {
 9661                self.buffer_store
 9662                    .read(cx)
 9663                    .get(BufferId::new(buffer_id).log_err()?)
 9664            })
 9665            .collect::<Vec<_>>()
 9666    }
 9667
 9668    async fn handle_apply_additional_edits_for_completion(
 9669        this: Entity<Self>,
 9670        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
 9671        mut cx: AsyncApp,
 9672    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
 9673        let (buffer, completion) = this.update(&mut cx, |this, cx| {
 9674            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9675            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9676            let completion = Self::deserialize_completion(
 9677                envelope.payload.completion.context("invalid completion")?,
 9678            )?;
 9679            anyhow::Ok((buffer, completion))
 9680        })??;
 9681
 9682        let apply_additional_edits = this.update(&mut cx, |this, cx| {
 9683            this.apply_additional_edits_for_completion(
 9684                buffer,
 9685                Rc::new(RefCell::new(Box::new([Completion {
 9686                    replace_range: completion.replace_range,
 9687                    new_text: completion.new_text,
 9688                    source: completion.source,
 9689                    documentation: None,
 9690                    label: CodeLabel {
 9691                        text: Default::default(),
 9692                        runs: Default::default(),
 9693                        filter_range: Default::default(),
 9694                    },
 9695                    insert_text_mode: None,
 9696                    icon_path: None,
 9697                    confirm: None,
 9698                }]))),
 9699                0,
 9700                false,
 9701                cx,
 9702            )
 9703        })?;
 9704
 9705        Ok(proto::ApplyCompletionAdditionalEditsResponse {
 9706            transaction: apply_additional_edits
 9707                .await?
 9708                .as_ref()
 9709                .map(language::proto::serialize_transaction),
 9710        })
 9711    }
 9712
 9713    pub fn last_formatting_failure(&self) -> Option<&str> {
 9714        self.last_formatting_failure.as_deref()
 9715    }
 9716
 9717    pub fn reset_last_formatting_failure(&mut self) {
 9718        self.last_formatting_failure = None;
 9719    }
 9720
 9721    pub fn environment_for_buffer(
 9722        &self,
 9723        buffer: &Entity<Buffer>,
 9724        cx: &mut Context<Self>,
 9725    ) -> Shared<Task<Option<HashMap<String, String>>>> {
 9726        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
 9727            environment.update(cx, |env, cx| {
 9728                env.get_buffer_environment(buffer, &self.worktree_store, cx)
 9729            })
 9730        } else {
 9731            Task::ready(None).shared()
 9732        }
 9733    }
 9734
 9735    pub fn format(
 9736        &mut self,
 9737        buffers: HashSet<Entity<Buffer>>,
 9738        target: LspFormatTarget,
 9739        push_to_history: bool,
 9740        trigger: FormatTrigger,
 9741        cx: &mut Context<Self>,
 9742    ) -> Task<anyhow::Result<ProjectTransaction>> {
 9743        let logger = zlog::scoped!("format");
 9744        if self.as_local().is_some() {
 9745            zlog::trace!(logger => "Formatting locally");
 9746            let logger = zlog::scoped!(logger => "local");
 9747            let buffers = buffers
 9748                .into_iter()
 9749                .map(|buffer_handle| {
 9750                    let buffer = buffer_handle.read(cx);
 9751                    let buffer_abs_path = File::from_dyn(buffer.file())
 9752                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
 9753
 9754                    (buffer_handle, buffer_abs_path, buffer.remote_id())
 9755                })
 9756                .collect::<Vec<_>>();
 9757
 9758            cx.spawn(async move |lsp_store, cx| {
 9759                let mut formattable_buffers = Vec::with_capacity(buffers.len());
 9760
 9761                for (handle, abs_path, id) in buffers {
 9762                    let env = lsp_store
 9763                        .update(cx, |lsp_store, cx| {
 9764                            lsp_store.environment_for_buffer(&handle, cx)
 9765                        })?
 9766                        .await;
 9767
 9768                    let ranges = match &target {
 9769                        LspFormatTarget::Buffers => None,
 9770                        LspFormatTarget::Ranges(ranges) => {
 9771                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
 9772                        }
 9773                    };
 9774
 9775                    formattable_buffers.push(FormattableBuffer {
 9776                        handle,
 9777                        abs_path,
 9778                        env,
 9779                        ranges,
 9780                    });
 9781                }
 9782                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
 9783
 9784                let format_timer = zlog::time!(logger => "Formatting buffers");
 9785                let result = LocalLspStore::format_locally(
 9786                    lsp_store.clone(),
 9787                    formattable_buffers,
 9788                    push_to_history,
 9789                    trigger,
 9790                    logger,
 9791                    cx,
 9792                )
 9793                .await;
 9794                format_timer.end();
 9795
 9796                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
 9797
 9798                lsp_store.update(cx, |lsp_store, _| {
 9799                    lsp_store.update_last_formatting_failure(&result);
 9800                })?;
 9801
 9802                result
 9803            })
 9804        } else if let Some((client, project_id)) = self.upstream_client() {
 9805            zlog::trace!(logger => "Formatting remotely");
 9806            let logger = zlog::scoped!(logger => "remote");
 9807            // Don't support formatting ranges via remote
 9808            match target {
 9809                LspFormatTarget::Buffers => {}
 9810                LspFormatTarget::Ranges(_) => {
 9811                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
 9812                    return Task::ready(Ok(ProjectTransaction::default()));
 9813                }
 9814            }
 9815
 9816            let buffer_store = self.buffer_store();
 9817            cx.spawn(async move |lsp_store, cx| {
 9818                zlog::trace!(logger => "Sending remote format request");
 9819                let request_timer = zlog::time!(logger => "remote format request");
 9820                let result = client
 9821                    .request(proto::FormatBuffers {
 9822                        project_id,
 9823                        trigger: trigger as i32,
 9824                        buffer_ids: buffers
 9825                            .iter()
 9826                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
 9827                            .collect::<Result<_>>()?,
 9828                    })
 9829                    .await
 9830                    .and_then(|result| result.transaction.context("missing transaction"));
 9831                request_timer.end();
 9832
 9833                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
 9834
 9835                lsp_store.update(cx, |lsp_store, _| {
 9836                    lsp_store.update_last_formatting_failure(&result);
 9837                })?;
 9838
 9839                let transaction_response = result?;
 9840                let _timer = zlog::time!(logger => "deserializing project transaction");
 9841                buffer_store
 9842                    .update(cx, |buffer_store, cx| {
 9843                        buffer_store.deserialize_project_transaction(
 9844                            transaction_response,
 9845                            push_to_history,
 9846                            cx,
 9847                        )
 9848                    })?
 9849                    .await
 9850            })
 9851        } else {
 9852            zlog::trace!(logger => "Not formatting");
 9853            Task::ready(Ok(ProjectTransaction::default()))
 9854        }
 9855    }
 9856
 9857    async fn handle_format_buffers(
 9858        this: Entity<Self>,
 9859        envelope: TypedEnvelope<proto::FormatBuffers>,
 9860        mut cx: AsyncApp,
 9861    ) -> Result<proto::FormatBuffersResponse> {
 9862        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9863        let format = this.update(&mut cx, |this, cx| {
 9864            let mut buffers = HashSet::default();
 9865            for buffer_id in &envelope.payload.buffer_ids {
 9866                let buffer_id = BufferId::new(*buffer_id)?;
 9867                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
 9868            }
 9869            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
 9870            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
 9871        })??;
 9872
 9873        let project_transaction = format.await?;
 9874        let project_transaction = this.update(&mut cx, |this, cx| {
 9875            this.buffer_store.update(cx, |buffer_store, cx| {
 9876                buffer_store.serialize_project_transaction_for_peer(
 9877                    project_transaction,
 9878                    sender_id,
 9879                    cx,
 9880                )
 9881            })
 9882        })?;
 9883        Ok(proto::FormatBuffersResponse {
 9884            transaction: Some(project_transaction),
 9885        })
 9886    }
 9887
 9888    async fn handle_apply_code_action_kind(
 9889        this: Entity<Self>,
 9890        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
 9891        mut cx: AsyncApp,
 9892    ) -> Result<proto::ApplyCodeActionKindResponse> {
 9893        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9894        let format = this.update(&mut cx, |this, cx| {
 9895            let mut buffers = HashSet::default();
 9896            for buffer_id in &envelope.payload.buffer_ids {
 9897                let buffer_id = BufferId::new(*buffer_id)?;
 9898                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
 9899            }
 9900            let kind = match envelope.payload.kind.as_str() {
 9901                "" => CodeActionKind::EMPTY,
 9902                "quickfix" => CodeActionKind::QUICKFIX,
 9903                "refactor" => CodeActionKind::REFACTOR,
 9904                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
 9905                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
 9906                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
 9907                "source" => CodeActionKind::SOURCE,
 9908                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
 9909                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
 9910                _ => anyhow::bail!(
 9911                    "Invalid code action kind {}",
 9912                    envelope.payload.kind.as_str()
 9913                ),
 9914            };
 9915            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
 9916        })??;
 9917
 9918        let project_transaction = format.await?;
 9919        let project_transaction = this.update(&mut cx, |this, cx| {
 9920            this.buffer_store.update(cx, |buffer_store, cx| {
 9921                buffer_store.serialize_project_transaction_for_peer(
 9922                    project_transaction,
 9923                    sender_id,
 9924                    cx,
 9925                )
 9926            })
 9927        })?;
 9928        Ok(proto::ApplyCodeActionKindResponse {
 9929            transaction: Some(project_transaction),
 9930        })
 9931    }
 9932
 9933    async fn shutdown_language_server(
 9934        server_state: Option<LanguageServerState>,
 9935        name: LanguageServerName,
 9936        cx: &mut AsyncApp,
 9937    ) {
 9938        let server = match server_state {
 9939            Some(LanguageServerState::Starting { startup, .. }) => {
 9940                let mut timer = cx
 9941                    .background_executor()
 9942                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
 9943                    .fuse();
 9944
 9945                select! {
 9946                    server = startup.fuse() => server,
 9947                    () = timer => {
 9948                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
 9949                        None
 9950                    },
 9951                }
 9952            }
 9953
 9954            Some(LanguageServerState::Running { server, .. }) => Some(server),
 9955
 9956            None => None,
 9957        };
 9958
 9959        if let Some(server) = server
 9960            && let Some(shutdown) = server.shutdown()
 9961        {
 9962            shutdown.await;
 9963        }
 9964    }
 9965
 9966    // Returns a list of all of the worktrees which no longer have a language server and the root path
 9967    // for the stopped server
 9968    fn stop_local_language_server(
 9969        &mut self,
 9970        server_id: LanguageServerId,
 9971        cx: &mut Context<Self>,
 9972    ) -> Task<()> {
 9973        let local = match &mut self.mode {
 9974            LspStoreMode::Local(local) => local,
 9975            _ => {
 9976                return Task::ready(());
 9977            }
 9978        };
 9979
 9980        // Remove this server ID from all entries in the given worktree.
 9981        local
 9982            .language_server_ids
 9983            .retain(|_, state| state.id != server_id);
 9984        self.buffer_store.update(cx, |buffer_store, cx| {
 9985            for buffer in buffer_store.buffers() {
 9986                buffer.update(cx, |buffer, cx| {
 9987                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 9988                    buffer.set_completion_triggers(server_id, Default::default(), cx);
 9989                });
 9990            }
 9991        });
 9992
 9993        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
 9994            summaries.retain(|path, summaries_by_server_id| {
 9995                if summaries_by_server_id.remove(&server_id).is_some() {
 9996                    if let Some((client, project_id)) = self.downstream_client.clone() {
 9997                        client
 9998                            .send(proto::UpdateDiagnosticSummary {
 9999                                project_id,
10000                                worktree_id: worktree_id.to_proto(),
10001                                summary: Some(proto::DiagnosticSummary {
10002                                    path: path.as_ref().to_proto(),
10003                                    language_server_id: server_id.0 as u64,
10004                                    error_count: 0,
10005                                    warning_count: 0,
10006                                }),
10007                                more_summaries: Vec::new(),
10008                            })
10009                            .log_err();
10010                    }
10011                    !summaries_by_server_id.is_empty()
10012                } else {
10013                    true
10014                }
10015            });
10016        }
10017
10018        let local = self.as_local_mut().unwrap();
10019        for diagnostics in local.diagnostics.values_mut() {
10020            diagnostics.retain(|_, diagnostics_by_server_id| {
10021                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10022                    diagnostics_by_server_id.remove(ix);
10023                    !diagnostics_by_server_id.is_empty()
10024                } else {
10025                    true
10026                }
10027            });
10028        }
10029        local.language_server_watched_paths.remove(&server_id);
10030
10031        let server_state = local.language_servers.remove(&server_id);
10032        self.cleanup_lsp_data(server_id);
10033        let name = self
10034            .language_server_statuses
10035            .remove(&server_id)
10036            .map(|status| status.name)
10037            .or_else(|| {
10038                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10039                    Some(adapter.name())
10040                } else {
10041                    None
10042                }
10043            });
10044
10045        if let Some(name) = name {
10046            log::info!("stopping language server {name}");
10047            self.languages
10048                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10049            cx.notify();
10050
10051            return cx.spawn(async move |lsp_store, cx| {
10052                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10053                lsp_store
10054                    .update(cx, |lsp_store, cx| {
10055                        lsp_store
10056                            .languages
10057                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10058                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10059                        cx.notify();
10060                    })
10061                    .ok();
10062            });
10063        }
10064
10065        if server_state.is_some() {
10066            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10067        }
10068        Task::ready(())
10069    }
10070
10071    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10072        if let Some((client, project_id)) = self.upstream_client() {
10073            let request = client.request(proto::StopLanguageServers {
10074                project_id,
10075                buffer_ids: Vec::new(),
10076                also_servers: Vec::new(),
10077                all: true,
10078            });
10079            cx.background_spawn(request).detach_and_log_err(cx);
10080        } else {
10081            let Some(local) = self.as_local_mut() else {
10082                return;
10083            };
10084            let language_servers_to_stop = local
10085                .language_server_ids
10086                .values()
10087                .map(|state| state.id)
10088                .collect();
10089            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10090            let tasks = language_servers_to_stop
10091                .into_iter()
10092                .map(|server| self.stop_local_language_server(server, cx))
10093                .collect::<Vec<_>>();
10094            cx.background_spawn(async move {
10095                futures::future::join_all(tasks).await;
10096            })
10097            .detach();
10098        }
10099    }
10100
10101    pub fn restart_language_servers_for_buffers(
10102        &mut self,
10103        buffers: Vec<Entity<Buffer>>,
10104        only_restart_servers: HashSet<LanguageServerSelector>,
10105        cx: &mut Context<Self>,
10106    ) {
10107        if let Some((client, project_id)) = self.upstream_client() {
10108            let request = client.request(proto::RestartLanguageServers {
10109                project_id,
10110                buffer_ids: buffers
10111                    .into_iter()
10112                    .map(|b| b.read(cx).remote_id().to_proto())
10113                    .collect(),
10114                only_servers: only_restart_servers
10115                    .into_iter()
10116                    .map(|selector| {
10117                        let selector = match selector {
10118                            LanguageServerSelector::Id(language_server_id) => {
10119                                proto::language_server_selector::Selector::ServerId(
10120                                    language_server_id.to_proto(),
10121                                )
10122                            }
10123                            LanguageServerSelector::Name(language_server_name) => {
10124                                proto::language_server_selector::Selector::Name(
10125                                    language_server_name.to_string(),
10126                                )
10127                            }
10128                        };
10129                        proto::LanguageServerSelector {
10130                            selector: Some(selector),
10131                        }
10132                    })
10133                    .collect(),
10134                all: false,
10135            });
10136            cx.background_spawn(request).detach_and_log_err(cx);
10137        } else {
10138            let stop_task = if only_restart_servers.is_empty() {
10139                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10140            } else {
10141                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10142            };
10143            cx.spawn(async move |lsp_store, cx| {
10144                stop_task.await;
10145                lsp_store
10146                    .update(cx, |lsp_store, cx| {
10147                        for buffer in buffers {
10148                            lsp_store.register_buffer_with_language_servers(
10149                                &buffer,
10150                                only_restart_servers.clone(),
10151                                true,
10152                                cx,
10153                            );
10154                        }
10155                    })
10156                    .ok()
10157            })
10158            .detach();
10159        }
10160    }
10161
10162    pub fn stop_language_servers_for_buffers(
10163        &mut self,
10164        buffers: Vec<Entity<Buffer>>,
10165        also_stop_servers: HashSet<LanguageServerSelector>,
10166        cx: &mut Context<Self>,
10167    ) -> Task<Result<()>> {
10168        if let Some((client, project_id)) = self.upstream_client() {
10169            let request = client.request(proto::StopLanguageServers {
10170                project_id,
10171                buffer_ids: buffers
10172                    .into_iter()
10173                    .map(|b| b.read(cx).remote_id().to_proto())
10174                    .collect(),
10175                also_servers: also_stop_servers
10176                    .into_iter()
10177                    .map(|selector| {
10178                        let selector = match selector {
10179                            LanguageServerSelector::Id(language_server_id) => {
10180                                proto::language_server_selector::Selector::ServerId(
10181                                    language_server_id.to_proto(),
10182                                )
10183                            }
10184                            LanguageServerSelector::Name(language_server_name) => {
10185                                proto::language_server_selector::Selector::Name(
10186                                    language_server_name.to_string(),
10187                                )
10188                            }
10189                        };
10190                        proto::LanguageServerSelector {
10191                            selector: Some(selector),
10192                        }
10193                    })
10194                    .collect(),
10195                all: false,
10196            });
10197            cx.background_spawn(async move {
10198                let _ = request.await?;
10199                Ok(())
10200            })
10201        } else {
10202            let task =
10203                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10204            cx.background_spawn(async move {
10205                task.await;
10206                Ok(())
10207            })
10208        }
10209    }
10210
10211    fn stop_local_language_servers_for_buffers(
10212        &mut self,
10213        buffers: &[Entity<Buffer>],
10214        also_stop_servers: HashSet<LanguageServerSelector>,
10215        cx: &mut Context<Self>,
10216    ) -> Task<()> {
10217        let Some(local) = self.as_local_mut() else {
10218            return Task::ready(());
10219        };
10220        let mut language_server_names_to_stop = BTreeSet::default();
10221        let mut language_servers_to_stop = also_stop_servers
10222            .into_iter()
10223            .flat_map(|selector| match selector {
10224                LanguageServerSelector::Id(id) => Some(id),
10225                LanguageServerSelector::Name(name) => {
10226                    language_server_names_to_stop.insert(name);
10227                    None
10228                }
10229            })
10230            .collect::<BTreeSet<_>>();
10231
10232        let mut covered_worktrees = HashSet::default();
10233        for buffer in buffers {
10234            buffer.update(cx, |buffer, cx| {
10235                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10236                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10237                    && covered_worktrees.insert(worktree_id)
10238                {
10239                    language_server_names_to_stop.retain(|name| {
10240                        let old_ids_count = language_servers_to_stop.len();
10241                        let all_language_servers_with_this_name = local
10242                            .language_server_ids
10243                            .iter()
10244                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10245                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10246                        old_ids_count == language_servers_to_stop.len()
10247                    });
10248                }
10249            });
10250        }
10251        for name in language_server_names_to_stop {
10252            language_servers_to_stop.extend(
10253                local
10254                    .language_server_ids
10255                    .iter()
10256                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10257            );
10258        }
10259
10260        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10261        let tasks = language_servers_to_stop
10262            .into_iter()
10263            .map(|server| self.stop_local_language_server(server, cx))
10264            .collect::<Vec<_>>();
10265
10266        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10267    }
10268
10269    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10270        let (worktree, relative_path) =
10271            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10272
10273        let project_path = ProjectPath {
10274            worktree_id: worktree.read(cx).id(),
10275            path: relative_path,
10276        };
10277
10278        Some(
10279            self.buffer_store()
10280                .read(cx)
10281                .get_by_path(&project_path)?
10282                .read(cx),
10283        )
10284    }
10285
10286    #[cfg(any(test, feature = "test-support"))]
10287    pub fn update_diagnostics(
10288        &mut self,
10289        server_id: LanguageServerId,
10290        diagnostics: lsp::PublishDiagnosticsParams,
10291        result_id: Option<String>,
10292        source_kind: DiagnosticSourceKind,
10293        disk_based_sources: &[String],
10294        cx: &mut Context<Self>,
10295    ) -> Result<()> {
10296        self.merge_lsp_diagnostics(
10297            source_kind,
10298            vec![DocumentDiagnosticsUpdate {
10299                diagnostics,
10300                result_id,
10301                server_id,
10302                disk_based_sources: Cow::Borrowed(disk_based_sources),
10303            }],
10304            |_, _, _| false,
10305            cx,
10306        )
10307    }
10308
10309    pub fn merge_lsp_diagnostics(
10310        &mut self,
10311        source_kind: DiagnosticSourceKind,
10312        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10313        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10314        cx: &mut Context<Self>,
10315    ) -> Result<()> {
10316        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10317        let updates = lsp_diagnostics
10318            .into_iter()
10319            .filter_map(|update| {
10320                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10321                Some(DocumentDiagnosticsUpdate {
10322                    diagnostics: self.lsp_to_document_diagnostics(
10323                        abs_path,
10324                        source_kind,
10325                        update.server_id,
10326                        update.diagnostics,
10327                        &update.disk_based_sources,
10328                    ),
10329                    result_id: update.result_id,
10330                    server_id: update.server_id,
10331                    disk_based_sources: update.disk_based_sources,
10332                })
10333            })
10334            .collect();
10335        self.merge_diagnostic_entries(updates, merge, cx)?;
10336        Ok(())
10337    }
10338
10339    fn lsp_to_document_diagnostics(
10340        &mut self,
10341        document_abs_path: PathBuf,
10342        source_kind: DiagnosticSourceKind,
10343        server_id: LanguageServerId,
10344        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10345        disk_based_sources: &[String],
10346    ) -> DocumentDiagnostics {
10347        let mut diagnostics = Vec::default();
10348        let mut primary_diagnostic_group_ids = HashMap::default();
10349        let mut sources_by_group_id = HashMap::default();
10350        let mut supporting_diagnostics = HashMap::default();
10351
10352        let adapter = self.language_server_adapter_for_id(server_id);
10353
10354        // Ensure that primary diagnostics are always the most severe
10355        lsp_diagnostics
10356            .diagnostics
10357            .sort_by_key(|item| item.severity);
10358
10359        for diagnostic in &lsp_diagnostics.diagnostics {
10360            let source = diagnostic.source.as_ref();
10361            let range = range_from_lsp(diagnostic.range);
10362            let is_supporting = diagnostic
10363                .related_information
10364                .as_ref()
10365                .is_some_and(|infos| {
10366                    infos.iter().any(|info| {
10367                        primary_diagnostic_group_ids.contains_key(&(
10368                            source,
10369                            diagnostic.code.clone(),
10370                            range_from_lsp(info.location.range),
10371                        ))
10372                    })
10373                });
10374
10375            let is_unnecessary = diagnostic
10376                .tags
10377                .as_ref()
10378                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10379
10380            let underline = self
10381                .language_server_adapter_for_id(server_id)
10382                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10383
10384            if is_supporting {
10385                supporting_diagnostics.insert(
10386                    (source, diagnostic.code.clone(), range),
10387                    (diagnostic.severity, is_unnecessary),
10388                );
10389            } else {
10390                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10391                let is_disk_based =
10392                    source.is_some_and(|source| disk_based_sources.contains(source));
10393
10394                sources_by_group_id.insert(group_id, source);
10395                primary_diagnostic_group_ids
10396                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10397
10398                diagnostics.push(DiagnosticEntry {
10399                    range,
10400                    diagnostic: Diagnostic {
10401                        source: diagnostic.source.clone(),
10402                        source_kind,
10403                        code: diagnostic.code.clone(),
10404                        code_description: diagnostic
10405                            .code_description
10406                            .as_ref()
10407                            .and_then(|d| d.href.clone()),
10408                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10409                        markdown: adapter.as_ref().and_then(|adapter| {
10410                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10411                        }),
10412                        message: diagnostic.message.trim().to_string(),
10413                        group_id,
10414                        is_primary: true,
10415                        is_disk_based,
10416                        is_unnecessary,
10417                        underline,
10418                        data: diagnostic.data.clone(),
10419                    },
10420                });
10421                if let Some(infos) = &diagnostic.related_information {
10422                    for info in infos {
10423                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10424                            let range = range_from_lsp(info.location.range);
10425                            diagnostics.push(DiagnosticEntry {
10426                                range,
10427                                diagnostic: Diagnostic {
10428                                    source: diagnostic.source.clone(),
10429                                    source_kind,
10430                                    code: diagnostic.code.clone(),
10431                                    code_description: diagnostic
10432                                        .code_description
10433                                        .as_ref()
10434                                        .and_then(|d| d.href.clone()),
10435                                    severity: DiagnosticSeverity::INFORMATION,
10436                                    markdown: adapter.as_ref().and_then(|adapter| {
10437                                        adapter.diagnostic_message_to_markdown(&info.message)
10438                                    }),
10439                                    message: info.message.trim().to_string(),
10440                                    group_id,
10441                                    is_primary: false,
10442                                    is_disk_based,
10443                                    is_unnecessary: false,
10444                                    underline,
10445                                    data: diagnostic.data.clone(),
10446                                },
10447                            });
10448                        }
10449                    }
10450                }
10451            }
10452        }
10453
10454        for entry in &mut diagnostics {
10455            let diagnostic = &mut entry.diagnostic;
10456            if !diagnostic.is_primary {
10457                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10458                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10459                    source,
10460                    diagnostic.code.clone(),
10461                    entry.range.clone(),
10462                )) {
10463                    if let Some(severity) = severity {
10464                        diagnostic.severity = severity;
10465                    }
10466                    diagnostic.is_unnecessary = is_unnecessary;
10467                }
10468            }
10469        }
10470
10471        DocumentDiagnostics {
10472            diagnostics,
10473            document_abs_path,
10474            version: lsp_diagnostics.version,
10475        }
10476    }
10477
10478    fn insert_newly_running_language_server(
10479        &mut self,
10480        adapter: Arc<CachedLspAdapter>,
10481        language_server: Arc<LanguageServer>,
10482        server_id: LanguageServerId,
10483        key: LanguageServerSeed,
10484        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10485        cx: &mut Context<Self>,
10486    ) {
10487        let Some(local) = self.as_local_mut() else {
10488            return;
10489        };
10490        // If the language server for this key doesn't match the server id, don't store the
10491        // server. Which will cause it to be dropped, killing the process
10492        if local
10493            .language_server_ids
10494            .get(&key)
10495            .map(|state| state.id != server_id)
10496            .unwrap_or(false)
10497        {
10498            return;
10499        }
10500
10501        // Update language_servers collection with Running variant of LanguageServerState
10502        // indicating that the server is up and running and ready
10503        let workspace_folders = workspace_folders.lock().clone();
10504        language_server.set_workspace_folders(workspace_folders);
10505
10506        local.language_servers.insert(
10507            server_id,
10508            LanguageServerState::Running {
10509                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10510                    language_server.clone(),
10511                    cx,
10512                ),
10513                adapter: adapter.clone(),
10514                server: language_server.clone(),
10515                simulate_disk_based_diagnostics_completion: None,
10516            },
10517        );
10518        local
10519            .languages
10520            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10521        if let Some(file_ops_caps) = language_server
10522            .capabilities()
10523            .workspace
10524            .as_ref()
10525            .and_then(|ws| ws.file_operations.as_ref())
10526        {
10527            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10528            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10529            if did_rename_caps.or(will_rename_caps).is_some() {
10530                let watcher = RenamePathsWatchedForServer::default()
10531                    .with_did_rename_patterns(did_rename_caps)
10532                    .with_will_rename_patterns(will_rename_caps);
10533                local
10534                    .language_server_paths_watched_for_rename
10535                    .insert(server_id, watcher);
10536            }
10537        }
10538
10539        self.language_server_statuses.insert(
10540            server_id,
10541            LanguageServerStatus {
10542                name: language_server.name(),
10543                pending_work: Default::default(),
10544                has_pending_diagnostic_updates: false,
10545                progress_tokens: Default::default(),
10546                worktree: Some(key.worktree_id),
10547            },
10548        );
10549
10550        cx.emit(LspStoreEvent::LanguageServerAdded(
10551            server_id,
10552            language_server.name(),
10553            Some(key.worktree_id),
10554        ));
10555        cx.emit(LspStoreEvent::RefreshInlayHints);
10556
10557        let server_capabilities = language_server.capabilities();
10558        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10559            downstream_client
10560                .send(proto::StartLanguageServer {
10561                    project_id: *project_id,
10562                    server: Some(proto::LanguageServer {
10563                        id: server_id.to_proto(),
10564                        name: language_server.name().to_string(),
10565                        worktree_id: Some(key.worktree_id.to_proto()),
10566                    }),
10567                    capabilities: serde_json::to_string(&server_capabilities)
10568                        .expect("serializing server LSP capabilities"),
10569                })
10570                .log_err();
10571        }
10572        self.lsp_server_capabilities
10573            .insert(server_id, server_capabilities);
10574
10575        // Tell the language server about every open buffer in the worktree that matches the language.
10576        // Also check for buffers in worktrees that reused this server
10577        let mut worktrees_using_server = vec![key.worktree_id];
10578        if let Some(local) = self.as_local() {
10579            // Find all worktrees that have this server in their language server tree
10580            for (worktree_id, servers) in &local.lsp_tree.instances {
10581                if *worktree_id != key.worktree_id {
10582                    for server_map in servers.roots.values() {
10583                        if server_map
10584                            .values()
10585                            .any(|(node, _)| node.id() == Some(server_id))
10586                        {
10587                            worktrees_using_server.push(*worktree_id);
10588                        }
10589                    }
10590                }
10591            }
10592        }
10593
10594        let mut buffer_paths_registered = Vec::new();
10595        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10596            let mut lsp_adapters = HashMap::default();
10597            for buffer_handle in buffer_store.buffers() {
10598                let buffer = buffer_handle.read(cx);
10599                let file = match File::from_dyn(buffer.file()) {
10600                    Some(file) => file,
10601                    None => continue,
10602                };
10603                let language = match buffer.language() {
10604                    Some(language) => language,
10605                    None => continue,
10606                };
10607
10608                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10609                    || !lsp_adapters
10610                        .entry(language.name())
10611                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
10612                        .iter()
10613                        .any(|a| a.name == key.name)
10614                {
10615                    continue;
10616                }
10617                // didOpen
10618                let file = match file.as_local() {
10619                    Some(file) => file,
10620                    None => continue,
10621                };
10622
10623                let local = self.as_local_mut().unwrap();
10624
10625                let buffer_id = buffer.remote_id();
10626                if local.registered_buffers.contains_key(&buffer_id) {
10627                    let versions = local
10628                        .buffer_snapshots
10629                        .entry(buffer_id)
10630                        .or_default()
10631                        .entry(server_id)
10632                        .and_modify(|_| {
10633                            assert!(
10634                            false,
10635                            "There should not be an existing snapshot for a newly inserted buffer"
10636                        )
10637                        })
10638                        .or_insert_with(|| {
10639                            vec![LspBufferSnapshot {
10640                                version: 0,
10641                                snapshot: buffer.text_snapshot(),
10642                            }]
10643                        });
10644
10645                    let snapshot = versions.last().unwrap();
10646                    let version = snapshot.version;
10647                    let initial_snapshot = &snapshot.snapshot;
10648                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
10649                    language_server.register_buffer(
10650                        uri,
10651                        adapter.language_id(&language.name()),
10652                        version,
10653                        initial_snapshot.text(),
10654                    );
10655                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
10656                    local
10657                        .buffers_opened_in_servers
10658                        .entry(buffer_id)
10659                        .or_default()
10660                        .insert(server_id);
10661                }
10662                buffer_handle.update(cx, |buffer, cx| {
10663                    buffer.set_completion_triggers(
10664                        server_id,
10665                        language_server
10666                            .capabilities()
10667                            .completion_provider
10668                            .as_ref()
10669                            .and_then(|provider| {
10670                                provider
10671                                    .trigger_characters
10672                                    .as_ref()
10673                                    .map(|characters| characters.iter().cloned().collect())
10674                            })
10675                            .unwrap_or_default(),
10676                        cx,
10677                    )
10678                });
10679            }
10680        });
10681
10682        for (buffer_id, abs_path) in buffer_paths_registered {
10683            cx.emit(LspStoreEvent::LanguageServerUpdate {
10684                language_server_id: server_id,
10685                name: Some(adapter.name()),
10686                message: proto::update_language_server::Variant::RegisteredForBuffer(
10687                    proto::RegisteredForBuffer {
10688                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
10689                        buffer_id: buffer_id.to_proto(),
10690                    },
10691                ),
10692            });
10693        }
10694
10695        cx.notify();
10696    }
10697
10698    pub fn language_servers_running_disk_based_diagnostics(
10699        &self,
10700    ) -> impl Iterator<Item = LanguageServerId> + '_ {
10701        self.language_server_statuses
10702            .iter()
10703            .filter_map(|(id, status)| {
10704                if status.has_pending_diagnostic_updates {
10705                    Some(*id)
10706                } else {
10707                    None
10708                }
10709            })
10710    }
10711
10712    pub(crate) fn cancel_language_server_work_for_buffers(
10713        &mut self,
10714        buffers: impl IntoIterator<Item = Entity<Buffer>>,
10715        cx: &mut Context<Self>,
10716    ) {
10717        if let Some((client, project_id)) = self.upstream_client() {
10718            let request = client.request(proto::CancelLanguageServerWork {
10719                project_id,
10720                work: Some(proto::cancel_language_server_work::Work::Buffers(
10721                    proto::cancel_language_server_work::Buffers {
10722                        buffer_ids: buffers
10723                            .into_iter()
10724                            .map(|b| b.read(cx).remote_id().to_proto())
10725                            .collect(),
10726                    },
10727                )),
10728            });
10729            cx.background_spawn(request).detach_and_log_err(cx);
10730        } else if let Some(local) = self.as_local() {
10731            let servers = buffers
10732                .into_iter()
10733                .flat_map(|buffer| {
10734                    buffer.update(cx, |buffer, cx| {
10735                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
10736                    })
10737                })
10738                .collect::<HashSet<_>>();
10739            for server_id in servers {
10740                self.cancel_language_server_work(server_id, None, cx);
10741            }
10742        }
10743    }
10744
10745    pub(crate) fn cancel_language_server_work(
10746        &mut self,
10747        server_id: LanguageServerId,
10748        token_to_cancel: Option<String>,
10749        cx: &mut Context<Self>,
10750    ) {
10751        if let Some(local) = self.as_local() {
10752            let status = self.language_server_statuses.get(&server_id);
10753            let server = local.language_servers.get(&server_id);
10754            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
10755            {
10756                for (token, progress) in &status.pending_work {
10757                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
10758                        && token != token_to_cancel
10759                    {
10760                        continue;
10761                    }
10762                    if progress.is_cancellable {
10763                        server
10764                            .notify::<lsp::notification::WorkDoneProgressCancel>(
10765                                &WorkDoneProgressCancelParams {
10766                                    token: lsp::NumberOrString::String(token.clone()),
10767                                },
10768                            )
10769                            .ok();
10770                    }
10771                }
10772            }
10773        } else if let Some((client, project_id)) = self.upstream_client() {
10774            let request = client.request(proto::CancelLanguageServerWork {
10775                project_id,
10776                work: Some(
10777                    proto::cancel_language_server_work::Work::LanguageServerWork(
10778                        proto::cancel_language_server_work::LanguageServerWork {
10779                            language_server_id: server_id.to_proto(),
10780                            token: token_to_cancel,
10781                        },
10782                    ),
10783                ),
10784            });
10785            cx.background_spawn(request).detach_and_log_err(cx);
10786        }
10787    }
10788
10789    fn register_supplementary_language_server(
10790        &mut self,
10791        id: LanguageServerId,
10792        name: LanguageServerName,
10793        server: Arc<LanguageServer>,
10794        cx: &mut Context<Self>,
10795    ) {
10796        if let Some(local) = self.as_local_mut() {
10797            local
10798                .supplementary_language_servers
10799                .insert(id, (name.clone(), server));
10800            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
10801        }
10802    }
10803
10804    fn unregister_supplementary_language_server(
10805        &mut self,
10806        id: LanguageServerId,
10807        cx: &mut Context<Self>,
10808    ) {
10809        if let Some(local) = self.as_local_mut() {
10810            local.supplementary_language_servers.remove(&id);
10811            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
10812        }
10813    }
10814
10815    pub(crate) fn supplementary_language_servers(
10816        &self,
10817    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
10818        self.as_local().into_iter().flat_map(|local| {
10819            local
10820                .supplementary_language_servers
10821                .iter()
10822                .map(|(id, (name, _))| (*id, name.clone()))
10823        })
10824    }
10825
10826    pub fn language_server_adapter_for_id(
10827        &self,
10828        id: LanguageServerId,
10829    ) -> Option<Arc<CachedLspAdapter>> {
10830        self.as_local()
10831            .and_then(|local| local.language_servers.get(&id))
10832            .and_then(|language_server_state| match language_server_state {
10833                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
10834                _ => None,
10835            })
10836    }
10837
10838    pub(super) fn update_local_worktree_language_servers(
10839        &mut self,
10840        worktree_handle: &Entity<Worktree>,
10841        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
10842        cx: &mut Context<Self>,
10843    ) {
10844        if changes.is_empty() {
10845            return;
10846        }
10847
10848        let Some(local) = self.as_local() else { return };
10849
10850        local.prettier_store.update(cx, |prettier_store, cx| {
10851            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
10852        });
10853
10854        let worktree_id = worktree_handle.read(cx).id();
10855        let mut language_server_ids = local
10856            .language_server_ids
10857            .iter()
10858            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
10859            .collect::<Vec<_>>();
10860        language_server_ids.sort();
10861        language_server_ids.dedup();
10862
10863        // let abs_path = worktree_handle.read(cx).abs_path();
10864        for server_id in &language_server_ids {
10865            if let Some(LanguageServerState::Running { server, .. }) =
10866                local.language_servers.get(server_id)
10867                && let Some(watched_paths) = local
10868                    .language_server_watched_paths
10869                    .get(server_id)
10870                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
10871            {
10872                let params = lsp::DidChangeWatchedFilesParams {
10873                    changes: changes
10874                        .iter()
10875                        .filter_map(|(path, _, change)| {
10876                            if !watched_paths.is_match(path.as_std_path()) {
10877                                return None;
10878                            }
10879                            let typ = match change {
10880                                PathChange::Loaded => return None,
10881                                PathChange::Added => lsp::FileChangeType::CREATED,
10882                                PathChange::Removed => lsp::FileChangeType::DELETED,
10883                                PathChange::Updated => lsp::FileChangeType::CHANGED,
10884                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
10885                            };
10886                            let uri = lsp::Uri::from_file_path(
10887                                worktree_handle.read(cx).absolutize(&path),
10888                            )
10889                            .ok()?;
10890                            Some(lsp::FileEvent { uri, typ })
10891                        })
10892                        .collect(),
10893                };
10894                if !params.changes.is_empty() {
10895                    server
10896                        .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
10897                        .ok();
10898                }
10899            }
10900        }
10901        for (path, _, _) in changes {
10902            if let Some(file_name) = path.file_name()
10903                && local.watched_manifest_filenames.contains(file_name)
10904            {
10905                self.request_workspace_config_refresh();
10906                break;
10907            }
10908        }
10909    }
10910
10911    pub fn wait_for_remote_buffer(
10912        &mut self,
10913        id: BufferId,
10914        cx: &mut Context<Self>,
10915    ) -> Task<Result<Entity<Buffer>>> {
10916        self.buffer_store.update(cx, |buffer_store, cx| {
10917            buffer_store.wait_for_remote_buffer(id, cx)
10918        })
10919    }
10920
10921    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
10922        let mut result = proto::Symbol {
10923            language_server_name: symbol.language_server_name.0.to_string(),
10924            source_worktree_id: symbol.source_worktree_id.to_proto(),
10925            language_server_id: symbol.source_language_server_id.to_proto(),
10926            name: symbol.name.clone(),
10927            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
10928            start: Some(proto::PointUtf16 {
10929                row: symbol.range.start.0.row,
10930                column: symbol.range.start.0.column,
10931            }),
10932            end: Some(proto::PointUtf16 {
10933                row: symbol.range.end.0.row,
10934                column: symbol.range.end.0.column,
10935            }),
10936            worktree_id: Default::default(),
10937            path: Default::default(),
10938            signature: Default::default(),
10939        };
10940        match &symbol.path {
10941            SymbolLocation::InProject(path) => {
10942                result.worktree_id = path.worktree_id.to_proto();
10943                result.path = path.path.to_proto();
10944            }
10945            SymbolLocation::OutsideProject {
10946                abs_path,
10947                signature,
10948            } => {
10949                result.path = abs_path.to_string_lossy().to_string();
10950                result.signature = signature.to_vec();
10951            }
10952        }
10953        result
10954    }
10955
10956    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
10957        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
10958        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
10959        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
10960
10961        let path = if serialized_symbol.signature.is_empty() {
10962            SymbolLocation::InProject(ProjectPath {
10963                worktree_id,
10964                path: RelPath::from_proto(&serialized_symbol.path)
10965                    .context("invalid symbol path")?,
10966            })
10967        } else {
10968            SymbolLocation::OutsideProject {
10969                abs_path: Path::new(&serialized_symbol.path).into(),
10970                signature: serialized_symbol
10971                    .signature
10972                    .try_into()
10973                    .map_err(|_| anyhow!("invalid signature"))?,
10974            }
10975        };
10976
10977        let start = serialized_symbol.start.context("invalid start")?;
10978        let end = serialized_symbol.end.context("invalid end")?;
10979        Ok(CoreSymbol {
10980            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
10981            source_worktree_id,
10982            source_language_server_id: LanguageServerId::from_proto(
10983                serialized_symbol.language_server_id,
10984            ),
10985            path,
10986            name: serialized_symbol.name,
10987            range: Unclipped(PointUtf16::new(start.row, start.column))
10988                ..Unclipped(PointUtf16::new(end.row, end.column)),
10989            kind,
10990        })
10991    }
10992
10993    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
10994        let mut serialized_completion = proto::Completion {
10995            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
10996            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
10997            new_text: completion.new_text.clone(),
10998            ..proto::Completion::default()
10999        };
11000        match &completion.source {
11001            CompletionSource::Lsp {
11002                insert_range,
11003                server_id,
11004                lsp_completion,
11005                lsp_defaults,
11006                resolved,
11007            } => {
11008                let (old_insert_start, old_insert_end) = insert_range
11009                    .as_ref()
11010                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11011                    .unzip();
11012
11013                serialized_completion.old_insert_start = old_insert_start;
11014                serialized_completion.old_insert_end = old_insert_end;
11015                serialized_completion.source = proto::completion::Source::Lsp as i32;
11016                serialized_completion.server_id = server_id.0 as u64;
11017                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11018                serialized_completion.lsp_defaults = lsp_defaults
11019                    .as_deref()
11020                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11021                serialized_completion.resolved = *resolved;
11022            }
11023            CompletionSource::BufferWord {
11024                word_range,
11025                resolved,
11026            } => {
11027                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11028                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11029                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11030                serialized_completion.resolved = *resolved;
11031            }
11032            CompletionSource::Custom => {
11033                serialized_completion.source = proto::completion::Source::Custom as i32;
11034                serialized_completion.resolved = true;
11035            }
11036            CompletionSource::Dap { sort_text } => {
11037                serialized_completion.source = proto::completion::Source::Dap as i32;
11038                serialized_completion.sort_text = Some(sort_text.clone());
11039            }
11040        }
11041
11042        serialized_completion
11043    }
11044
11045    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11046        let old_replace_start = completion
11047            .old_replace_start
11048            .and_then(deserialize_anchor)
11049            .context("invalid old start")?;
11050        let old_replace_end = completion
11051            .old_replace_end
11052            .and_then(deserialize_anchor)
11053            .context("invalid old end")?;
11054        let insert_range = {
11055            match completion.old_insert_start.zip(completion.old_insert_end) {
11056                Some((start, end)) => {
11057                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11058                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11059                    Some(start..end)
11060                }
11061                None => None,
11062            }
11063        };
11064        Ok(CoreCompletion {
11065            replace_range: old_replace_start..old_replace_end,
11066            new_text: completion.new_text,
11067            source: match proto::completion::Source::from_i32(completion.source) {
11068                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11069                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11070                    insert_range,
11071                    server_id: LanguageServerId::from_proto(completion.server_id),
11072                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11073                    lsp_defaults: completion
11074                        .lsp_defaults
11075                        .as_deref()
11076                        .map(serde_json::from_slice)
11077                        .transpose()?,
11078                    resolved: completion.resolved,
11079                },
11080                Some(proto::completion::Source::BufferWord) => {
11081                    let word_range = completion
11082                        .buffer_word_start
11083                        .and_then(deserialize_anchor)
11084                        .context("invalid buffer word start")?
11085                        ..completion
11086                            .buffer_word_end
11087                            .and_then(deserialize_anchor)
11088                            .context("invalid buffer word end")?;
11089                    CompletionSource::BufferWord {
11090                        word_range,
11091                        resolved: completion.resolved,
11092                    }
11093                }
11094                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11095                    sort_text: completion
11096                        .sort_text
11097                        .context("expected sort text to exist")?,
11098                },
11099                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11100            },
11101        })
11102    }
11103
11104    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11105        let (kind, lsp_action) = match &action.lsp_action {
11106            LspAction::Action(code_action) => (
11107                proto::code_action::Kind::Action as i32,
11108                serde_json::to_vec(code_action).unwrap(),
11109            ),
11110            LspAction::Command(command) => (
11111                proto::code_action::Kind::Command as i32,
11112                serde_json::to_vec(command).unwrap(),
11113            ),
11114            LspAction::CodeLens(code_lens) => (
11115                proto::code_action::Kind::CodeLens as i32,
11116                serde_json::to_vec(code_lens).unwrap(),
11117            ),
11118        };
11119
11120        proto::CodeAction {
11121            server_id: action.server_id.0 as u64,
11122            start: Some(serialize_anchor(&action.range.start)),
11123            end: Some(serialize_anchor(&action.range.end)),
11124            lsp_action,
11125            kind,
11126            resolved: action.resolved,
11127        }
11128    }
11129
11130    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11131        let start = action
11132            .start
11133            .and_then(deserialize_anchor)
11134            .context("invalid start")?;
11135        let end = action
11136            .end
11137            .and_then(deserialize_anchor)
11138            .context("invalid end")?;
11139        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11140            Some(proto::code_action::Kind::Action) => {
11141                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11142            }
11143            Some(proto::code_action::Kind::Command) => {
11144                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11145            }
11146            Some(proto::code_action::Kind::CodeLens) => {
11147                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11148            }
11149            None => anyhow::bail!("Unknown action kind {}", action.kind),
11150        };
11151        Ok(CodeAction {
11152            server_id: LanguageServerId(action.server_id as usize),
11153            range: start..end,
11154            resolved: action.resolved,
11155            lsp_action,
11156        })
11157    }
11158
11159    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11160        match &formatting_result {
11161            Ok(_) => self.last_formatting_failure = None,
11162            Err(error) => {
11163                let error_string = format!("{error:#}");
11164                log::error!("Formatting failed: {error_string}");
11165                self.last_formatting_failure
11166                    .replace(error_string.lines().join(" "));
11167            }
11168        }
11169    }
11170
11171    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11172        self.lsp_server_capabilities.remove(&for_server);
11173        for buffer_colors in self.lsp_document_colors.values_mut() {
11174            buffer_colors.colors.remove(&for_server);
11175            buffer_colors.cache_version += 1;
11176        }
11177        for buffer_lens in self.lsp_code_lens.values_mut() {
11178            buffer_lens.lens.remove(&for_server);
11179        }
11180        if let Some(local) = self.as_local_mut() {
11181            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11182            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11183                buffer_servers.remove(&for_server);
11184            }
11185        }
11186    }
11187
11188    pub fn result_id(
11189        &self,
11190        server_id: LanguageServerId,
11191        buffer_id: BufferId,
11192        cx: &App,
11193    ) -> Option<String> {
11194        let abs_path = self
11195            .buffer_store
11196            .read(cx)
11197            .get(buffer_id)
11198            .and_then(|b| File::from_dyn(b.read(cx).file()))
11199            .map(|f| f.abs_path(cx))?;
11200        self.as_local()?
11201            .buffer_pull_diagnostics_result_ids
11202            .get(&server_id)?
11203            .get(&abs_path)?
11204            .clone()
11205    }
11206
11207    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11208        let Some(local) = self.as_local() else {
11209            return HashMap::default();
11210        };
11211        local
11212            .buffer_pull_diagnostics_result_ids
11213            .get(&server_id)
11214            .into_iter()
11215            .flatten()
11216            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11217            .collect()
11218    }
11219
11220    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11221        if let Some(LanguageServerState::Running {
11222            workspace_refresh_task: Some(workspace_refresh_task),
11223            ..
11224        }) = self
11225            .as_local_mut()
11226            .and_then(|local| local.language_servers.get_mut(&server_id))
11227        {
11228            workspace_refresh_task.refresh_tx.try_send(()).ok();
11229        }
11230    }
11231
11232    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11233        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11234            return;
11235        };
11236        let Some(local) = self.as_local_mut() else {
11237            return;
11238        };
11239
11240        for server_id in buffer.update(cx, |buffer, cx| {
11241            local.language_server_ids_for_buffer(buffer, cx)
11242        }) {
11243            if let Some(LanguageServerState::Running {
11244                workspace_refresh_task: Some(workspace_refresh_task),
11245                ..
11246            }) = local.language_servers.get_mut(&server_id)
11247            {
11248                workspace_refresh_task.refresh_tx.try_send(()).ok();
11249            }
11250        }
11251    }
11252
11253    fn apply_workspace_diagnostic_report(
11254        &mut self,
11255        server_id: LanguageServerId,
11256        report: lsp::WorkspaceDiagnosticReportResult,
11257        cx: &mut Context<Self>,
11258    ) {
11259        let workspace_diagnostics =
11260            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11261        let mut unchanged_buffers = HashSet::default();
11262        let mut changed_buffers = HashSet::default();
11263        let workspace_diagnostics_updates = workspace_diagnostics
11264            .into_iter()
11265            .filter_map(
11266                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11267                    LspPullDiagnostics::Response {
11268                        server_id,
11269                        uri,
11270                        diagnostics,
11271                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11272                    LspPullDiagnostics::Default => None,
11273                },
11274            )
11275            .fold(
11276                HashMap::default(),
11277                |mut acc, (server_id, uri, diagnostics, version)| {
11278                    let (result_id, diagnostics) = match diagnostics {
11279                        PulledDiagnostics::Unchanged { result_id } => {
11280                            unchanged_buffers.insert(uri.clone());
11281                            (Some(result_id), Vec::new())
11282                        }
11283                        PulledDiagnostics::Changed {
11284                            result_id,
11285                            diagnostics,
11286                        } => {
11287                            changed_buffers.insert(uri.clone());
11288                            (result_id, diagnostics)
11289                        }
11290                    };
11291                    let disk_based_sources = Cow::Owned(
11292                        self.language_server_adapter_for_id(server_id)
11293                            .as_ref()
11294                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11295                            .unwrap_or(&[])
11296                            .to_vec(),
11297                    );
11298                    acc.entry(server_id)
11299                        .or_insert_with(Vec::new)
11300                        .push(DocumentDiagnosticsUpdate {
11301                            server_id,
11302                            diagnostics: lsp::PublishDiagnosticsParams {
11303                                uri,
11304                                diagnostics,
11305                                version,
11306                            },
11307                            result_id,
11308                            disk_based_sources,
11309                        });
11310                    acc
11311                },
11312            );
11313
11314        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11315            self.merge_lsp_diagnostics(
11316                DiagnosticSourceKind::Pulled,
11317                diagnostic_updates,
11318                |buffer, old_diagnostic, cx| {
11319                    File::from_dyn(buffer.file())
11320                        .and_then(|file| {
11321                            let abs_path = file.as_local()?.abs_path(cx);
11322                            lsp::Uri::from_file_path(abs_path).ok()
11323                        })
11324                        .is_none_or(|buffer_uri| {
11325                            unchanged_buffers.contains(&buffer_uri)
11326                                || match old_diagnostic.source_kind {
11327                                    DiagnosticSourceKind::Pulled => {
11328                                        !changed_buffers.contains(&buffer_uri)
11329                                    }
11330                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11331                                        true
11332                                    }
11333                                }
11334                        })
11335                },
11336                cx,
11337            )
11338            .log_err();
11339        }
11340    }
11341
11342    fn register_server_capabilities(
11343        &mut self,
11344        server_id: LanguageServerId,
11345        params: lsp::RegistrationParams,
11346        cx: &mut Context<Self>,
11347    ) -> anyhow::Result<()> {
11348        let server = self
11349            .language_server_for_id(server_id)
11350            .with_context(|| format!("no server {server_id} found"))?;
11351        for reg in params.registrations {
11352            match reg.method.as_str() {
11353                "workspace/didChangeWatchedFiles" => {
11354                    if let Some(options) = reg.register_options {
11355                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11356                            let caps = serde_json::from_value(options)?;
11357                            local_lsp_store
11358                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11359                            true
11360                        } else {
11361                            false
11362                        };
11363                        if notify {
11364                            notify_server_capabilities_updated(&server, cx);
11365                        }
11366                    }
11367                }
11368                "workspace/didChangeConfiguration" => {
11369                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11370                }
11371                "workspace/didChangeWorkspaceFolders" => {
11372                    // In this case register options is an empty object, we can ignore it
11373                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11374                        supported: Some(true),
11375                        change_notifications: Some(OneOf::Right(reg.id)),
11376                    };
11377                    server.update_capabilities(|capabilities| {
11378                        capabilities
11379                            .workspace
11380                            .get_or_insert_default()
11381                            .workspace_folders = Some(caps);
11382                    });
11383                    notify_server_capabilities_updated(&server, cx);
11384                }
11385                "workspace/symbol" => {
11386                    let options = parse_register_capabilities(reg)?;
11387                    server.update_capabilities(|capabilities| {
11388                        capabilities.workspace_symbol_provider = Some(options);
11389                    });
11390                    notify_server_capabilities_updated(&server, cx);
11391                }
11392                "workspace/fileOperations" => {
11393                    if let Some(options) = reg.register_options {
11394                        let caps = serde_json::from_value(options)?;
11395                        server.update_capabilities(|capabilities| {
11396                            capabilities
11397                                .workspace
11398                                .get_or_insert_default()
11399                                .file_operations = Some(caps);
11400                        });
11401                        notify_server_capabilities_updated(&server, cx);
11402                    }
11403                }
11404                "workspace/executeCommand" => {
11405                    if let Some(options) = reg.register_options {
11406                        let options = serde_json::from_value(options)?;
11407                        server.update_capabilities(|capabilities| {
11408                            capabilities.execute_command_provider = Some(options);
11409                        });
11410                        notify_server_capabilities_updated(&server, cx);
11411                    }
11412                }
11413                "textDocument/rangeFormatting" => {
11414                    let options = parse_register_capabilities(reg)?;
11415                    server.update_capabilities(|capabilities| {
11416                        capabilities.document_range_formatting_provider = Some(options);
11417                    });
11418                    notify_server_capabilities_updated(&server, cx);
11419                }
11420                "textDocument/onTypeFormatting" => {
11421                    if let Some(options) = reg
11422                        .register_options
11423                        .map(serde_json::from_value)
11424                        .transpose()?
11425                    {
11426                        server.update_capabilities(|capabilities| {
11427                            capabilities.document_on_type_formatting_provider = Some(options);
11428                        });
11429                        notify_server_capabilities_updated(&server, cx);
11430                    }
11431                }
11432                "textDocument/formatting" => {
11433                    let options = parse_register_capabilities(reg)?;
11434                    server.update_capabilities(|capabilities| {
11435                        capabilities.document_formatting_provider = Some(options);
11436                    });
11437                    notify_server_capabilities_updated(&server, cx);
11438                }
11439                "textDocument/rename" => {
11440                    let options = parse_register_capabilities(reg)?;
11441                    server.update_capabilities(|capabilities| {
11442                        capabilities.rename_provider = Some(options);
11443                    });
11444                    notify_server_capabilities_updated(&server, cx);
11445                }
11446                "textDocument/inlayHint" => {
11447                    let options = parse_register_capabilities(reg)?;
11448                    server.update_capabilities(|capabilities| {
11449                        capabilities.inlay_hint_provider = Some(options);
11450                    });
11451                    notify_server_capabilities_updated(&server, cx);
11452                }
11453                "textDocument/documentSymbol" => {
11454                    let options = parse_register_capabilities(reg)?;
11455                    server.update_capabilities(|capabilities| {
11456                        capabilities.document_symbol_provider = Some(options);
11457                    });
11458                    notify_server_capabilities_updated(&server, cx);
11459                }
11460                "textDocument/codeAction" => {
11461                    let options = parse_register_capabilities(reg)?;
11462                    let provider = match options {
11463                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11464                        OneOf::Right(caps) => caps,
11465                    };
11466                    server.update_capabilities(|capabilities| {
11467                        capabilities.code_action_provider = Some(provider);
11468                    });
11469                    notify_server_capabilities_updated(&server, cx);
11470                }
11471                "textDocument/definition" => {
11472                    let options = parse_register_capabilities(reg)?;
11473                    server.update_capabilities(|capabilities| {
11474                        capabilities.definition_provider = Some(options);
11475                    });
11476                    notify_server_capabilities_updated(&server, cx);
11477                }
11478                "textDocument/completion" => {
11479                    if let Some(caps) = reg
11480                        .register_options
11481                        .map(serde_json::from_value)
11482                        .transpose()?
11483                    {
11484                        server.update_capabilities(|capabilities| {
11485                            capabilities.completion_provider = Some(caps);
11486                        });
11487                        notify_server_capabilities_updated(&server, cx);
11488                    }
11489                }
11490                "textDocument/hover" => {
11491                    let options = parse_register_capabilities(reg)?;
11492                    let provider = match options {
11493                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11494                        OneOf::Right(caps) => caps,
11495                    };
11496                    server.update_capabilities(|capabilities| {
11497                        capabilities.hover_provider = Some(provider);
11498                    });
11499                    notify_server_capabilities_updated(&server, cx);
11500                }
11501                "textDocument/signatureHelp" => {
11502                    if let Some(caps) = reg
11503                        .register_options
11504                        .map(serde_json::from_value)
11505                        .transpose()?
11506                    {
11507                        server.update_capabilities(|capabilities| {
11508                            capabilities.signature_help_provider = Some(caps);
11509                        });
11510                        notify_server_capabilities_updated(&server, cx);
11511                    }
11512                }
11513                "textDocument/didChange" => {
11514                    if let Some(sync_kind) = reg
11515                        .register_options
11516                        .and_then(|opts| opts.get("syncKind").cloned())
11517                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11518                        .transpose()?
11519                    {
11520                        server.update_capabilities(|capabilities| {
11521                            let mut sync_options =
11522                                Self::take_text_document_sync_options(capabilities);
11523                            sync_options.change = Some(sync_kind);
11524                            capabilities.text_document_sync =
11525                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11526                        });
11527                        notify_server_capabilities_updated(&server, cx);
11528                    }
11529                }
11530                "textDocument/didSave" => {
11531                    if let Some(include_text) = reg
11532                        .register_options
11533                        .map(|opts| {
11534                            let transpose = opts
11535                                .get("includeText")
11536                                .cloned()
11537                                .map(serde_json::from_value::<Option<bool>>)
11538                                .transpose();
11539                            match transpose {
11540                                Ok(value) => Ok(value.flatten()),
11541                                Err(e) => Err(e),
11542                            }
11543                        })
11544                        .transpose()?
11545                    {
11546                        server.update_capabilities(|capabilities| {
11547                            let mut sync_options =
11548                                Self::take_text_document_sync_options(capabilities);
11549                            sync_options.save =
11550                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11551                                    include_text,
11552                                }));
11553                            capabilities.text_document_sync =
11554                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11555                        });
11556                        notify_server_capabilities_updated(&server, cx);
11557                    }
11558                }
11559                "textDocument/codeLens" => {
11560                    if let Some(caps) = reg
11561                        .register_options
11562                        .map(serde_json::from_value)
11563                        .transpose()?
11564                    {
11565                        server.update_capabilities(|capabilities| {
11566                            capabilities.code_lens_provider = Some(caps);
11567                        });
11568                        notify_server_capabilities_updated(&server, cx);
11569                    }
11570                }
11571                "textDocument/diagnostic" => {
11572                    if let Some(caps) = reg
11573                        .register_options
11574                        .map(serde_json::from_value)
11575                        .transpose()?
11576                    {
11577                        server.update_capabilities(|capabilities| {
11578                            capabilities.diagnostic_provider = Some(caps);
11579                        });
11580                        notify_server_capabilities_updated(&server, cx);
11581                    }
11582                }
11583                "textDocument/documentColor" => {
11584                    let options = parse_register_capabilities(reg)?;
11585                    let provider = match options {
11586                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
11587                        OneOf::Right(caps) => caps,
11588                    };
11589                    server.update_capabilities(|capabilities| {
11590                        capabilities.color_provider = Some(provider);
11591                    });
11592                    notify_server_capabilities_updated(&server, cx);
11593                }
11594                _ => log::warn!("unhandled capability registration: {reg:?}"),
11595            }
11596        }
11597
11598        Ok(())
11599    }
11600
11601    fn unregister_server_capabilities(
11602        &mut self,
11603        server_id: LanguageServerId,
11604        params: lsp::UnregistrationParams,
11605        cx: &mut Context<Self>,
11606    ) -> anyhow::Result<()> {
11607        let server = self
11608            .language_server_for_id(server_id)
11609            .with_context(|| format!("no server {server_id} found"))?;
11610        for unreg in params.unregisterations.iter() {
11611            match unreg.method.as_str() {
11612                "workspace/didChangeWatchedFiles" => {
11613                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11614                        local_lsp_store
11615                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11616                        true
11617                    } else {
11618                        false
11619                    };
11620                    if notify {
11621                        notify_server_capabilities_updated(&server, cx);
11622                    }
11623                }
11624                "workspace/didChangeConfiguration" => {
11625                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11626                }
11627                "workspace/didChangeWorkspaceFolders" => {
11628                    server.update_capabilities(|capabilities| {
11629                        capabilities
11630                            .workspace
11631                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11632                                workspace_folders: None,
11633                                file_operations: None,
11634                            })
11635                            .workspace_folders = None;
11636                    });
11637                    notify_server_capabilities_updated(&server, cx);
11638                }
11639                "workspace/symbol" => {
11640                    server.update_capabilities(|capabilities| {
11641                        capabilities.workspace_symbol_provider = None
11642                    });
11643                    notify_server_capabilities_updated(&server, cx);
11644                }
11645                "workspace/fileOperations" => {
11646                    server.update_capabilities(|capabilities| {
11647                        capabilities
11648                            .workspace
11649                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11650                                workspace_folders: None,
11651                                file_operations: None,
11652                            })
11653                            .file_operations = None;
11654                    });
11655                    notify_server_capabilities_updated(&server, cx);
11656                }
11657                "workspace/executeCommand" => {
11658                    server.update_capabilities(|capabilities| {
11659                        capabilities.execute_command_provider = None;
11660                    });
11661                    notify_server_capabilities_updated(&server, cx);
11662                }
11663                "textDocument/rangeFormatting" => {
11664                    server.update_capabilities(|capabilities| {
11665                        capabilities.document_range_formatting_provider = None
11666                    });
11667                    notify_server_capabilities_updated(&server, cx);
11668                }
11669                "textDocument/onTypeFormatting" => {
11670                    server.update_capabilities(|capabilities| {
11671                        capabilities.document_on_type_formatting_provider = None;
11672                    });
11673                    notify_server_capabilities_updated(&server, cx);
11674                }
11675                "textDocument/formatting" => {
11676                    server.update_capabilities(|capabilities| {
11677                        capabilities.document_formatting_provider = None;
11678                    });
11679                    notify_server_capabilities_updated(&server, cx);
11680                }
11681                "textDocument/rename" => {
11682                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
11683                    notify_server_capabilities_updated(&server, cx);
11684                }
11685                "textDocument/codeAction" => {
11686                    server.update_capabilities(|capabilities| {
11687                        capabilities.code_action_provider = None;
11688                    });
11689                    notify_server_capabilities_updated(&server, cx);
11690                }
11691                "textDocument/definition" => {
11692                    server.update_capabilities(|capabilities| {
11693                        capabilities.definition_provider = None;
11694                    });
11695                    notify_server_capabilities_updated(&server, cx);
11696                }
11697                "textDocument/completion" => {
11698                    server.update_capabilities(|capabilities| {
11699                        capabilities.completion_provider = None;
11700                    });
11701                    notify_server_capabilities_updated(&server, cx);
11702                }
11703                "textDocument/hover" => {
11704                    server.update_capabilities(|capabilities| {
11705                        capabilities.hover_provider = None;
11706                    });
11707                    notify_server_capabilities_updated(&server, cx);
11708                }
11709                "textDocument/signatureHelp" => {
11710                    server.update_capabilities(|capabilities| {
11711                        capabilities.signature_help_provider = None;
11712                    });
11713                    notify_server_capabilities_updated(&server, cx);
11714                }
11715                "textDocument/didChange" => {
11716                    server.update_capabilities(|capabilities| {
11717                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11718                        sync_options.change = None;
11719                        capabilities.text_document_sync =
11720                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11721                    });
11722                    notify_server_capabilities_updated(&server, cx);
11723                }
11724                "textDocument/didSave" => {
11725                    server.update_capabilities(|capabilities| {
11726                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11727                        sync_options.save = None;
11728                        capabilities.text_document_sync =
11729                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11730                    });
11731                    notify_server_capabilities_updated(&server, cx);
11732                }
11733                "textDocument/codeLens" => {
11734                    server.update_capabilities(|capabilities| {
11735                        capabilities.code_lens_provider = None;
11736                    });
11737                    notify_server_capabilities_updated(&server, cx);
11738                }
11739                "textDocument/diagnostic" => {
11740                    server.update_capabilities(|capabilities| {
11741                        capabilities.diagnostic_provider = None;
11742                    });
11743                    notify_server_capabilities_updated(&server, cx);
11744                }
11745                "textDocument/documentColor" => {
11746                    server.update_capabilities(|capabilities| {
11747                        capabilities.color_provider = None;
11748                    });
11749                    notify_server_capabilities_updated(&server, cx);
11750                }
11751                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
11752            }
11753        }
11754
11755        Ok(())
11756    }
11757
11758    async fn query_lsp_locally<T>(
11759        lsp_store: Entity<Self>,
11760        sender_id: proto::PeerId,
11761        lsp_request_id: LspRequestId,
11762        proto_request: T::ProtoRequest,
11763        position: Option<Anchor>,
11764        mut cx: AsyncApp,
11765    ) -> Result<()>
11766    where
11767        T: LspCommand + Clone,
11768        T::ProtoRequest: proto::LspRequestMessage,
11769        <T::ProtoRequest as proto::RequestMessage>::Response:
11770            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
11771    {
11772        let buffer_id = BufferId::new(proto_request.buffer_id())?;
11773        let version = deserialize_version(proto_request.buffer_version());
11774        let buffer = lsp_store.update(&mut cx, |this, cx| {
11775            this.buffer_store.read(cx).get_existing(buffer_id)
11776        })??;
11777        buffer
11778            .update(&mut cx, |buffer, _| {
11779                buffer.wait_for_version(version.clone())
11780            })?
11781            .await?;
11782        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
11783        let request =
11784            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
11785        lsp_store.update(&mut cx, |lsp_store, cx| {
11786            let request_task =
11787                lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx);
11788            let existing_queries = lsp_store
11789                .running_lsp_requests
11790                .entry(TypeId::of::<T>())
11791                .or_default();
11792            if T::ProtoRequest::stop_previous_requests()
11793                || buffer_version.changed_since(&existing_queries.0)
11794            {
11795                existing_queries.1.clear();
11796            }
11797            existing_queries.1.insert(
11798                lsp_request_id,
11799                cx.spawn(async move |lsp_store, cx| {
11800                    let response = request_task.await;
11801                    lsp_store
11802                        .update(cx, |lsp_store, cx| {
11803                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
11804                            {
11805                                let response = response
11806                                    .into_iter()
11807                                    .map(|(server_id, response)| {
11808                                        (
11809                                            server_id.to_proto(),
11810                                            T::response_to_proto(
11811                                                response,
11812                                                lsp_store,
11813                                                sender_id,
11814                                                &buffer_version,
11815                                                cx,
11816                                            )
11817                                            .into(),
11818                                        )
11819                                    })
11820                                    .collect::<HashMap<_, _>>();
11821                                match client.send_lsp_response::<T::ProtoRequest>(
11822                                    project_id,
11823                                    lsp_request_id,
11824                                    response,
11825                                ) {
11826                                    Ok(()) => {}
11827                                    Err(e) => {
11828                                        log::error!("Failed to send LSP response: {e:#}",)
11829                                    }
11830                                }
11831                            }
11832                        })
11833                        .ok();
11834                }),
11835            );
11836        })?;
11837        Ok(())
11838    }
11839
11840    fn take_text_document_sync_options(
11841        capabilities: &mut lsp::ServerCapabilities,
11842    ) -> lsp::TextDocumentSyncOptions {
11843        match capabilities.text_document_sync.take() {
11844            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
11845            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
11846                let mut sync_options = lsp::TextDocumentSyncOptions::default();
11847                sync_options.change = Some(sync_kind);
11848                sync_options
11849            }
11850            None => lsp::TextDocumentSyncOptions::default(),
11851        }
11852    }
11853
11854    #[cfg(any(test, feature = "test-support"))]
11855    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
11856        let data = self.lsp_code_lens.get_mut(&buffer_id)?;
11857        Some(data.update.take()?.1)
11858    }
11859
11860    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
11861        self.downstream_client.clone()
11862    }
11863
11864    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
11865        self.worktree_store.clone()
11866    }
11867}
11868
11869// Registration with registerOptions as null, should fallback to true.
11870// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
11871fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
11872    reg: lsp::Registration,
11873) -> Result<OneOf<bool, T>> {
11874    Ok(match reg.register_options {
11875        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
11876        None => OneOf::Left(true),
11877    })
11878}
11879
11880fn subscribe_to_binary_statuses(
11881    languages: &Arc<LanguageRegistry>,
11882    cx: &mut Context<'_, LspStore>,
11883) -> Task<()> {
11884    let mut server_statuses = languages.language_server_binary_statuses();
11885    cx.spawn(async move |lsp_store, cx| {
11886        while let Some((server_name, binary_status)) = server_statuses.next().await {
11887            if lsp_store
11888                .update(cx, |_, cx| {
11889                    let mut message = None;
11890                    let binary_status = match binary_status {
11891                        BinaryStatus::None => proto::ServerBinaryStatus::None,
11892                        BinaryStatus::CheckingForUpdate => {
11893                            proto::ServerBinaryStatus::CheckingForUpdate
11894                        }
11895                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
11896                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
11897                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
11898                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
11899                        BinaryStatus::Failed { error } => {
11900                            message = Some(error);
11901                            proto::ServerBinaryStatus::Failed
11902                        }
11903                    };
11904                    cx.emit(LspStoreEvent::LanguageServerUpdate {
11905                        // Binary updates are about the binary that might not have any language server id at that point.
11906                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
11907                        language_server_id: LanguageServerId(0),
11908                        name: Some(server_name),
11909                        message: proto::update_language_server::Variant::StatusUpdate(
11910                            proto::StatusUpdate {
11911                                message,
11912                                status: Some(proto::status_update::Status::Binary(
11913                                    binary_status as i32,
11914                                )),
11915                            },
11916                        ),
11917                    });
11918                })
11919                .is_err()
11920            {
11921                break;
11922            }
11923        }
11924    })
11925}
11926
11927fn lsp_workspace_diagnostics_refresh(
11928    server: Arc<LanguageServer>,
11929    cx: &mut Context<'_, LspStore>,
11930) -> Option<WorkspaceRefreshTask> {
11931    let identifier = match server.capabilities().diagnostic_provider? {
11932        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
11933            if !diagnostic_options.workspace_diagnostics {
11934                return None;
11935            }
11936            diagnostic_options.identifier
11937        }
11938        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
11939            let diagnostic_options = registration_options.diagnostic_options;
11940            if !diagnostic_options.workspace_diagnostics {
11941                return None;
11942            }
11943            diagnostic_options.identifier
11944        }
11945    };
11946
11947    let (progress_tx, mut progress_rx) = mpsc::channel(1);
11948    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
11949    refresh_tx.try_send(()).ok();
11950
11951    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
11952        let mut attempts = 0;
11953        let max_attempts = 50;
11954        let mut requests = 0;
11955
11956        loop {
11957            let Some(()) = refresh_rx.recv().await else {
11958                return;
11959            };
11960
11961            'request: loop {
11962                requests += 1;
11963                if attempts > max_attempts {
11964                    log::error!(
11965                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
11966                    );
11967                    return;
11968                }
11969                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
11970                cx.background_executor()
11971                    .timer(Duration::from_millis(backoff_millis))
11972                    .await;
11973                attempts += 1;
11974
11975                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
11976                    lsp_store
11977                        .all_result_ids(server.server_id())
11978                        .into_iter()
11979                        .filter_map(|(abs_path, result_id)| {
11980                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
11981                            Some(lsp::PreviousResultId {
11982                                uri,
11983                                value: result_id,
11984                            })
11985                        })
11986                        .collect()
11987                }) else {
11988                    return;
11989                };
11990
11991                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
11992
11993                progress_rx.try_recv().ok();
11994                let timer =
11995                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
11996                let progress = pin!(progress_rx.recv().fuse());
11997                let response_result = server
11998                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
11999                        lsp::WorkspaceDiagnosticParams {
12000                            previous_result_ids,
12001                            identifier: identifier.clone(),
12002                            work_done_progress_params: Default::default(),
12003                            partial_result_params: lsp::PartialResultParams {
12004                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12005                            },
12006                        },
12007                        select(timer, progress).then(|either| match either {
12008                            Either::Left((message, ..)) => ready(message).left_future(),
12009                            Either::Right(..) => pending::<String>().right_future(),
12010                        }),
12011                    )
12012                    .await;
12013
12014                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12015                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12016                match response_result {
12017                    ConnectionResult::Timeout => {
12018                        log::error!("Timeout during workspace diagnostics pull");
12019                        continue 'request;
12020                    }
12021                    ConnectionResult::ConnectionReset => {
12022                        log::error!("Server closed a workspace diagnostics pull request");
12023                        continue 'request;
12024                    }
12025                    ConnectionResult::Result(Err(e)) => {
12026                        log::error!("Error during workspace diagnostics pull: {e:#}");
12027                        break 'request;
12028                    }
12029                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12030                        attempts = 0;
12031                        if lsp_store
12032                            .update(cx, |lsp_store, cx| {
12033                                lsp_store.apply_workspace_diagnostic_report(
12034                                    server.server_id(),
12035                                    pulled_diagnostics,
12036                                    cx,
12037                                )
12038                            })
12039                            .is_err()
12040                        {
12041                            return;
12042                        }
12043                        break 'request;
12044                    }
12045                }
12046            }
12047        }
12048    });
12049
12050    Some(WorkspaceRefreshTask {
12051        refresh_tx,
12052        progress_tx,
12053        task: workspace_query_language_server,
12054    })
12055}
12056
12057fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12058    let CompletionSource::BufferWord {
12059        word_range,
12060        resolved,
12061    } = &mut completion.source
12062    else {
12063        return;
12064    };
12065    if *resolved {
12066        return;
12067    }
12068
12069    if completion.new_text
12070        != snapshot
12071            .text_for_range(word_range.clone())
12072            .collect::<String>()
12073    {
12074        return;
12075    }
12076
12077    let mut offset = 0;
12078    for chunk in snapshot.chunks(word_range.clone(), true) {
12079        let end_offset = offset + chunk.text.len();
12080        if let Some(highlight_id) = chunk.syntax_highlight_id {
12081            completion
12082                .label
12083                .runs
12084                .push((offset..end_offset, highlight_id));
12085        }
12086        offset = end_offset;
12087    }
12088    *resolved = true;
12089}
12090
12091impl EventEmitter<LspStoreEvent> for LspStore {}
12092
12093fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12094    hover
12095        .contents
12096        .retain(|hover_block| !hover_block.text.trim().is_empty());
12097    if hover.contents.is_empty() {
12098        None
12099    } else {
12100        Some(hover)
12101    }
12102}
12103
12104async fn populate_labels_for_completions(
12105    new_completions: Vec<CoreCompletion>,
12106    language: Option<Arc<Language>>,
12107    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12108) -> Vec<Completion> {
12109    let lsp_completions = new_completions
12110        .iter()
12111        .filter_map(|new_completion| {
12112            new_completion
12113                .source
12114                .lsp_completion(true)
12115                .map(|lsp_completion| lsp_completion.into_owned())
12116        })
12117        .collect::<Vec<_>>();
12118
12119    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12120        lsp_adapter
12121            .labels_for_completions(&lsp_completions, language)
12122            .await
12123            .log_err()
12124            .unwrap_or_default()
12125    } else {
12126        Vec::new()
12127    }
12128    .into_iter()
12129    .fuse();
12130
12131    let mut completions = Vec::new();
12132    for completion in new_completions {
12133        match completion.source.lsp_completion(true) {
12134            Some(lsp_completion) => {
12135                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12136
12137                let mut label = labels.next().flatten().unwrap_or_else(|| {
12138                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12139                });
12140                ensure_uniform_list_compatible_label(&mut label);
12141                completions.push(Completion {
12142                    label,
12143                    documentation,
12144                    replace_range: completion.replace_range,
12145                    new_text: completion.new_text,
12146                    insert_text_mode: lsp_completion.insert_text_mode,
12147                    source: completion.source,
12148                    icon_path: None,
12149                    confirm: None,
12150                });
12151            }
12152            None => {
12153                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12154                ensure_uniform_list_compatible_label(&mut label);
12155                completions.push(Completion {
12156                    label,
12157                    documentation: None,
12158                    replace_range: completion.replace_range,
12159                    new_text: completion.new_text,
12160                    source: completion.source,
12161                    insert_text_mode: None,
12162                    icon_path: None,
12163                    confirm: None,
12164                });
12165            }
12166        }
12167    }
12168    completions
12169}
12170
12171#[derive(Debug)]
12172pub enum LanguageServerToQuery {
12173    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12174    FirstCapable,
12175    /// Query a specific language server.
12176    Other(LanguageServerId),
12177}
12178
12179#[derive(Default)]
12180struct RenamePathsWatchedForServer {
12181    did_rename: Vec<RenameActionPredicate>,
12182    will_rename: Vec<RenameActionPredicate>,
12183}
12184
12185impl RenamePathsWatchedForServer {
12186    fn with_did_rename_patterns(
12187        mut self,
12188        did_rename: Option<&FileOperationRegistrationOptions>,
12189    ) -> Self {
12190        if let Some(did_rename) = did_rename {
12191            self.did_rename = did_rename
12192                .filters
12193                .iter()
12194                .filter_map(|filter| filter.try_into().log_err())
12195                .collect();
12196        }
12197        self
12198    }
12199    fn with_will_rename_patterns(
12200        mut self,
12201        will_rename: Option<&FileOperationRegistrationOptions>,
12202    ) -> Self {
12203        if let Some(will_rename) = will_rename {
12204            self.will_rename = will_rename
12205                .filters
12206                .iter()
12207                .filter_map(|filter| filter.try_into().log_err())
12208                .collect();
12209        }
12210        self
12211    }
12212
12213    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12214        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12215    }
12216    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12217        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12218    }
12219}
12220
12221impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12222    type Error = globset::Error;
12223    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12224        Ok(Self {
12225            kind: ops.pattern.matches.clone(),
12226            glob: GlobBuilder::new(&ops.pattern.glob)
12227                .case_insensitive(
12228                    ops.pattern
12229                        .options
12230                        .as_ref()
12231                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12232                )
12233                .build()?
12234                .compile_matcher(),
12235        })
12236    }
12237}
12238struct RenameActionPredicate {
12239    glob: GlobMatcher,
12240    kind: Option<FileOperationPatternKind>,
12241}
12242
12243impl RenameActionPredicate {
12244    // Returns true if language server should be notified
12245    fn eval(&self, path: &str, is_dir: bool) -> bool {
12246        self.kind.as_ref().is_none_or(|kind| {
12247            let expected_kind = if is_dir {
12248                FileOperationPatternKind::Folder
12249            } else {
12250                FileOperationPatternKind::File
12251            };
12252            kind == &expected_kind
12253        }) && self.glob.is_match(path)
12254    }
12255}
12256
12257#[derive(Default)]
12258struct LanguageServerWatchedPaths {
12259    worktree_paths: HashMap<WorktreeId, GlobSet>,
12260    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12261}
12262
12263#[derive(Default)]
12264struct LanguageServerWatchedPathsBuilder {
12265    worktree_paths: HashMap<WorktreeId, GlobSet>,
12266    abs_paths: HashMap<Arc<Path>, GlobSet>,
12267}
12268
12269impl LanguageServerWatchedPathsBuilder {
12270    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12271        self.worktree_paths.insert(worktree_id, glob_set);
12272    }
12273    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12274        self.abs_paths.insert(path, glob_set);
12275    }
12276    fn build(
12277        self,
12278        fs: Arc<dyn Fs>,
12279        language_server_id: LanguageServerId,
12280        cx: &mut Context<LspStore>,
12281    ) -> LanguageServerWatchedPaths {
12282        let project = cx.weak_entity();
12283
12284        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12285        let abs_paths = self
12286            .abs_paths
12287            .into_iter()
12288            .map(|(abs_path, globset)| {
12289                let task = cx.spawn({
12290                    let abs_path = abs_path.clone();
12291                    let fs = fs.clone();
12292
12293                    let lsp_store = project.clone();
12294                    async move |_, cx| {
12295                        maybe!(async move {
12296                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12297                            while let Some(update) = push_updates.0.next().await {
12298                                let action = lsp_store
12299                                    .update(cx, |this, _| {
12300                                        let Some(local) = this.as_local() else {
12301                                            return ControlFlow::Break(());
12302                                        };
12303                                        let Some(watcher) = local
12304                                            .language_server_watched_paths
12305                                            .get(&language_server_id)
12306                                        else {
12307                                            return ControlFlow::Break(());
12308                                        };
12309                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12310                                            "Watched abs path is not registered with a watcher",
12311                                        );
12312                                        let matching_entries = update
12313                                            .into_iter()
12314                                            .filter(|event| globs.is_match(&event.path))
12315                                            .collect::<Vec<_>>();
12316                                        this.lsp_notify_abs_paths_changed(
12317                                            language_server_id,
12318                                            matching_entries,
12319                                        );
12320                                        ControlFlow::Continue(())
12321                                    })
12322                                    .ok()?;
12323
12324                                if action.is_break() {
12325                                    break;
12326                                }
12327                            }
12328                            Some(())
12329                        })
12330                        .await;
12331                    }
12332                });
12333                (abs_path, (globset, task))
12334            })
12335            .collect();
12336        LanguageServerWatchedPaths {
12337            worktree_paths: self.worktree_paths,
12338            abs_paths,
12339        }
12340    }
12341}
12342
12343struct LspBufferSnapshot {
12344    version: i32,
12345    snapshot: TextBufferSnapshot,
12346}
12347
12348/// A prompt requested by LSP server.
12349#[derive(Clone, Debug)]
12350pub struct LanguageServerPromptRequest {
12351    pub level: PromptLevel,
12352    pub message: String,
12353    pub actions: Vec<MessageActionItem>,
12354    pub lsp_name: String,
12355    pub(crate) response_channel: Sender<MessageActionItem>,
12356}
12357
12358impl LanguageServerPromptRequest {
12359    pub async fn respond(self, index: usize) -> Option<()> {
12360        if let Some(response) = self.actions.into_iter().nth(index) {
12361            self.response_channel.send(response).await.ok()
12362        } else {
12363            None
12364        }
12365    }
12366}
12367impl PartialEq for LanguageServerPromptRequest {
12368    fn eq(&self, other: &Self) -> bool {
12369        self.message == other.message && self.actions == other.actions
12370    }
12371}
12372
12373#[derive(Clone, Debug, PartialEq)]
12374pub enum LanguageServerLogType {
12375    Log(MessageType),
12376    Trace { verbose_info: Option<String> },
12377    Rpc { received: bool },
12378}
12379
12380impl LanguageServerLogType {
12381    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12382        match self {
12383            Self::Log(log_type) => {
12384                use proto::log_message::LogLevel;
12385                let level = match *log_type {
12386                    MessageType::ERROR => LogLevel::Error,
12387                    MessageType::WARNING => LogLevel::Warning,
12388                    MessageType::INFO => LogLevel::Info,
12389                    MessageType::LOG => LogLevel::Log,
12390                    other => {
12391                        log::warn!("Unknown lsp log message type: {other:?}");
12392                        LogLevel::Log
12393                    }
12394                };
12395                proto::language_server_log::LogType::Log(proto::LogMessage {
12396                    level: level as i32,
12397                })
12398            }
12399            Self::Trace { verbose_info } => {
12400                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12401                    verbose_info: verbose_info.to_owned(),
12402                })
12403            }
12404            Self::Rpc { received } => {
12405                let kind = if *received {
12406                    proto::rpc_message::Kind::Received
12407                } else {
12408                    proto::rpc_message::Kind::Sent
12409                };
12410                let kind = kind as i32;
12411                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12412            }
12413        }
12414    }
12415
12416    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12417        use proto::log_message::LogLevel;
12418        use proto::rpc_message;
12419        match log_type {
12420            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12421                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12422                    LogLevel::Error => MessageType::ERROR,
12423                    LogLevel::Warning => MessageType::WARNING,
12424                    LogLevel::Info => MessageType::INFO,
12425                    LogLevel::Log => MessageType::LOG,
12426                },
12427            ),
12428            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12429                verbose_info: trace_message.verbose_info,
12430            },
12431            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12432                received: match rpc_message::Kind::from_i32(message.kind)
12433                    .unwrap_or(rpc_message::Kind::Received)
12434                {
12435                    rpc_message::Kind::Received => true,
12436                    rpc_message::Kind::Sent => false,
12437                },
12438            },
12439        }
12440    }
12441}
12442
12443pub struct WorkspaceRefreshTask {
12444    refresh_tx: mpsc::Sender<()>,
12445    progress_tx: mpsc::Sender<()>,
12446    #[allow(dead_code)]
12447    task: Task<()>,
12448}
12449
12450pub enum LanguageServerState {
12451    Starting {
12452        startup: Task<Option<Arc<LanguageServer>>>,
12453        /// List of language servers that will be added to the workspace once it's initialization completes.
12454        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
12455    },
12456
12457    Running {
12458        adapter: Arc<CachedLspAdapter>,
12459        server: Arc<LanguageServer>,
12460        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12461        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12462    },
12463}
12464
12465impl LanguageServerState {
12466    fn add_workspace_folder(&self, uri: Uri) {
12467        match self {
12468            LanguageServerState::Starting {
12469                pending_workspace_folders,
12470                ..
12471            } => {
12472                pending_workspace_folders.lock().insert(uri);
12473            }
12474            LanguageServerState::Running { server, .. } => {
12475                server.add_workspace_folder(uri);
12476            }
12477        }
12478    }
12479    fn _remove_workspace_folder(&self, uri: Uri) {
12480        match self {
12481            LanguageServerState::Starting {
12482                pending_workspace_folders,
12483                ..
12484            } => {
12485                pending_workspace_folders.lock().remove(&uri);
12486            }
12487            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12488        }
12489    }
12490}
12491
12492impl std::fmt::Debug for LanguageServerState {
12493    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12494        match self {
12495            LanguageServerState::Starting { .. } => {
12496                f.debug_struct("LanguageServerState::Starting").finish()
12497            }
12498            LanguageServerState::Running { .. } => {
12499                f.debug_struct("LanguageServerState::Running").finish()
12500            }
12501        }
12502    }
12503}
12504
12505#[derive(Clone, Debug, Serialize)]
12506pub struct LanguageServerProgress {
12507    pub is_disk_based_diagnostics_progress: bool,
12508    pub is_cancellable: bool,
12509    pub title: Option<String>,
12510    pub message: Option<String>,
12511    pub percentage: Option<usize>,
12512    #[serde(skip_serializing)]
12513    pub last_update_at: Instant,
12514}
12515
12516#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12517pub struct DiagnosticSummary {
12518    pub error_count: usize,
12519    pub warning_count: usize,
12520}
12521
12522impl DiagnosticSummary {
12523    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12524        let mut this = Self {
12525            error_count: 0,
12526            warning_count: 0,
12527        };
12528
12529        for entry in diagnostics {
12530            if entry.diagnostic.is_primary {
12531                match entry.diagnostic.severity {
12532                    DiagnosticSeverity::ERROR => this.error_count += 1,
12533                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12534                    _ => {}
12535                }
12536            }
12537        }
12538
12539        this
12540    }
12541
12542    pub fn is_empty(&self) -> bool {
12543        self.error_count == 0 && self.warning_count == 0
12544    }
12545
12546    pub fn to_proto(
12547        self,
12548        language_server_id: LanguageServerId,
12549        path: &RelPath,
12550    ) -> proto::DiagnosticSummary {
12551        proto::DiagnosticSummary {
12552            path: path.to_proto(),
12553            language_server_id: language_server_id.0 as u64,
12554            error_count: self.error_count as u32,
12555            warning_count: self.warning_count as u32,
12556        }
12557    }
12558}
12559
12560#[derive(Clone, Debug)]
12561pub enum CompletionDocumentation {
12562    /// There is no documentation for this completion.
12563    Undocumented,
12564    /// A single line of documentation.
12565    SingleLine(SharedString),
12566    /// Multiple lines of plain text documentation.
12567    MultiLinePlainText(SharedString),
12568    /// Markdown documentation.
12569    MultiLineMarkdown(SharedString),
12570    /// Both single line and multiple lines of plain text documentation.
12571    SingleLineAndMultiLinePlainText {
12572        single_line: SharedString,
12573        plain_text: Option<SharedString>,
12574    },
12575}
12576
12577impl CompletionDocumentation {
12578    #[cfg(any(test, feature = "test-support"))]
12579    pub fn text(&self) -> SharedString {
12580        match self {
12581            CompletionDocumentation::Undocumented => "".into(),
12582            CompletionDocumentation::SingleLine(s) => s.clone(),
12583            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
12584            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
12585            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
12586                single_line.clone()
12587            }
12588        }
12589    }
12590}
12591
12592impl From<lsp::Documentation> for CompletionDocumentation {
12593    fn from(docs: lsp::Documentation) -> Self {
12594        match docs {
12595            lsp::Documentation::String(text) => {
12596                if text.lines().count() <= 1 {
12597                    CompletionDocumentation::SingleLine(text.into())
12598                } else {
12599                    CompletionDocumentation::MultiLinePlainText(text.into())
12600                }
12601            }
12602
12603            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
12604                lsp::MarkupKind::PlainText => {
12605                    if value.lines().count() <= 1 {
12606                        CompletionDocumentation::SingleLine(value.into())
12607                    } else {
12608                        CompletionDocumentation::MultiLinePlainText(value.into())
12609                    }
12610                }
12611
12612                lsp::MarkupKind::Markdown => {
12613                    CompletionDocumentation::MultiLineMarkdown(value.into())
12614                }
12615            },
12616        }
12617    }
12618}
12619
12620fn glob_literal_prefix(glob: &Path) -> PathBuf {
12621    glob.components()
12622        .take_while(|component| match component {
12623            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
12624            _ => true,
12625        })
12626        .collect()
12627}
12628
12629pub struct SshLspAdapter {
12630    name: LanguageServerName,
12631    binary: LanguageServerBinary,
12632    initialization_options: Option<String>,
12633    code_action_kinds: Option<Vec<CodeActionKind>>,
12634}
12635
12636impl SshLspAdapter {
12637    pub fn new(
12638        name: LanguageServerName,
12639        binary: LanguageServerBinary,
12640        initialization_options: Option<String>,
12641        code_action_kinds: Option<String>,
12642    ) -> Self {
12643        Self {
12644            name,
12645            binary,
12646            initialization_options,
12647            code_action_kinds: code_action_kinds
12648                .as_ref()
12649                .and_then(|c| serde_json::from_str(c).ok()),
12650        }
12651    }
12652}
12653
12654impl LspInstaller for SshLspAdapter {
12655    type BinaryVersion = ();
12656    async fn check_if_user_installed(
12657        &self,
12658        _: &dyn LspAdapterDelegate,
12659        _: Option<Toolchain>,
12660        _: &AsyncApp,
12661    ) -> Option<LanguageServerBinary> {
12662        Some(self.binary.clone())
12663    }
12664
12665    async fn cached_server_binary(
12666        &self,
12667        _: PathBuf,
12668        _: &dyn LspAdapterDelegate,
12669    ) -> Option<LanguageServerBinary> {
12670        None
12671    }
12672
12673    async fn fetch_latest_server_version(
12674        &self,
12675        _: &dyn LspAdapterDelegate,
12676        _: bool,
12677        _: &mut AsyncApp,
12678    ) -> Result<()> {
12679        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
12680    }
12681
12682    async fn fetch_server_binary(
12683        &self,
12684        _: (),
12685        _: PathBuf,
12686        _: &dyn LspAdapterDelegate,
12687    ) -> Result<LanguageServerBinary> {
12688        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
12689    }
12690}
12691
12692#[async_trait(?Send)]
12693impl LspAdapter for SshLspAdapter {
12694    fn name(&self) -> LanguageServerName {
12695        self.name.clone()
12696    }
12697
12698    async fn initialization_options(
12699        self: Arc<Self>,
12700        _: &Arc<dyn LspAdapterDelegate>,
12701    ) -> Result<Option<serde_json::Value>> {
12702        let Some(options) = &self.initialization_options else {
12703            return Ok(None);
12704        };
12705        let result = serde_json::from_str(options)?;
12706        Ok(result)
12707    }
12708
12709    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
12710        self.code_action_kinds.clone()
12711    }
12712}
12713
12714pub fn language_server_settings<'a>(
12715    delegate: &'a dyn LspAdapterDelegate,
12716    language: &LanguageServerName,
12717    cx: &'a App,
12718) -> Option<&'a LspSettings> {
12719    language_server_settings_for(
12720        SettingsLocation {
12721            worktree_id: delegate.worktree_id(),
12722            path: RelPath::empty(),
12723        },
12724        language,
12725        cx,
12726    )
12727}
12728
12729pub(crate) fn language_server_settings_for<'a>(
12730    location: SettingsLocation<'a>,
12731    language: &LanguageServerName,
12732    cx: &'a App,
12733) -> Option<&'a LspSettings> {
12734    ProjectSettings::get(Some(location), cx).lsp.get(language)
12735}
12736
12737pub struct LocalLspAdapterDelegate {
12738    lsp_store: WeakEntity<LspStore>,
12739    worktree: worktree::Snapshot,
12740    fs: Arc<dyn Fs>,
12741    http_client: Arc<dyn HttpClient>,
12742    language_registry: Arc<LanguageRegistry>,
12743    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
12744}
12745
12746impl LocalLspAdapterDelegate {
12747    pub fn new(
12748        language_registry: Arc<LanguageRegistry>,
12749        environment: &Entity<ProjectEnvironment>,
12750        lsp_store: WeakEntity<LspStore>,
12751        worktree: &Entity<Worktree>,
12752        http_client: Arc<dyn HttpClient>,
12753        fs: Arc<dyn Fs>,
12754        cx: &mut App,
12755    ) -> Arc<Self> {
12756        let load_shell_env_task = environment.update(cx, |env, cx| {
12757            env.get_worktree_environment(worktree.clone(), cx)
12758        });
12759
12760        Arc::new(Self {
12761            lsp_store,
12762            worktree: worktree.read(cx).snapshot(),
12763            fs,
12764            http_client,
12765            language_registry,
12766            load_shell_env_task,
12767        })
12768    }
12769
12770    fn from_local_lsp(
12771        local: &LocalLspStore,
12772        worktree: &Entity<Worktree>,
12773        cx: &mut App,
12774    ) -> Arc<Self> {
12775        Self::new(
12776            local.languages.clone(),
12777            &local.environment,
12778            local.weak.clone(),
12779            worktree,
12780            local.http_client.clone(),
12781            local.fs.clone(),
12782            cx,
12783        )
12784    }
12785}
12786
12787#[async_trait]
12788impl LspAdapterDelegate for LocalLspAdapterDelegate {
12789    fn show_notification(&self, message: &str, cx: &mut App) {
12790        self.lsp_store
12791            .update(cx, |_, cx| {
12792                cx.emit(LspStoreEvent::Notification(message.to_owned()))
12793            })
12794            .ok();
12795    }
12796
12797    fn http_client(&self) -> Arc<dyn HttpClient> {
12798        self.http_client.clone()
12799    }
12800
12801    fn worktree_id(&self) -> WorktreeId {
12802        self.worktree.id()
12803    }
12804
12805    fn worktree_root_path(&self) -> &Path {
12806        self.worktree.abs_path().as_ref()
12807    }
12808
12809    async fn shell_env(&self) -> HashMap<String, String> {
12810        let task = self.load_shell_env_task.clone();
12811        task.await.unwrap_or_default()
12812    }
12813
12814    async fn npm_package_installed_version(
12815        &self,
12816        package_name: &str,
12817    ) -> Result<Option<(PathBuf, String)>> {
12818        let local_package_directory = self.worktree_root_path();
12819        let node_modules_directory = local_package_directory.join("node_modules");
12820
12821        if let Some(version) =
12822            read_package_installed_version(node_modules_directory.clone(), package_name).await?
12823        {
12824            return Ok(Some((node_modules_directory, version)));
12825        }
12826        let Some(npm) = self.which("npm".as_ref()).await else {
12827            log::warn!(
12828                "Failed to find npm executable for {:?}",
12829                local_package_directory
12830            );
12831            return Ok(None);
12832        };
12833
12834        let env = self.shell_env().await;
12835        let output = util::command::new_smol_command(&npm)
12836            .args(["root", "-g"])
12837            .envs(env)
12838            .current_dir(local_package_directory)
12839            .output()
12840            .await?;
12841        let global_node_modules =
12842            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
12843
12844        if let Some(version) =
12845            read_package_installed_version(global_node_modules.clone(), package_name).await?
12846        {
12847            return Ok(Some((global_node_modules, version)));
12848        }
12849        return Ok(None);
12850    }
12851
12852    #[cfg(not(target_os = "windows"))]
12853    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12854        let worktree_abs_path = self.worktree.abs_path();
12855        let shell_path = self.shell_env().await.get("PATH").cloned();
12856        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
12857    }
12858
12859    #[cfg(target_os = "windows")]
12860    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12861        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
12862        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
12863        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
12864        which::which(command).ok()
12865    }
12866
12867    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
12868        let working_dir = self.worktree_root_path();
12869        let output = util::command::new_smol_command(&command.path)
12870            .args(command.arguments)
12871            .envs(command.env.clone().unwrap_or_default())
12872            .current_dir(working_dir)
12873            .output()
12874            .await?;
12875
12876        anyhow::ensure!(
12877            output.status.success(),
12878            "{}, stdout: {:?}, stderr: {:?}",
12879            output.status,
12880            String::from_utf8_lossy(&output.stdout),
12881            String::from_utf8_lossy(&output.stderr)
12882        );
12883        Ok(())
12884    }
12885
12886    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
12887        self.language_registry
12888            .update_lsp_binary_status(server_name, status);
12889    }
12890
12891    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
12892        self.language_registry
12893            .all_lsp_adapters()
12894            .into_iter()
12895            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
12896            .collect()
12897    }
12898
12899    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
12900        let dir = self.language_registry.language_server_download_dir(name)?;
12901
12902        if !dir.exists() {
12903            smol::fs::create_dir_all(&dir)
12904                .await
12905                .context("failed to create container directory")
12906                .log_err()?;
12907        }
12908
12909        Some(dir)
12910    }
12911
12912    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
12913        let entry = self
12914            .worktree
12915            .entry_for_path(path)
12916            .with_context(|| format!("no worktree entry for path {path:?}"))?;
12917        let abs_path = self.worktree.absolutize(&entry.path);
12918        self.fs.load(&abs_path).await
12919    }
12920}
12921
12922async fn populate_labels_for_symbols(
12923    symbols: Vec<CoreSymbol>,
12924    language_registry: &Arc<LanguageRegistry>,
12925    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12926    output: &mut Vec<Symbol>,
12927) {
12928    #[allow(clippy::mutable_key_type)]
12929    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
12930
12931    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
12932    for symbol in symbols {
12933        let Some(file_name) = symbol.path.file_name() else {
12934            continue;
12935        };
12936        let language = language_registry
12937            .language_for_file_path(Path::new(file_name))
12938            .await
12939            .ok()
12940            .or_else(|| {
12941                unknown_paths.insert(file_name.into());
12942                None
12943            });
12944        symbols_by_language
12945            .entry(language)
12946            .or_default()
12947            .push(symbol);
12948    }
12949
12950    for unknown_path in unknown_paths {
12951        log::info!("no language found for symbol in file {unknown_path:?}");
12952    }
12953
12954    let mut label_params = Vec::new();
12955    for (language, mut symbols) in symbols_by_language {
12956        label_params.clear();
12957        label_params.extend(
12958            symbols
12959                .iter_mut()
12960                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
12961        );
12962
12963        let mut labels = Vec::new();
12964        if let Some(language) = language {
12965            let lsp_adapter = lsp_adapter.clone().or_else(|| {
12966                language_registry
12967                    .lsp_adapters(&language.name())
12968                    .first()
12969                    .cloned()
12970            });
12971            if let Some(lsp_adapter) = lsp_adapter {
12972                labels = lsp_adapter
12973                    .labels_for_symbols(&label_params, &language)
12974                    .await
12975                    .log_err()
12976                    .unwrap_or_default();
12977            }
12978        }
12979
12980        for ((symbol, (name, _)), label) in symbols
12981            .into_iter()
12982            .zip(label_params.drain(..))
12983            .zip(labels.into_iter().chain(iter::repeat(None)))
12984        {
12985            output.push(Symbol {
12986                language_server_name: symbol.language_server_name,
12987                source_worktree_id: symbol.source_worktree_id,
12988                source_language_server_id: symbol.source_language_server_id,
12989                path: symbol.path,
12990                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
12991                name,
12992                kind: symbol.kind,
12993                range: symbol.range,
12994            });
12995        }
12996    }
12997}
12998
12999fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13000    match server.capabilities().text_document_sync.as_ref()? {
13001        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13002            // Server wants didSave but didn't specify includeText.
13003            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13004            // Server doesn't want didSave at all.
13005            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13006            // Server provided SaveOptions.
13007            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13008                Some(save_options.include_text.unwrap_or(false))
13009            }
13010        },
13011        // We do not have any save info. Kind affects didChange only.
13012        lsp::TextDocumentSyncCapability::Kind(_) => None,
13013    }
13014}
13015
13016/// Completion items are displayed in a `UniformList`.
13017/// Usually, those items are single-line strings, but in LSP responses,
13018/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13019/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13020/// 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,
13021/// breaking the completions menu presentation.
13022///
13023/// 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.
13024fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13025    let mut new_text = String::with_capacity(label.text.len());
13026    let mut offset_map = vec![0; label.text.len() + 1];
13027    let mut last_char_was_space = false;
13028    let mut new_idx = 0;
13029    let chars = label.text.char_indices().fuse();
13030    let mut newlines_removed = false;
13031
13032    for (idx, c) in chars {
13033        offset_map[idx] = new_idx;
13034
13035        match c {
13036            '\n' if last_char_was_space => {
13037                newlines_removed = true;
13038            }
13039            '\t' | ' ' if last_char_was_space => {}
13040            '\n' if !last_char_was_space => {
13041                new_text.push(' ');
13042                new_idx += 1;
13043                last_char_was_space = true;
13044                newlines_removed = true;
13045            }
13046            ' ' | '\t' => {
13047                new_text.push(' ');
13048                new_idx += 1;
13049                last_char_was_space = true;
13050            }
13051            _ => {
13052                new_text.push(c);
13053                new_idx += c.len_utf8();
13054                last_char_was_space = false;
13055            }
13056        }
13057    }
13058    offset_map[label.text.len()] = new_idx;
13059
13060    // Only modify the label if newlines were removed.
13061    if !newlines_removed {
13062        return;
13063    }
13064
13065    let last_index = new_idx;
13066    let mut run_ranges_errors = Vec::new();
13067    label.runs.retain_mut(|(range, _)| {
13068        match offset_map.get(range.start) {
13069            Some(&start) => range.start = start,
13070            None => {
13071                run_ranges_errors.push(range.clone());
13072                return false;
13073            }
13074        }
13075
13076        match offset_map.get(range.end) {
13077            Some(&end) => range.end = end,
13078            None => {
13079                run_ranges_errors.push(range.clone());
13080                range.end = last_index;
13081            }
13082        }
13083        true
13084    });
13085    if !run_ranges_errors.is_empty() {
13086        log::error!(
13087            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13088            label.text
13089        );
13090    }
13091
13092    let mut wrong_filter_range = None;
13093    if label.filter_range == (0..label.text.len()) {
13094        label.filter_range = 0..new_text.len();
13095    } else {
13096        let mut original_filter_range = Some(label.filter_range.clone());
13097        match offset_map.get(label.filter_range.start) {
13098            Some(&start) => label.filter_range.start = start,
13099            None => {
13100                wrong_filter_range = original_filter_range.take();
13101                label.filter_range.start = last_index;
13102            }
13103        }
13104
13105        match offset_map.get(label.filter_range.end) {
13106            Some(&end) => label.filter_range.end = end,
13107            None => {
13108                wrong_filter_range = original_filter_range.take();
13109                label.filter_range.end = last_index;
13110            }
13111        }
13112    }
13113    if let Some(wrong_filter_range) = wrong_filter_range {
13114        log::error!(
13115            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13116            label.text
13117        );
13118    }
13119
13120    label.text = new_text;
13121}
13122
13123#[cfg(test)]
13124mod tests {
13125    use language::HighlightId;
13126
13127    use super::*;
13128
13129    #[test]
13130    fn test_glob_literal_prefix() {
13131        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13132        assert_eq!(
13133            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13134            Path::new("node_modules")
13135        );
13136        assert_eq!(
13137            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13138            Path::new("foo")
13139        );
13140        assert_eq!(
13141            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13142            Path::new("foo/bar/baz.js")
13143        );
13144
13145        #[cfg(target_os = "windows")]
13146        {
13147            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13148            assert_eq!(
13149                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13150                Path::new("node_modules")
13151            );
13152            assert_eq!(
13153                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13154                Path::new("foo")
13155            );
13156            assert_eq!(
13157                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13158                Path::new("foo/bar/baz.js")
13159            );
13160        }
13161    }
13162
13163    #[test]
13164    fn test_multi_len_chars_normalization() {
13165        let mut label = CodeLabel {
13166            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13167            runs: vec![(0..6, HighlightId(1))],
13168            filter_range: 0..6,
13169        };
13170        ensure_uniform_list_compatible_label(&mut label);
13171        assert_eq!(
13172            label,
13173            CodeLabel {
13174                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13175                runs: vec![(0..6, HighlightId(1))],
13176                filter_range: 0..6,
13177            }
13178        );
13179    }
13180}