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