lsp_store.rs

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