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