lsp_store.rs

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