lsp_store.rs

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