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            .clone();
 5821            if !completion_settings.lsp {
 5822                return Task::ready(Ok(Vec::new()));
 5823            }
 5824
 5825            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5826                local
 5827                    .language_servers_for_buffer(buffer, cx)
 5828                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5829                    .filter(|(adapter, _)| {
 5830                        scope
 5831                            .as_ref()
 5832                            .map(|scope| scope.language_allowed(&adapter.name))
 5833                            .unwrap_or(true)
 5834                    })
 5835                    .map(|(_, server)| server.server_id())
 5836                    .collect()
 5837            });
 5838
 5839            let buffer = buffer.clone();
 5840            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5841            let lsp_timeout = if lsp_timeout > 0 {
 5842                Some(Duration::from_millis(lsp_timeout))
 5843            } else {
 5844                None
 5845            };
 5846            cx.spawn(async move |this,  cx| {
 5847                let mut tasks = Vec::with_capacity(server_ids.len());
 5848                this.update(cx, |lsp_store, cx| {
 5849                    for server_id in server_ids {
 5850                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5851                        let lsp_timeout = lsp_timeout
 5852                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5853                        let mut timeout = cx.background_spawn(async move {
 5854                            match lsp_timeout {
 5855                                Some(lsp_timeout) => {
 5856                                    lsp_timeout.await;
 5857                                    true
 5858                                },
 5859                                None => false,
 5860                            }
 5861                        }).fuse();
 5862                        let mut lsp_request = lsp_store.request_lsp(
 5863                            buffer.clone(),
 5864                            LanguageServerToQuery::Other(server_id),
 5865                            GetCompletions {
 5866                                position,
 5867                                context: context.clone(),
 5868                            },
 5869                            cx,
 5870                        ).fuse();
 5871                        let new_task = cx.background_spawn(async move {
 5872                            select_biased! {
 5873                                response = lsp_request => anyhow::Ok(Some(response?)),
 5874                                timeout_happened = timeout => {
 5875                                    if timeout_happened {
 5876                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5877                                        Ok(None)
 5878                                    } else {
 5879                                        let completions = lsp_request.await?;
 5880                                        Ok(Some(completions))
 5881                                    }
 5882                                },
 5883                            }
 5884                        });
 5885                        tasks.push((lsp_adapter, new_task));
 5886                    }
 5887                })?;
 5888
 5889                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5890                    let completion_response = task.await.ok()??;
 5891                    let completions = populate_labels_for_completions(
 5892                            completion_response.completions,
 5893                            language.clone(),
 5894                            lsp_adapter,
 5895                        )
 5896                        .await;
 5897                    Some(CompletionResponse {
 5898                        completions,
 5899                        display_options: CompletionDisplayOptions::default(),
 5900                        is_incomplete: completion_response.is_incomplete,
 5901                    })
 5902                });
 5903
 5904                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 5905
 5906                Ok(responses.into_iter().flatten().collect())
 5907            })
 5908        } else {
 5909            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5910        }
 5911    }
 5912
 5913    pub fn resolve_completions(
 5914        &self,
 5915        buffer: Entity<Buffer>,
 5916        completion_indices: Vec<usize>,
 5917        completions: Rc<RefCell<Box<[Completion]>>>,
 5918        cx: &mut Context<Self>,
 5919    ) -> Task<Result<bool>> {
 5920        let client = self.upstream_client();
 5921        let buffer_id = buffer.read(cx).remote_id();
 5922        let buffer_snapshot = buffer.read(cx).snapshot();
 5923
 5924        if !self.check_if_capable_for_proto_request(
 5925            &buffer,
 5926            GetCompletions::can_resolve_completions,
 5927            cx,
 5928        ) {
 5929            return Task::ready(Ok(false));
 5930        }
 5931        cx.spawn(async move |lsp_store, cx| {
 5932            let mut did_resolve = false;
 5933            if let Some((client, project_id)) = client {
 5934                for completion_index in completion_indices {
 5935                    let server_id = {
 5936                        let completion = &completions.borrow()[completion_index];
 5937                        completion.source.server_id()
 5938                    };
 5939                    if let Some(server_id) = server_id {
 5940                        if Self::resolve_completion_remote(
 5941                            project_id,
 5942                            server_id,
 5943                            buffer_id,
 5944                            completions.clone(),
 5945                            completion_index,
 5946                            client.clone(),
 5947                        )
 5948                        .await
 5949                        .log_err()
 5950                        .is_some()
 5951                        {
 5952                            did_resolve = true;
 5953                        }
 5954                    } else {
 5955                        resolve_word_completion(
 5956                            &buffer_snapshot,
 5957                            &mut completions.borrow_mut()[completion_index],
 5958                        );
 5959                    }
 5960                }
 5961            } else {
 5962                for completion_index in completion_indices {
 5963                    let server_id = {
 5964                        let completion = &completions.borrow()[completion_index];
 5965                        completion.source.server_id()
 5966                    };
 5967                    if let Some(server_id) = server_id {
 5968                        let server_and_adapter = lsp_store
 5969                            .read_with(cx, |lsp_store, _| {
 5970                                let server = lsp_store.language_server_for_id(server_id)?;
 5971                                let adapter =
 5972                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 5973                                Some((server, adapter))
 5974                            })
 5975                            .ok()
 5976                            .flatten();
 5977                        let Some((server, adapter)) = server_and_adapter else {
 5978                            continue;
 5979                        };
 5980
 5981                        let resolved = Self::resolve_completion_local(
 5982                            server,
 5983                            completions.clone(),
 5984                            completion_index,
 5985                        )
 5986                        .await
 5987                        .log_err()
 5988                        .is_some();
 5989                        if resolved {
 5990                            Self::regenerate_completion_labels(
 5991                                adapter,
 5992                                &buffer_snapshot,
 5993                                completions.clone(),
 5994                                completion_index,
 5995                            )
 5996                            .await
 5997                            .log_err();
 5998                            did_resolve = true;
 5999                        }
 6000                    } else {
 6001                        resolve_word_completion(
 6002                            &buffer_snapshot,
 6003                            &mut completions.borrow_mut()[completion_index],
 6004                        );
 6005                    }
 6006                }
 6007            }
 6008
 6009            Ok(did_resolve)
 6010        })
 6011    }
 6012
 6013    async fn resolve_completion_local(
 6014        server: Arc<lsp::LanguageServer>,
 6015        completions: Rc<RefCell<Box<[Completion]>>>,
 6016        completion_index: usize,
 6017    ) -> Result<()> {
 6018        let server_id = server.server_id();
 6019        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6020            return Ok(());
 6021        }
 6022
 6023        let request = {
 6024            let completion = &completions.borrow()[completion_index];
 6025            match &completion.source {
 6026                CompletionSource::Lsp {
 6027                    lsp_completion,
 6028                    resolved,
 6029                    server_id: completion_server_id,
 6030                    ..
 6031                } => {
 6032                    if *resolved {
 6033                        return Ok(());
 6034                    }
 6035                    anyhow::ensure!(
 6036                        server_id == *completion_server_id,
 6037                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6038                    );
 6039                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6040                }
 6041                CompletionSource::BufferWord { .. }
 6042                | CompletionSource::Dap { .. }
 6043                | CompletionSource::Custom => {
 6044                    return Ok(());
 6045                }
 6046            }
 6047        };
 6048        let resolved_completion = request
 6049            .await
 6050            .into_response()
 6051            .context("resolve completion")?;
 6052
 6053        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6054        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6055
 6056        let mut completions = completions.borrow_mut();
 6057        let completion = &mut completions[completion_index];
 6058        if let CompletionSource::Lsp {
 6059            lsp_completion,
 6060            resolved,
 6061            server_id: completion_server_id,
 6062            ..
 6063        } = &mut completion.source
 6064        {
 6065            if *resolved {
 6066                return Ok(());
 6067            }
 6068            anyhow::ensure!(
 6069                server_id == *completion_server_id,
 6070                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6071            );
 6072            *lsp_completion = Box::new(resolved_completion);
 6073            *resolved = true;
 6074        }
 6075        Ok(())
 6076    }
 6077
 6078    async fn regenerate_completion_labels(
 6079        adapter: Arc<CachedLspAdapter>,
 6080        snapshot: &BufferSnapshot,
 6081        completions: Rc<RefCell<Box<[Completion]>>>,
 6082        completion_index: usize,
 6083    ) -> Result<()> {
 6084        let completion_item = completions.borrow()[completion_index]
 6085            .source
 6086            .lsp_completion(true)
 6087            .map(Cow::into_owned);
 6088        if let Some(lsp_documentation) = completion_item
 6089            .as_ref()
 6090            .and_then(|completion_item| completion_item.documentation.clone())
 6091        {
 6092            let mut completions = completions.borrow_mut();
 6093            let completion = &mut completions[completion_index];
 6094            completion.documentation = Some(lsp_documentation.into());
 6095        } else {
 6096            let mut completions = completions.borrow_mut();
 6097            let completion = &mut completions[completion_index];
 6098            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6099        }
 6100
 6101        let mut new_label = match completion_item {
 6102            Some(completion_item) => {
 6103                // 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
 6104                // So we have to update the label here anyway...
 6105                let language = snapshot.language();
 6106                match language {
 6107                    Some(language) => {
 6108                        adapter
 6109                            .labels_for_completions(
 6110                                std::slice::from_ref(&completion_item),
 6111                                language,
 6112                            )
 6113                            .await?
 6114                    }
 6115                    None => Vec::new(),
 6116                }
 6117                .pop()
 6118                .flatten()
 6119                .unwrap_or_else(|| {
 6120                    CodeLabel::fallback_for_completion(
 6121                        &completion_item,
 6122                        language.map(|language| language.as_ref()),
 6123                    )
 6124                })
 6125            }
 6126            None => CodeLabel::plain(
 6127                completions.borrow()[completion_index].new_text.clone(),
 6128                None,
 6129            ),
 6130        };
 6131        ensure_uniform_list_compatible_label(&mut new_label);
 6132
 6133        let mut completions = completions.borrow_mut();
 6134        let completion = &mut completions[completion_index];
 6135        if completion.label.filter_text() == new_label.filter_text() {
 6136            completion.label = new_label;
 6137        } else {
 6138            log::error!(
 6139                "Resolved completion changed display label from {} to {}. \
 6140                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6141                completion.label.text(),
 6142                new_label.text(),
 6143                completion.label.filter_text(),
 6144                new_label.filter_text()
 6145            );
 6146        }
 6147
 6148        Ok(())
 6149    }
 6150
 6151    async fn resolve_completion_remote(
 6152        project_id: u64,
 6153        server_id: LanguageServerId,
 6154        buffer_id: BufferId,
 6155        completions: Rc<RefCell<Box<[Completion]>>>,
 6156        completion_index: usize,
 6157        client: AnyProtoClient,
 6158    ) -> Result<()> {
 6159        let lsp_completion = {
 6160            let completion = &completions.borrow()[completion_index];
 6161            match &completion.source {
 6162                CompletionSource::Lsp {
 6163                    lsp_completion,
 6164                    resolved,
 6165                    server_id: completion_server_id,
 6166                    ..
 6167                } => {
 6168                    anyhow::ensure!(
 6169                        server_id == *completion_server_id,
 6170                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6171                    );
 6172                    if *resolved {
 6173                        return Ok(());
 6174                    }
 6175                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6176                }
 6177                CompletionSource::Custom
 6178                | CompletionSource::Dap { .. }
 6179                | CompletionSource::BufferWord { .. } => {
 6180                    return Ok(());
 6181                }
 6182            }
 6183        };
 6184        let request = proto::ResolveCompletionDocumentation {
 6185            project_id,
 6186            language_server_id: server_id.0 as u64,
 6187            lsp_completion,
 6188            buffer_id: buffer_id.into(),
 6189        };
 6190
 6191        let response = client
 6192            .request(request)
 6193            .await
 6194            .context("completion documentation resolve proto request")?;
 6195        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6196
 6197        let documentation = if response.documentation.is_empty() {
 6198            CompletionDocumentation::Undocumented
 6199        } else if response.documentation_is_markdown {
 6200            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6201        } else if response.documentation.lines().count() <= 1 {
 6202            CompletionDocumentation::SingleLine(response.documentation.into())
 6203        } else {
 6204            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6205        };
 6206
 6207        let mut completions = completions.borrow_mut();
 6208        let completion = &mut completions[completion_index];
 6209        completion.documentation = Some(documentation);
 6210        if let CompletionSource::Lsp {
 6211            insert_range,
 6212            lsp_completion,
 6213            resolved,
 6214            server_id: completion_server_id,
 6215            lsp_defaults: _,
 6216        } = &mut completion.source
 6217        {
 6218            let completion_insert_range = response
 6219                .old_insert_start
 6220                .and_then(deserialize_anchor)
 6221                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6222            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6223
 6224            if *resolved {
 6225                return Ok(());
 6226            }
 6227            anyhow::ensure!(
 6228                server_id == *completion_server_id,
 6229                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6230            );
 6231            *lsp_completion = Box::new(resolved_lsp_completion);
 6232            *resolved = true;
 6233        }
 6234
 6235        let replace_range = response
 6236            .old_replace_start
 6237            .and_then(deserialize_anchor)
 6238            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6239        if let Some((old_replace_start, old_replace_end)) = replace_range
 6240            && !response.new_text.is_empty()
 6241        {
 6242            completion.new_text = response.new_text;
 6243            completion.replace_range = old_replace_start..old_replace_end;
 6244        }
 6245
 6246        Ok(())
 6247    }
 6248
 6249    pub fn apply_additional_edits_for_completion(
 6250        &self,
 6251        buffer_handle: Entity<Buffer>,
 6252        completions: Rc<RefCell<Box<[Completion]>>>,
 6253        completion_index: usize,
 6254        push_to_history: bool,
 6255        cx: &mut Context<Self>,
 6256    ) -> Task<Result<Option<Transaction>>> {
 6257        if let Some((client, project_id)) = self.upstream_client() {
 6258            let buffer = buffer_handle.read(cx);
 6259            let buffer_id = buffer.remote_id();
 6260            cx.spawn(async move |_, cx| {
 6261                let request = {
 6262                    let completion = completions.borrow()[completion_index].clone();
 6263                    proto::ApplyCompletionAdditionalEdits {
 6264                        project_id,
 6265                        buffer_id: buffer_id.into(),
 6266                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6267                            replace_range: completion.replace_range,
 6268                            new_text: completion.new_text,
 6269                            source: completion.source,
 6270                        })),
 6271                    }
 6272                };
 6273
 6274                if let Some(transaction) = client.request(request).await?.transaction {
 6275                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6276                    buffer_handle
 6277                        .update(cx, |buffer, _| {
 6278                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6279                        })?
 6280                        .await?;
 6281                    if push_to_history {
 6282                        buffer_handle.update(cx, |buffer, _| {
 6283                            buffer.push_transaction(transaction.clone(), Instant::now());
 6284                            buffer.finalize_last_transaction();
 6285                        })?;
 6286                    }
 6287                    Ok(Some(transaction))
 6288                } else {
 6289                    Ok(None)
 6290                }
 6291            })
 6292        } else {
 6293            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6294                let completion = &completions.borrow()[completion_index];
 6295                let server_id = completion.source.server_id()?;
 6296                Some(
 6297                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6298                        .1
 6299                        .clone(),
 6300                )
 6301            }) else {
 6302                return Task::ready(Ok(None));
 6303            };
 6304
 6305            cx.spawn(async move |this, cx| {
 6306                Self::resolve_completion_local(
 6307                    server.clone(),
 6308                    completions.clone(),
 6309                    completion_index,
 6310                )
 6311                .await
 6312                .context("resolving completion")?;
 6313                let completion = completions.borrow()[completion_index].clone();
 6314                let additional_text_edits = completion
 6315                    .source
 6316                    .lsp_completion(true)
 6317                    .as_ref()
 6318                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6319                if let Some(edits) = additional_text_edits {
 6320                    let edits = this
 6321                        .update(cx, |this, cx| {
 6322                            this.as_local_mut().unwrap().edits_from_lsp(
 6323                                &buffer_handle,
 6324                                edits,
 6325                                server.server_id(),
 6326                                None,
 6327                                cx,
 6328                            )
 6329                        })?
 6330                        .await?;
 6331
 6332                    buffer_handle.update(cx, |buffer, cx| {
 6333                        buffer.finalize_last_transaction();
 6334                        buffer.start_transaction();
 6335
 6336                        for (range, text) in edits {
 6337                            let primary = &completion.replace_range;
 6338
 6339                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6340                            // and the primary completion is just an insertion (empty range), then this is likely
 6341                            // an auto-import scenario and should not be considered overlapping
 6342                            // https://github.com/zed-industries/zed/issues/26136
 6343                            let is_file_start_auto_import = {
 6344                                let snapshot = buffer.snapshot();
 6345                                let primary_start_point = primary.start.to_point(&snapshot);
 6346                                let range_start_point = range.start.to_point(&snapshot);
 6347
 6348                                let result = primary_start_point.row == 0
 6349                                    && primary_start_point.column == 0
 6350                                    && range_start_point.row == 0
 6351                                    && range_start_point.column == 0;
 6352
 6353                                result
 6354                            };
 6355
 6356                            let has_overlap = if is_file_start_auto_import {
 6357                                false
 6358                            } else {
 6359                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6360                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6361                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6362                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6363                                let result = start_within || end_within;
 6364                                result
 6365                            };
 6366
 6367                            //Skip additional edits which overlap with the primary completion edit
 6368                            //https://github.com/zed-industries/zed/pull/1871
 6369                            if !has_overlap {
 6370                                buffer.edit([(range, text)], None, cx);
 6371                            }
 6372                        }
 6373
 6374                        let transaction = if buffer.end_transaction(cx).is_some() {
 6375                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6376                            if !push_to_history {
 6377                                buffer.forget_transaction(transaction.id);
 6378                            }
 6379                            Some(transaction)
 6380                        } else {
 6381                            None
 6382                        };
 6383                        Ok(transaction)
 6384                    })?
 6385                } else {
 6386                    Ok(None)
 6387                }
 6388            })
 6389        }
 6390    }
 6391
 6392    pub fn pull_diagnostics(
 6393        &mut self,
 6394        buffer: Entity<Buffer>,
 6395        cx: &mut Context<Self>,
 6396    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6397        let buffer_id = buffer.read(cx).remote_id();
 6398
 6399        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6400            let request = GetDocumentDiagnostics {
 6401                previous_result_id: None,
 6402            };
 6403            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6404                return Task::ready(Ok(None));
 6405            }
 6406            let request_task = client.request_lsp(
 6407                upstream_project_id,
 6408                LSP_REQUEST_TIMEOUT,
 6409                cx.background_executor().clone(),
 6410                request.to_proto(upstream_project_id, buffer.read(cx)),
 6411            );
 6412            cx.background_spawn(async move {
 6413                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6414                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6415                // Do not attempt to further process the dummy responses here.
 6416                let _response = request_task.await?;
 6417                Ok(None)
 6418            })
 6419        } else {
 6420            let server_ids = buffer.update(cx, |buffer, cx| {
 6421                self.language_servers_for_local_buffer(buffer, cx)
 6422                    .map(|(_, server)| server.server_id())
 6423                    .collect::<Vec<_>>()
 6424            });
 6425            let pull_diagnostics = server_ids
 6426                .into_iter()
 6427                .map(|server_id| {
 6428                    let result_id = self.result_id(server_id, buffer_id, cx);
 6429                    self.request_lsp(
 6430                        buffer.clone(),
 6431                        LanguageServerToQuery::Other(server_id),
 6432                        GetDocumentDiagnostics {
 6433                            previous_result_id: result_id,
 6434                        },
 6435                        cx,
 6436                    )
 6437                })
 6438                .collect::<Vec<_>>();
 6439
 6440            cx.background_spawn(async move {
 6441                let mut responses = Vec::new();
 6442                for diagnostics in join_all(pull_diagnostics).await {
 6443                    responses.extend(diagnostics?);
 6444                }
 6445                Ok(Some(responses))
 6446            })
 6447        }
 6448    }
 6449
 6450    pub fn inlay_hints(
 6451        &mut self,
 6452        buffer: Entity<Buffer>,
 6453        range: Range<Anchor>,
 6454        cx: &mut Context<Self>,
 6455    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
 6456        let range_start = range.start;
 6457        let range_end = range.end;
 6458        let buffer_id = buffer.read(cx).remote_id().into();
 6459        let request = InlayHints { range };
 6460
 6461        if let Some((client, project_id)) = self.upstream_client() {
 6462            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6463                return Task::ready(Ok(Vec::new()));
 6464            }
 6465            let proto_request = proto::InlayHints {
 6466                project_id,
 6467                buffer_id,
 6468                start: Some(serialize_anchor(&range_start)),
 6469                end: Some(serialize_anchor(&range_end)),
 6470                version: serialize_version(&buffer.read(cx).version()),
 6471            };
 6472            cx.spawn(async move |project, cx| {
 6473                let response = client
 6474                    .request(proto_request)
 6475                    .await
 6476                    .context("inlay hints proto request")?;
 6477                LspCommand::response_from_proto(
 6478                    request,
 6479                    response,
 6480                    project.upgrade().context("No project")?,
 6481                    buffer.clone(),
 6482                    cx.clone(),
 6483                )
 6484                .await
 6485                .context("inlay hints proto response conversion")
 6486            })
 6487        } else {
 6488            let lsp_request_task = self.request_lsp(
 6489                buffer.clone(),
 6490                LanguageServerToQuery::FirstCapable,
 6491                request,
 6492                cx,
 6493            );
 6494            cx.spawn(async move |_, cx| {
 6495                buffer
 6496                    .update(cx, |buffer, _| {
 6497                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
 6498                    })?
 6499                    .await
 6500                    .context("waiting for inlay hint request range edits")?;
 6501                lsp_request_task.await.context("inlay hints LSP request")
 6502            })
 6503        }
 6504    }
 6505
 6506    pub fn pull_diagnostics_for_buffer(
 6507        &mut self,
 6508        buffer: Entity<Buffer>,
 6509        cx: &mut Context<Self>,
 6510    ) -> Task<anyhow::Result<()>> {
 6511        let diagnostics = self.pull_diagnostics(buffer, cx);
 6512        cx.spawn(async move |lsp_store, cx| {
 6513            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6514                return Ok(());
 6515            };
 6516            lsp_store.update(cx, |lsp_store, cx| {
 6517                if lsp_store.as_local().is_none() {
 6518                    return;
 6519                }
 6520
 6521                let mut unchanged_buffers = HashSet::default();
 6522                let mut changed_buffers = HashSet::default();
 6523                let server_diagnostics_updates = diagnostics
 6524                    .into_iter()
 6525                    .filter_map(|diagnostics_set| match diagnostics_set {
 6526                        LspPullDiagnostics::Response {
 6527                            server_id,
 6528                            uri,
 6529                            diagnostics,
 6530                        } => Some((server_id, uri, diagnostics)),
 6531                        LspPullDiagnostics::Default => None,
 6532                    })
 6533                    .fold(
 6534                        HashMap::default(),
 6535                        |mut acc, (server_id, uri, diagnostics)| {
 6536                            let (result_id, diagnostics) = match diagnostics {
 6537                                PulledDiagnostics::Unchanged { result_id } => {
 6538                                    unchanged_buffers.insert(uri.clone());
 6539                                    (Some(result_id), Vec::new())
 6540                                }
 6541                                PulledDiagnostics::Changed {
 6542                                    result_id,
 6543                                    diagnostics,
 6544                                } => {
 6545                                    changed_buffers.insert(uri.clone());
 6546                                    (result_id, diagnostics)
 6547                                }
 6548                            };
 6549                            let disk_based_sources = Cow::Owned(
 6550                                lsp_store
 6551                                    .language_server_adapter_for_id(server_id)
 6552                                    .as_ref()
 6553                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6554                                    .unwrap_or(&[])
 6555                                    .to_vec(),
 6556                            );
 6557                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6558                                DocumentDiagnosticsUpdate {
 6559                                    server_id,
 6560                                    diagnostics: lsp::PublishDiagnosticsParams {
 6561                                        uri,
 6562                                        diagnostics,
 6563                                        version: None,
 6564                                    },
 6565                                    result_id,
 6566                                    disk_based_sources,
 6567                                },
 6568                            );
 6569                            acc
 6570                        },
 6571                    );
 6572
 6573                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6574                    lsp_store
 6575                        .merge_lsp_diagnostics(
 6576                            DiagnosticSourceKind::Pulled,
 6577                            diagnostic_updates,
 6578                            |buffer, old_diagnostic, cx| {
 6579                                File::from_dyn(buffer.file())
 6580                                    .and_then(|file| {
 6581                                        let abs_path = file.as_local()?.abs_path(cx);
 6582                                        lsp::Uri::from_file_path(abs_path).ok()
 6583                                    })
 6584                                    .is_none_or(|buffer_uri| {
 6585                                        unchanged_buffers.contains(&buffer_uri)
 6586                                            || match old_diagnostic.source_kind {
 6587                                                DiagnosticSourceKind::Pulled => {
 6588                                                    !changed_buffers.contains(&buffer_uri)
 6589                                                }
 6590                                                DiagnosticSourceKind::Other
 6591                                                | DiagnosticSourceKind::Pushed => true,
 6592                                            }
 6593                                    })
 6594                            },
 6595                            cx,
 6596                        )
 6597                        .log_err();
 6598                }
 6599            })
 6600        })
 6601    }
 6602
 6603    pub fn document_colors(
 6604        &mut self,
 6605        fetch_strategy: LspFetchStrategy,
 6606        buffer: Entity<Buffer>,
 6607        cx: &mut Context<Self>,
 6608    ) -> Option<DocumentColorTask> {
 6609        let version_queried_for = buffer.read(cx).version();
 6610        let buffer_id = buffer.read(cx).remote_id();
 6611
 6612        match fetch_strategy {
 6613            LspFetchStrategy::IgnoreCache => {}
 6614            LspFetchStrategy::UseCache {
 6615                known_cache_version,
 6616            } => {
 6617                if let Some(cached_data) = self.lsp_document_colors.get(&buffer_id)
 6618                    && !version_queried_for.changed_since(&cached_data.colors_for_version)
 6619                {
 6620                    let has_different_servers = self.as_local().is_some_and(|local| {
 6621                        local
 6622                            .buffers_opened_in_servers
 6623                            .get(&buffer_id)
 6624                            .cloned()
 6625                            .unwrap_or_default()
 6626                            != cached_data.colors.keys().copied().collect()
 6627                    });
 6628                    if !has_different_servers {
 6629                        if Some(cached_data.cache_version) == known_cache_version {
 6630                            return None;
 6631                        } else {
 6632                            return Some(
 6633                                Task::ready(Ok(DocumentColors {
 6634                                    colors: cached_data
 6635                                        .colors
 6636                                        .values()
 6637                                        .flatten()
 6638                                        .cloned()
 6639                                        .collect(),
 6640                                    cache_version: Some(cached_data.cache_version),
 6641                                }))
 6642                                .shared(),
 6643                            );
 6644                        }
 6645                    }
 6646                }
 6647            }
 6648        }
 6649
 6650        let lsp_data = self.lsp_document_colors.entry(buffer_id).or_default();
 6651        if let Some((updating_for, running_update)) = &lsp_data.colors_update
 6652            && !version_queried_for.changed_since(updating_for)
 6653        {
 6654            return Some(running_update.clone());
 6655        }
 6656        let query_version_queried_for = version_queried_for.clone();
 6657        let new_task = cx
 6658            .spawn(async move |lsp_store, cx| {
 6659                cx.background_executor()
 6660                    .timer(Duration::from_millis(30))
 6661                    .await;
 6662                let fetched_colors = lsp_store
 6663                    .update(cx, |lsp_store, cx| {
 6664                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 6665                    })?
 6666                    .await
 6667                    .context("fetching document colors")
 6668                    .map_err(Arc::new);
 6669                let fetched_colors = match fetched_colors {
 6670                    Ok(fetched_colors) => {
 6671                        if fetch_strategy != LspFetchStrategy::IgnoreCache
 6672                            && Some(true)
 6673                                == buffer
 6674                                    .update(cx, |buffer, _| {
 6675                                        buffer.version() != query_version_queried_for
 6676                                    })
 6677                                    .ok()
 6678                        {
 6679                            return Ok(DocumentColors::default());
 6680                        }
 6681                        fetched_colors
 6682                    }
 6683                    Err(e) => {
 6684                        lsp_store
 6685                            .update(cx, |lsp_store, _| {
 6686                                lsp_store
 6687                                    .lsp_document_colors
 6688                                    .entry(buffer_id)
 6689                                    .or_default()
 6690                                    .colors_update = None;
 6691                            })
 6692                            .ok();
 6693                        return Err(e);
 6694                    }
 6695                };
 6696
 6697                lsp_store
 6698                    .update(cx, |lsp_store, _| {
 6699                        let lsp_data = lsp_store.lsp_document_colors.entry(buffer_id).or_default();
 6700
 6701                        if let Some(fetched_colors) = fetched_colors {
 6702                            if lsp_data.colors_for_version == query_version_queried_for {
 6703                                lsp_data.colors.extend(fetched_colors);
 6704                                lsp_data.cache_version += 1;
 6705                            } else if !lsp_data
 6706                                .colors_for_version
 6707                                .changed_since(&query_version_queried_for)
 6708                            {
 6709                                lsp_data.colors_for_version = query_version_queried_for;
 6710                                lsp_data.colors = fetched_colors;
 6711                                lsp_data.cache_version += 1;
 6712                            }
 6713                        }
 6714                        lsp_data.colors_update = None;
 6715                        let colors = lsp_data
 6716                            .colors
 6717                            .values()
 6718                            .flatten()
 6719                            .cloned()
 6720                            .collect::<HashSet<_>>();
 6721                        DocumentColors {
 6722                            colors,
 6723                            cache_version: Some(lsp_data.cache_version),
 6724                        }
 6725                    })
 6726                    .map_err(Arc::new)
 6727            })
 6728            .shared();
 6729        lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 6730        Some(new_task)
 6731    }
 6732
 6733    fn fetch_document_colors_for_buffer(
 6734        &mut self,
 6735        buffer: &Entity<Buffer>,
 6736        cx: &mut Context<Self>,
 6737    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 6738        if let Some((client, project_id)) = self.upstream_client() {
 6739            let request = GetDocumentColor {};
 6740            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6741                return Task::ready(Ok(None));
 6742            }
 6743
 6744            let request_task = client.request_lsp(
 6745                project_id,
 6746                LSP_REQUEST_TIMEOUT,
 6747                cx.background_executor().clone(),
 6748                request.to_proto(project_id, buffer.read(cx)),
 6749            );
 6750            let buffer = buffer.clone();
 6751            cx.spawn(async move |lsp_store, cx| {
 6752                let Some(project) = lsp_store.upgrade() else {
 6753                    return Ok(None);
 6754                };
 6755                let colors = join_all(
 6756                    request_task
 6757                        .await
 6758                        .log_err()
 6759                        .flatten()
 6760                        .map(|response| response.payload)
 6761                        .unwrap_or_default()
 6762                        .into_iter()
 6763                        .map(|color_response| {
 6764                            let response = request.response_from_proto(
 6765                                color_response.response,
 6766                                project.clone(),
 6767                                buffer.clone(),
 6768                                cx.clone(),
 6769                            );
 6770                            async move {
 6771                                (
 6772                                    LanguageServerId::from_proto(color_response.server_id),
 6773                                    response.await.log_err().unwrap_or_default(),
 6774                                )
 6775                            }
 6776                        }),
 6777                )
 6778                .await
 6779                .into_iter()
 6780                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6781                    acc.entry(server_id)
 6782                        .or_insert_with(HashSet::default)
 6783                        .extend(colors);
 6784                    acc
 6785                });
 6786                Ok(Some(colors))
 6787            })
 6788        } else {
 6789            let document_colors_task =
 6790                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 6791            cx.background_spawn(async move {
 6792                Ok(Some(
 6793                    document_colors_task
 6794                        .await
 6795                        .into_iter()
 6796                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6797                            acc.entry(server_id)
 6798                                .or_insert_with(HashSet::default)
 6799                                .extend(colors);
 6800                            acc
 6801                        })
 6802                        .into_iter()
 6803                        .collect(),
 6804                ))
 6805            })
 6806        }
 6807    }
 6808
 6809    pub fn signature_help<T: ToPointUtf16>(
 6810        &mut self,
 6811        buffer: &Entity<Buffer>,
 6812        position: T,
 6813        cx: &mut Context<Self>,
 6814    ) -> Task<Option<Vec<SignatureHelp>>> {
 6815        let position = position.to_point_utf16(buffer.read(cx));
 6816
 6817        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6818            let request = GetSignatureHelp { position };
 6819            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6820                return Task::ready(None);
 6821            }
 6822            let request_task = client.request_lsp(
 6823                upstream_project_id,
 6824                LSP_REQUEST_TIMEOUT,
 6825                cx.background_executor().clone(),
 6826                request.to_proto(upstream_project_id, buffer.read(cx)),
 6827            );
 6828            let buffer = buffer.clone();
 6829            cx.spawn(async move |weak_project, cx| {
 6830                let project = weak_project.upgrade()?;
 6831                let signatures = join_all(
 6832                    request_task
 6833                        .await
 6834                        .log_err()
 6835                        .flatten()
 6836                        .map(|response| response.payload)
 6837                        .unwrap_or_default()
 6838                        .into_iter()
 6839                        .map(|response| {
 6840                            let response = GetSignatureHelp { position }.response_from_proto(
 6841                                response.response,
 6842                                project.clone(),
 6843                                buffer.clone(),
 6844                                cx.clone(),
 6845                            );
 6846                            async move { response.await.log_err().flatten() }
 6847                        }),
 6848                )
 6849                .await
 6850                .into_iter()
 6851                .flatten()
 6852                .collect();
 6853                Some(signatures)
 6854            })
 6855        } else {
 6856            let all_actions_task = self.request_multiple_lsp_locally(
 6857                buffer,
 6858                Some(position),
 6859                GetSignatureHelp { position },
 6860                cx,
 6861            );
 6862            cx.background_spawn(async move {
 6863                Some(
 6864                    all_actions_task
 6865                        .await
 6866                        .into_iter()
 6867                        .flat_map(|(_, actions)| actions)
 6868                        .collect::<Vec<_>>(),
 6869                )
 6870            })
 6871        }
 6872    }
 6873
 6874    pub fn hover(
 6875        &mut self,
 6876        buffer: &Entity<Buffer>,
 6877        position: PointUtf16,
 6878        cx: &mut Context<Self>,
 6879    ) -> Task<Option<Vec<Hover>>> {
 6880        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6881            let request = GetHover { position };
 6882            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6883                return Task::ready(None);
 6884            }
 6885            let request_task = client.request_lsp(
 6886                upstream_project_id,
 6887                LSP_REQUEST_TIMEOUT,
 6888                cx.background_executor().clone(),
 6889                request.to_proto(upstream_project_id, buffer.read(cx)),
 6890            );
 6891            let buffer = buffer.clone();
 6892            cx.spawn(async move |weak_project, cx| {
 6893                let project = weak_project.upgrade()?;
 6894                let hovers = join_all(
 6895                    request_task
 6896                        .await
 6897                        .log_err()
 6898                        .flatten()
 6899                        .map(|response| response.payload)
 6900                        .unwrap_or_default()
 6901                        .into_iter()
 6902                        .map(|response| {
 6903                            let response = GetHover { position }.response_from_proto(
 6904                                response.response,
 6905                                project.clone(),
 6906                                buffer.clone(),
 6907                                cx.clone(),
 6908                            );
 6909                            async move {
 6910                                response
 6911                                    .await
 6912                                    .log_err()
 6913                                    .flatten()
 6914                                    .and_then(remove_empty_hover_blocks)
 6915                            }
 6916                        }),
 6917                )
 6918                .await
 6919                .into_iter()
 6920                .flatten()
 6921                .collect();
 6922                Some(hovers)
 6923            })
 6924        } else {
 6925            let all_actions_task = self.request_multiple_lsp_locally(
 6926                buffer,
 6927                Some(position),
 6928                GetHover { position },
 6929                cx,
 6930            );
 6931            cx.background_spawn(async move {
 6932                Some(
 6933                    all_actions_task
 6934                        .await
 6935                        .into_iter()
 6936                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 6937                        .collect::<Vec<Hover>>(),
 6938                )
 6939            })
 6940        }
 6941    }
 6942
 6943    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 6944        let language_registry = self.languages.clone();
 6945
 6946        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 6947            let request = upstream_client.request(proto::GetProjectSymbols {
 6948                project_id: *project_id,
 6949                query: query.to_string(),
 6950            });
 6951            cx.foreground_executor().spawn(async move {
 6952                let response = request.await?;
 6953                let mut symbols = Vec::new();
 6954                let core_symbols = response
 6955                    .symbols
 6956                    .into_iter()
 6957                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 6958                    .collect::<Vec<_>>();
 6959                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 6960                    .await;
 6961                Ok(symbols)
 6962            })
 6963        } else if let Some(local) = self.as_local() {
 6964            struct WorkspaceSymbolsResult {
 6965                server_id: LanguageServerId,
 6966                lsp_adapter: Arc<CachedLspAdapter>,
 6967                worktree: WeakEntity<Worktree>,
 6968                worktree_abs_path: Arc<Path>,
 6969                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 6970            }
 6971
 6972            let mut requests = Vec::new();
 6973            let mut requested_servers = BTreeSet::new();
 6974            for (seed, state) in local.language_server_ids.iter() {
 6975                let Some(worktree_handle) = self
 6976                    .worktree_store
 6977                    .read(cx)
 6978                    .worktree_for_id(seed.worktree_id, cx)
 6979                else {
 6980                    continue;
 6981                };
 6982                let worktree = worktree_handle.read(cx);
 6983                if !worktree.is_visible() {
 6984                    continue;
 6985                }
 6986
 6987                if !requested_servers.insert(state.id) {
 6988                    continue;
 6989                }
 6990
 6991                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 6992                    Some(LanguageServerState::Running {
 6993                        adapter, server, ..
 6994                    }) => (adapter.clone(), server),
 6995
 6996                    _ => continue,
 6997                };
 6998                let supports_workspace_symbol_request =
 6999                    match server.capabilities().workspace_symbol_provider {
 7000                        Some(OneOf::Left(supported)) => supported,
 7001                        Some(OneOf::Right(_)) => true,
 7002                        None => false,
 7003                    };
 7004                if !supports_workspace_symbol_request {
 7005                    continue;
 7006                }
 7007                let worktree_abs_path = worktree.abs_path().clone();
 7008                let worktree_handle = worktree_handle.clone();
 7009                let server_id = server.server_id();
 7010                requests.push(
 7011                        server
 7012                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7013                                lsp::WorkspaceSymbolParams {
 7014                                    query: query.to_string(),
 7015                                    ..Default::default()
 7016                                },
 7017                            )
 7018                            .map(move |response| {
 7019                                let lsp_symbols = response.into_response()
 7020                                    .context("workspace symbols request")
 7021                                    .log_err()
 7022                                    .flatten()
 7023                                    .map(|symbol_response| match symbol_response {
 7024                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7025                                            flat_responses.into_iter().map(|lsp_symbol| {
 7026                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7027                                            }).collect::<Vec<_>>()
 7028                                        }
 7029                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7030                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7031                                                let location = match lsp_symbol.location {
 7032                                                    OneOf::Left(location) => location,
 7033                                                    OneOf::Right(_) => {
 7034                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7035                                                        return None
 7036                                                    }
 7037                                                };
 7038                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7039                                            }).collect::<Vec<_>>()
 7040                                        }
 7041                                    }).unwrap_or_default();
 7042
 7043                                WorkspaceSymbolsResult {
 7044                                    server_id,
 7045                                    lsp_adapter,
 7046                                    worktree: worktree_handle.downgrade(),
 7047                                    worktree_abs_path,
 7048                                    lsp_symbols,
 7049                                }
 7050                            }),
 7051                    );
 7052            }
 7053
 7054            cx.spawn(async move |this, cx| {
 7055                let responses = futures::future::join_all(requests).await;
 7056                let this = match this.upgrade() {
 7057                    Some(this) => this,
 7058                    None => return Ok(Vec::new()),
 7059                };
 7060
 7061                let mut symbols = Vec::new();
 7062                for result in responses {
 7063                    let core_symbols = this.update(cx, |this, cx| {
 7064                        result
 7065                            .lsp_symbols
 7066                            .into_iter()
 7067                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7068                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7069                                let source_worktree = result.worktree.upgrade()?;
 7070                                let source_worktree_id = source_worktree.read(cx).id();
 7071
 7072                                let path;
 7073                                let worktree;
 7074                                if let Some((tree, rel_path)) =
 7075                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7076                                {
 7077                                    worktree = tree;
 7078                                    path = rel_path;
 7079                                } else {
 7080                                    worktree = source_worktree;
 7081                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
 7082                                }
 7083
 7084                                let worktree_id = worktree.read(cx).id();
 7085                                let project_path = ProjectPath {
 7086                                    worktree_id,
 7087                                    path: path.into(),
 7088                                };
 7089                                let signature = this.symbol_signature(&project_path);
 7090                                Some(CoreSymbol {
 7091                                    source_language_server_id: result.server_id,
 7092                                    language_server_name: result.lsp_adapter.name.clone(),
 7093                                    source_worktree_id,
 7094                                    path: project_path,
 7095                                    kind: symbol_kind,
 7096                                    name: symbol_name,
 7097                                    range: range_from_lsp(symbol_location.range),
 7098                                    signature,
 7099                                })
 7100                            })
 7101                            .collect()
 7102                    })?;
 7103
 7104                    populate_labels_for_symbols(
 7105                        core_symbols,
 7106                        &language_registry,
 7107                        Some(result.lsp_adapter),
 7108                        &mut symbols,
 7109                    )
 7110                    .await;
 7111                }
 7112
 7113                Ok(symbols)
 7114            })
 7115        } else {
 7116            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7117        }
 7118    }
 7119
 7120    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7121        let mut summary = DiagnosticSummary::default();
 7122        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7123            summary.error_count += path_summary.error_count;
 7124            summary.warning_count += path_summary.warning_count;
 7125        }
 7126        summary
 7127    }
 7128
 7129    /// Returns the diagnostic summary for a specific project path.
 7130    pub fn diagnostic_summary_for_path(
 7131        &self,
 7132        project_path: &ProjectPath,
 7133        _: &App,
 7134    ) -> DiagnosticSummary {
 7135        if let Some(summaries) = self
 7136            .diagnostic_summaries
 7137            .get(&project_path.worktree_id)
 7138            .and_then(|map| map.get(&project_path.path))
 7139        {
 7140            let (error_count, warning_count) = summaries.iter().fold(
 7141                (0, 0),
 7142                |(error_count, warning_count), (_language_server_id, summary)| {
 7143                    (
 7144                        error_count + summary.error_count,
 7145                        warning_count + summary.warning_count,
 7146                    )
 7147                },
 7148            );
 7149
 7150            DiagnosticSummary {
 7151                error_count,
 7152                warning_count,
 7153            }
 7154        } else {
 7155            DiagnosticSummary::default()
 7156        }
 7157    }
 7158
 7159    pub fn diagnostic_summaries<'a>(
 7160        &'a self,
 7161        include_ignored: bool,
 7162        cx: &'a App,
 7163    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7164        self.worktree_store
 7165            .read(cx)
 7166            .visible_worktrees(cx)
 7167            .filter_map(|worktree| {
 7168                let worktree = worktree.read(cx);
 7169                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7170            })
 7171            .flat_map(move |(worktree, summaries)| {
 7172                let worktree_id = worktree.id();
 7173                summaries
 7174                    .iter()
 7175                    .filter(move |(path, _)| {
 7176                        include_ignored
 7177                            || worktree
 7178                                .entry_for_path(path.as_ref())
 7179                                .is_some_and(|entry| !entry.is_ignored)
 7180                    })
 7181                    .flat_map(move |(path, summaries)| {
 7182                        summaries.iter().map(move |(server_id, summary)| {
 7183                            (
 7184                                ProjectPath {
 7185                                    worktree_id,
 7186                                    path: path.clone(),
 7187                                },
 7188                                *server_id,
 7189                                *summary,
 7190                            )
 7191                        })
 7192                    })
 7193            })
 7194    }
 7195
 7196    pub fn on_buffer_edited(
 7197        &mut self,
 7198        buffer: Entity<Buffer>,
 7199        cx: &mut Context<Self>,
 7200    ) -> Option<()> {
 7201        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7202            Some(
 7203                self.as_local()?
 7204                    .language_servers_for_buffer(buffer, cx)
 7205                    .map(|i| i.1.clone())
 7206                    .collect(),
 7207            )
 7208        })?;
 7209
 7210        let buffer = buffer.read(cx);
 7211        let file = File::from_dyn(buffer.file())?;
 7212        let abs_path = file.as_local()?.abs_path(cx);
 7213        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7214        let next_snapshot = buffer.text_snapshot();
 7215        for language_server in language_servers {
 7216            let language_server = language_server.clone();
 7217
 7218            let buffer_snapshots = self
 7219                .as_local_mut()
 7220                .unwrap()
 7221                .buffer_snapshots
 7222                .get_mut(&buffer.remote_id())
 7223                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7224            let previous_snapshot = buffer_snapshots.last()?;
 7225
 7226            let build_incremental_change = || {
 7227                buffer
 7228                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7229                        previous_snapshot.snapshot.version(),
 7230                    )
 7231                    .map(|edit| {
 7232                        let edit_start = edit.new.start.0;
 7233                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7234                        let new_text = next_snapshot
 7235                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7236                            .collect();
 7237                        lsp::TextDocumentContentChangeEvent {
 7238                            range: Some(lsp::Range::new(
 7239                                point_to_lsp(edit_start),
 7240                                point_to_lsp(edit_end),
 7241                            )),
 7242                            range_length: None,
 7243                            text: new_text,
 7244                        }
 7245                    })
 7246                    .collect()
 7247            };
 7248
 7249            let document_sync_kind = language_server
 7250                .capabilities()
 7251                .text_document_sync
 7252                .as_ref()
 7253                .and_then(|sync| match sync {
 7254                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7255                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7256                });
 7257
 7258            let content_changes: Vec<_> = match document_sync_kind {
 7259                Some(lsp::TextDocumentSyncKind::FULL) => {
 7260                    vec![lsp::TextDocumentContentChangeEvent {
 7261                        range: None,
 7262                        range_length: None,
 7263                        text: next_snapshot.text(),
 7264                    }]
 7265                }
 7266                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7267                _ => {
 7268                    #[cfg(any(test, feature = "test-support"))]
 7269                    {
 7270                        build_incremental_change()
 7271                    }
 7272
 7273                    #[cfg(not(any(test, feature = "test-support")))]
 7274                    {
 7275                        continue;
 7276                    }
 7277                }
 7278            };
 7279
 7280            let next_version = previous_snapshot.version + 1;
 7281            buffer_snapshots.push(LspBufferSnapshot {
 7282                version: next_version,
 7283                snapshot: next_snapshot.clone(),
 7284            });
 7285
 7286            language_server
 7287                .notify::<lsp::notification::DidChangeTextDocument>(
 7288                    &lsp::DidChangeTextDocumentParams {
 7289                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7290                            uri.clone(),
 7291                            next_version,
 7292                        ),
 7293                        content_changes,
 7294                    },
 7295                )
 7296                .ok();
 7297            self.pull_workspace_diagnostics(language_server.server_id());
 7298        }
 7299
 7300        None
 7301    }
 7302
 7303    pub fn on_buffer_saved(
 7304        &mut self,
 7305        buffer: Entity<Buffer>,
 7306        cx: &mut Context<Self>,
 7307    ) -> Option<()> {
 7308        let file = File::from_dyn(buffer.read(cx).file())?;
 7309        let worktree_id = file.worktree_id(cx);
 7310        let abs_path = file.as_local()?.abs_path(cx);
 7311        let text_document = lsp::TextDocumentIdentifier {
 7312            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7313        };
 7314        let local = self.as_local()?;
 7315
 7316        for server in local.language_servers_for_worktree(worktree_id) {
 7317            if let Some(include_text) = include_text(server.as_ref()) {
 7318                let text = if include_text {
 7319                    Some(buffer.read(cx).text())
 7320                } else {
 7321                    None
 7322                };
 7323                server
 7324                    .notify::<lsp::notification::DidSaveTextDocument>(
 7325                        &lsp::DidSaveTextDocumentParams {
 7326                            text_document: text_document.clone(),
 7327                            text,
 7328                        },
 7329                    )
 7330                    .ok();
 7331            }
 7332        }
 7333
 7334        let language_servers = buffer.update(cx, |buffer, cx| {
 7335            local.language_server_ids_for_buffer(buffer, cx)
 7336        });
 7337        for language_server_id in language_servers {
 7338            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7339        }
 7340
 7341        None
 7342    }
 7343
 7344    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7345        maybe!(async move {
 7346            let mut refreshed_servers = HashSet::default();
 7347            let servers = lsp_store
 7348                .update(cx, |lsp_store, cx| {
 7349                    let local = lsp_store.as_local()?;
 7350
 7351                    let servers = local
 7352                        .language_server_ids
 7353                        .iter()
 7354                        .filter_map(|(seed, state)| {
 7355                            let worktree = lsp_store
 7356                                .worktree_store
 7357                                .read(cx)
 7358                                .worktree_for_id(seed.worktree_id, cx);
 7359                            let delegate: Arc<dyn LspAdapterDelegate> =
 7360                                worktree.map(|worktree| {
 7361                                    LocalLspAdapterDelegate::new(
 7362                                        local.languages.clone(),
 7363                                        &local.environment,
 7364                                        cx.weak_entity(),
 7365                                        &worktree,
 7366                                        local.http_client.clone(),
 7367                                        local.fs.clone(),
 7368                                        cx,
 7369                                    )
 7370                                })?;
 7371                            let server_id = state.id;
 7372
 7373                            let states = local.language_servers.get(&server_id)?;
 7374
 7375                            match states {
 7376                                LanguageServerState::Starting { .. } => None,
 7377                                LanguageServerState::Running {
 7378                                    adapter, server, ..
 7379                                } => {
 7380                                    let adapter = adapter.clone();
 7381                                    let server = server.clone();
 7382                                    refreshed_servers.insert(server.name());
 7383                                    let toolchain = seed.toolchain.clone();
 7384                                    Some(cx.spawn(async move |_, cx| {
 7385                                        let settings =
 7386                                            LocalLspStore::workspace_configuration_for_adapter(
 7387                                                adapter.adapter.clone(),
 7388                                                &delegate,
 7389                                                toolchain,
 7390                                                cx,
 7391                                            )
 7392                                            .await
 7393                                            .ok()?;
 7394                                        server
 7395                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7396                                                &lsp::DidChangeConfigurationParams { settings },
 7397                                            )
 7398                                            .ok()?;
 7399                                        Some(())
 7400                                    }))
 7401                                }
 7402                            }
 7403                        })
 7404                        .collect::<Vec<_>>();
 7405
 7406                    Some(servers)
 7407                })
 7408                .ok()
 7409                .flatten()?;
 7410
 7411            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7412            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7413            // to stop and unregister its language server wrapper.
 7414            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7415            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7416            let _: Vec<Option<()>> = join_all(servers).await;
 7417
 7418            Some(())
 7419        })
 7420        .await;
 7421    }
 7422
 7423    fn maintain_workspace_config(
 7424        external_refresh_requests: watch::Receiver<()>,
 7425        cx: &mut Context<Self>,
 7426    ) -> Task<Result<()>> {
 7427        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7428        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7429
 7430        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7431            *settings_changed_tx.borrow_mut() = ();
 7432        });
 7433
 7434        let mut joint_future =
 7435            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7436        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7437        // - 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).
 7438        // - 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.
 7439        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7440        // - 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,
 7441        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7442        cx.spawn(async move |this, cx| {
 7443            while let Some(()) = joint_future.next().await {
 7444                this.update(cx, |this, cx| {
 7445                    this.refresh_server_tree(cx);
 7446                })
 7447                .ok();
 7448
 7449                Self::refresh_workspace_configurations(&this, cx).await;
 7450            }
 7451
 7452            drop(settings_observation);
 7453            anyhow::Ok(())
 7454        })
 7455    }
 7456
 7457    pub fn language_servers_for_local_buffer<'a>(
 7458        &'a self,
 7459        buffer: &Buffer,
 7460        cx: &mut App,
 7461    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7462        let local = self.as_local();
 7463        let language_server_ids = local
 7464            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7465            .unwrap_or_default();
 7466
 7467        language_server_ids
 7468            .into_iter()
 7469            .filter_map(
 7470                move |server_id| match local?.language_servers.get(&server_id)? {
 7471                    LanguageServerState::Running {
 7472                        adapter, server, ..
 7473                    } => Some((adapter, server)),
 7474                    _ => None,
 7475                },
 7476            )
 7477    }
 7478
 7479    pub fn language_server_for_local_buffer<'a>(
 7480        &'a self,
 7481        buffer: &'a Buffer,
 7482        server_id: LanguageServerId,
 7483        cx: &'a mut App,
 7484    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7485        self.as_local()?
 7486            .language_servers_for_buffer(buffer, cx)
 7487            .find(|(_, s)| s.server_id() == server_id)
 7488    }
 7489
 7490    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7491        self.diagnostic_summaries.remove(&id_to_remove);
 7492        if let Some(local) = self.as_local_mut() {
 7493            let to_remove = local.remove_worktree(id_to_remove, cx);
 7494            for server in to_remove {
 7495                self.language_server_statuses.remove(&server);
 7496            }
 7497        }
 7498    }
 7499
 7500    pub fn shared(
 7501        &mut self,
 7502        project_id: u64,
 7503        downstream_client: AnyProtoClient,
 7504        _: &mut Context<Self>,
 7505    ) {
 7506        self.downstream_client = Some((downstream_client.clone(), project_id));
 7507
 7508        for (server_id, status) in &self.language_server_statuses {
 7509            if let Some(server) = self.language_server_for_id(*server_id) {
 7510                downstream_client
 7511                    .send(proto::StartLanguageServer {
 7512                        project_id,
 7513                        server: Some(proto::LanguageServer {
 7514                            id: server_id.to_proto(),
 7515                            name: status.name.to_string(),
 7516                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7517                        }),
 7518                        capabilities: serde_json::to_string(&server.capabilities())
 7519                            .expect("serializing server LSP capabilities"),
 7520                    })
 7521                    .log_err();
 7522            }
 7523        }
 7524    }
 7525
 7526    pub fn disconnected_from_host(&mut self) {
 7527        self.downstream_client.take();
 7528    }
 7529
 7530    pub fn disconnected_from_ssh_remote(&mut self) {
 7531        if let LspStoreMode::Remote(RemoteLspStore {
 7532            upstream_client, ..
 7533        }) = &mut self.mode
 7534        {
 7535            upstream_client.take();
 7536        }
 7537    }
 7538
 7539    pub(crate) fn set_language_server_statuses_from_proto(
 7540        &mut self,
 7541        project: WeakEntity<Project>,
 7542        language_servers: Vec<proto::LanguageServer>,
 7543        server_capabilities: Vec<String>,
 7544        cx: &mut Context<Self>,
 7545    ) {
 7546        let lsp_logs = cx
 7547            .try_global::<GlobalLogStore>()
 7548            .map(|lsp_store| lsp_store.0.clone());
 7549
 7550        self.language_server_statuses = language_servers
 7551            .into_iter()
 7552            .zip(server_capabilities)
 7553            .map(|(server, server_capabilities)| {
 7554                let server_id = LanguageServerId(server.id as usize);
 7555                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7556                    self.lsp_server_capabilities
 7557                        .insert(server_id, server_capabilities);
 7558                }
 7559
 7560                let name = LanguageServerName::from_proto(server.name);
 7561                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7562
 7563                if let Some(lsp_logs) = &lsp_logs {
 7564                    lsp_logs.update(cx, |lsp_logs, cx| {
 7565                        lsp_logs.add_language_server(
 7566                            // Only remote clients get their language servers set from proto
 7567                            LanguageServerKind::Remote {
 7568                                project: project.clone(),
 7569                            },
 7570                            server_id,
 7571                            Some(name.clone()),
 7572                            worktree,
 7573                            None,
 7574                            cx,
 7575                        );
 7576                    });
 7577                }
 7578
 7579                (
 7580                    server_id,
 7581                    LanguageServerStatus {
 7582                        name,
 7583                        pending_work: Default::default(),
 7584                        has_pending_diagnostic_updates: false,
 7585                        progress_tokens: Default::default(),
 7586                        worktree,
 7587                    },
 7588                )
 7589            })
 7590            .collect();
 7591    }
 7592
 7593    #[cfg(test)]
 7594    pub fn update_diagnostic_entries(
 7595        &mut self,
 7596        server_id: LanguageServerId,
 7597        abs_path: PathBuf,
 7598        result_id: Option<String>,
 7599        version: Option<i32>,
 7600        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7601        cx: &mut Context<Self>,
 7602    ) -> anyhow::Result<()> {
 7603        self.merge_diagnostic_entries(
 7604            vec![DocumentDiagnosticsUpdate {
 7605                diagnostics: DocumentDiagnostics {
 7606                    diagnostics,
 7607                    document_abs_path: abs_path,
 7608                    version,
 7609                },
 7610                result_id,
 7611                server_id,
 7612                disk_based_sources: Cow::Borrowed(&[]),
 7613            }],
 7614            |_, _, _| false,
 7615            cx,
 7616        )?;
 7617        Ok(())
 7618    }
 7619
 7620    pub fn merge_diagnostic_entries<'a>(
 7621        &mut self,
 7622        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7623        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7624        cx: &mut Context<Self>,
 7625    ) -> anyhow::Result<()> {
 7626        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7627        let mut updated_diagnostics_paths = HashMap::default();
 7628        for mut update in diagnostic_updates {
 7629            let abs_path = &update.diagnostics.document_abs_path;
 7630            let server_id = update.server_id;
 7631            let Some((worktree, relative_path)) =
 7632                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7633            else {
 7634                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7635                return Ok(());
 7636            };
 7637
 7638            let worktree_id = worktree.read(cx).id();
 7639            let project_path = ProjectPath {
 7640                worktree_id,
 7641                path: relative_path.into(),
 7642            };
 7643
 7644            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7645                let snapshot = buffer_handle.read(cx).snapshot();
 7646                let buffer = buffer_handle.read(cx);
 7647                let reused_diagnostics = buffer
 7648                    .buffer_diagnostics(Some(server_id))
 7649                    .iter()
 7650                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 7651                    .map(|v| {
 7652                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 7653                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 7654                        DiagnosticEntry {
 7655                            range: start..end,
 7656                            diagnostic: v.diagnostic.clone(),
 7657                        }
 7658                    })
 7659                    .collect::<Vec<_>>();
 7660
 7661                self.as_local_mut()
 7662                    .context("cannot merge diagnostics on a remote LspStore")?
 7663                    .update_buffer_diagnostics(
 7664                        &buffer_handle,
 7665                        server_id,
 7666                        update.result_id,
 7667                        update.diagnostics.version,
 7668                        update.diagnostics.diagnostics.clone(),
 7669                        reused_diagnostics.clone(),
 7670                        cx,
 7671                    )?;
 7672
 7673                update.diagnostics.diagnostics.extend(reused_diagnostics);
 7674            }
 7675
 7676            let updated = worktree.update(cx, |worktree, cx| {
 7677                self.update_worktree_diagnostics(
 7678                    worktree.id(),
 7679                    server_id,
 7680                    project_path.path.clone(),
 7681                    update.diagnostics.diagnostics,
 7682                    cx,
 7683                )
 7684            })?;
 7685            match updated {
 7686                ControlFlow::Continue(new_summary) => {
 7687                    if let Some((project_id, new_summary)) = new_summary {
 7688                        match &mut diagnostics_summary {
 7689                            Some(diagnostics_summary) => {
 7690                                diagnostics_summary
 7691                                    .more_summaries
 7692                                    .push(proto::DiagnosticSummary {
 7693                                        path: project_path.path.as_ref().to_proto(),
 7694                                        language_server_id: server_id.0 as u64,
 7695                                        error_count: new_summary.error_count,
 7696                                        warning_count: new_summary.warning_count,
 7697                                    })
 7698                            }
 7699                            None => {
 7700                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 7701                                    project_id,
 7702                                    worktree_id: worktree_id.to_proto(),
 7703                                    summary: Some(proto::DiagnosticSummary {
 7704                                        path: project_path.path.as_ref().to_proto(),
 7705                                        language_server_id: server_id.0 as u64,
 7706                                        error_count: new_summary.error_count,
 7707                                        warning_count: new_summary.warning_count,
 7708                                    }),
 7709                                    more_summaries: Vec::new(),
 7710                                })
 7711                            }
 7712                        }
 7713                    }
 7714                    updated_diagnostics_paths
 7715                        .entry(server_id)
 7716                        .or_insert_with(Vec::new)
 7717                        .push(project_path);
 7718                }
 7719                ControlFlow::Break(()) => {}
 7720            }
 7721        }
 7722
 7723        if let Some((diagnostics_summary, (downstream_client, _))) =
 7724            diagnostics_summary.zip(self.downstream_client.as_ref())
 7725        {
 7726            downstream_client.send(diagnostics_summary).log_err();
 7727        }
 7728        for (server_id, paths) in updated_diagnostics_paths {
 7729            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 7730        }
 7731        Ok(())
 7732    }
 7733
 7734    fn update_worktree_diagnostics(
 7735        &mut self,
 7736        worktree_id: WorktreeId,
 7737        server_id: LanguageServerId,
 7738        path_in_worktree: Arc<Path>,
 7739        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7740        _: &mut Context<Worktree>,
 7741    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 7742        let local = match &mut self.mode {
 7743            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 7744            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 7745        };
 7746
 7747        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 7748        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 7749        let summaries_by_server_id = summaries_for_tree
 7750            .entry(path_in_worktree.clone())
 7751            .or_default();
 7752
 7753        let old_summary = summaries_by_server_id
 7754            .remove(&server_id)
 7755            .unwrap_or_default();
 7756
 7757        let new_summary = DiagnosticSummary::new(&diagnostics);
 7758        if new_summary.is_empty() {
 7759            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 7760            {
 7761                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7762                    diagnostics_by_server_id.remove(ix);
 7763                }
 7764                if diagnostics_by_server_id.is_empty() {
 7765                    diagnostics_for_tree.remove(&path_in_worktree);
 7766                }
 7767            }
 7768        } else {
 7769            summaries_by_server_id.insert(server_id, new_summary);
 7770            let diagnostics_by_server_id = diagnostics_for_tree
 7771                .entry(path_in_worktree.clone())
 7772                .or_default();
 7773            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7774                Ok(ix) => {
 7775                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 7776                }
 7777                Err(ix) => {
 7778                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 7779                }
 7780            }
 7781        }
 7782
 7783        if !old_summary.is_empty() || !new_summary.is_empty() {
 7784            if let Some((_, project_id)) = &self.downstream_client {
 7785                Ok(ControlFlow::Continue(Some((
 7786                    *project_id,
 7787                    proto::DiagnosticSummary {
 7788                        path: path_in_worktree.to_proto(),
 7789                        language_server_id: server_id.0 as u64,
 7790                        error_count: new_summary.error_count as u32,
 7791                        warning_count: new_summary.warning_count as u32,
 7792                    },
 7793                ))))
 7794            } else {
 7795                Ok(ControlFlow::Continue(None))
 7796            }
 7797        } else {
 7798            Ok(ControlFlow::Break(()))
 7799        }
 7800    }
 7801
 7802    pub fn open_buffer_for_symbol(
 7803        &mut self,
 7804        symbol: &Symbol,
 7805        cx: &mut Context<Self>,
 7806    ) -> Task<Result<Entity<Buffer>>> {
 7807        if let Some((client, project_id)) = self.upstream_client() {
 7808            let request = client.request(proto::OpenBufferForSymbol {
 7809                project_id,
 7810                symbol: Some(Self::serialize_symbol(symbol)),
 7811            });
 7812            cx.spawn(async move |this, cx| {
 7813                let response = request.await?;
 7814                let buffer_id = BufferId::new(response.buffer_id)?;
 7815                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 7816                    .await
 7817            })
 7818        } else if let Some(local) = self.as_local() {
 7819            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 7820                seed.worktree_id == symbol.source_worktree_id
 7821                    && state.id == symbol.source_language_server_id
 7822                    && symbol.language_server_name == seed.name
 7823            });
 7824            if !is_valid {
 7825                return Task::ready(Err(anyhow!(
 7826                    "language server for worktree and language not found"
 7827                )));
 7828            };
 7829
 7830            let worktree_abs_path = if let Some(worktree_abs_path) = self
 7831                .worktree_store
 7832                .read(cx)
 7833                .worktree_for_id(symbol.path.worktree_id, cx)
 7834                .map(|worktree| worktree.read(cx).abs_path())
 7835            {
 7836                worktree_abs_path
 7837            } else {
 7838                return Task::ready(Err(anyhow!("worktree not found for symbol")));
 7839            };
 7840
 7841            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
 7842            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 7843                uri
 7844            } else {
 7845                return Task::ready(Err(anyhow!("invalid symbol path")));
 7846            };
 7847
 7848            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 7849        } else {
 7850            Task::ready(Err(anyhow!("no upstream client or local store")))
 7851        }
 7852    }
 7853
 7854    pub(crate) fn open_local_buffer_via_lsp(
 7855        &mut self,
 7856        abs_path: lsp::Uri,
 7857        language_server_id: LanguageServerId,
 7858        cx: &mut Context<Self>,
 7859    ) -> Task<Result<Entity<Buffer>>> {
 7860        cx.spawn(async move |lsp_store, cx| {
 7861            // Escape percent-encoded string.
 7862            let current_scheme = abs_path.scheme().to_owned();
 7863            // Uri is immutable, so we can't modify the scheme
 7864
 7865            let abs_path = abs_path
 7866                .to_file_path()
 7867                .map_err(|()| anyhow!("can't convert URI to path"))?;
 7868            let p = abs_path.clone();
 7869            let yarn_worktree = lsp_store
 7870                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 7871                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 7872                        cx.spawn(async move |this, cx| {
 7873                            let t = this
 7874                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 7875                                .ok()?;
 7876                            t.await
 7877                        })
 7878                    }),
 7879                    None => Task::ready(None),
 7880                })?
 7881                .await;
 7882            let (worktree_root_target, known_relative_path) =
 7883                if let Some((zip_root, relative_path)) = yarn_worktree {
 7884                    (zip_root, Some(relative_path))
 7885                } else {
 7886                    (Arc::<Path>::from(abs_path.as_path()), None)
 7887                };
 7888            let (worktree, relative_path) = if let Some(result) =
 7889                lsp_store.update(cx, |lsp_store, cx| {
 7890                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7891                        worktree_store.find_worktree(&worktree_root_target, cx)
 7892                    })
 7893                })? {
 7894                let relative_path =
 7895                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
 7896                (result.0, relative_path)
 7897            } else {
 7898                let worktree = lsp_store
 7899                    .update(cx, |lsp_store, cx| {
 7900                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7901                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 7902                        })
 7903                    })?
 7904                    .await?;
 7905                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 7906                    lsp_store
 7907                        .update(cx, |lsp_store, cx| {
 7908                            if let Some(local) = lsp_store.as_local_mut() {
 7909                                local.register_language_server_for_invisible_worktree(
 7910                                    &worktree,
 7911                                    language_server_id,
 7912                                    cx,
 7913                                )
 7914                            }
 7915                        })
 7916                        .ok();
 7917                }
 7918                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 7919                let relative_path = if let Some(known_path) = known_relative_path {
 7920                    known_path
 7921                } else {
 7922                    abs_path.strip_prefix(worktree_root)?.into()
 7923                };
 7924                (worktree, relative_path)
 7925            };
 7926            let project_path = ProjectPath {
 7927                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 7928                path: relative_path,
 7929            };
 7930            lsp_store
 7931                .update(cx, |lsp_store, cx| {
 7932                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 7933                        buffer_store.open_buffer(project_path, cx)
 7934                    })
 7935                })?
 7936                .await
 7937        })
 7938    }
 7939
 7940    fn request_multiple_lsp_locally<P, R>(
 7941        &mut self,
 7942        buffer: &Entity<Buffer>,
 7943        position: Option<P>,
 7944        request: R,
 7945        cx: &mut Context<Self>,
 7946    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 7947    where
 7948        P: ToOffset,
 7949        R: LspCommand + Clone,
 7950        <R::LspRequest as lsp::request::Request>::Result: Send,
 7951        <R::LspRequest as lsp::request::Request>::Params: Send,
 7952    {
 7953        let Some(local) = self.as_local() else {
 7954            return Task::ready(Vec::new());
 7955        };
 7956
 7957        let snapshot = buffer.read(cx).snapshot();
 7958        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 7959
 7960        let server_ids = buffer.update(cx, |buffer, cx| {
 7961            local
 7962                .language_servers_for_buffer(buffer, cx)
 7963                .filter(|(adapter, _)| {
 7964                    scope
 7965                        .as_ref()
 7966                        .map(|scope| scope.language_allowed(&adapter.name))
 7967                        .unwrap_or(true)
 7968                })
 7969                .map(|(_, server)| server.server_id())
 7970                .filter(|server_id| {
 7971                    self.as_local().is_none_or(|local| {
 7972                        local
 7973                            .buffers_opened_in_servers
 7974                            .get(&snapshot.remote_id())
 7975                            .is_some_and(|servers| servers.contains(server_id))
 7976                    })
 7977                })
 7978                .collect::<Vec<_>>()
 7979        });
 7980
 7981        let mut response_results = server_ids
 7982            .into_iter()
 7983            .map(|server_id| {
 7984                let task = self.request_lsp(
 7985                    buffer.clone(),
 7986                    LanguageServerToQuery::Other(server_id),
 7987                    request.clone(),
 7988                    cx,
 7989                );
 7990                async move { (server_id, task.await) }
 7991            })
 7992            .collect::<FuturesUnordered<_>>();
 7993
 7994        cx.background_spawn(async move {
 7995            let mut responses = Vec::with_capacity(response_results.len());
 7996            while let Some((server_id, response_result)) = response_results.next().await {
 7997                if let Some(response) = response_result.log_err() {
 7998                    responses.push((server_id, response));
 7999                }
 8000            }
 8001            responses
 8002        })
 8003    }
 8004
 8005    async fn handle_lsp_command<T: LspCommand>(
 8006        this: Entity<Self>,
 8007        envelope: TypedEnvelope<T::ProtoRequest>,
 8008        mut cx: AsyncApp,
 8009    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8010    where
 8011        <T::LspRequest as lsp::request::Request>::Params: Send,
 8012        <T::LspRequest as lsp::request::Request>::Result: Send,
 8013    {
 8014        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8015        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8016        let buffer_handle = this.update(&mut cx, |this, cx| {
 8017            this.buffer_store.read(cx).get_existing(buffer_id)
 8018        })??;
 8019        let request = T::from_proto(
 8020            envelope.payload,
 8021            this.clone(),
 8022            buffer_handle.clone(),
 8023            cx.clone(),
 8024        )
 8025        .await?;
 8026        let response = this
 8027            .update(&mut cx, |this, cx| {
 8028                this.request_lsp(
 8029                    buffer_handle.clone(),
 8030                    LanguageServerToQuery::FirstCapable,
 8031                    request,
 8032                    cx,
 8033                )
 8034            })?
 8035            .await?;
 8036        this.update(&mut cx, |this, cx| {
 8037            Ok(T::response_to_proto(
 8038                response,
 8039                this,
 8040                sender_id,
 8041                &buffer_handle.read(cx).version(),
 8042                cx,
 8043            ))
 8044        })?
 8045    }
 8046
 8047    async fn handle_lsp_query(
 8048        lsp_store: Entity<Self>,
 8049        envelope: TypedEnvelope<proto::LspQuery>,
 8050        mut cx: AsyncApp,
 8051    ) -> Result<proto::Ack> {
 8052        use proto::lsp_query::Request;
 8053        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8054        let lsp_query = envelope.payload;
 8055        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8056        match lsp_query.request.context("invalid LSP query request")? {
 8057            Request::GetReferences(get_references) => {
 8058                let position = get_references.position.clone().and_then(deserialize_anchor);
 8059                Self::query_lsp_locally::<GetReferences>(
 8060                    lsp_store,
 8061                    sender_id,
 8062                    lsp_request_id,
 8063                    get_references,
 8064                    position,
 8065                    cx.clone(),
 8066                )
 8067                .await?;
 8068            }
 8069            Request::GetDocumentColor(get_document_color) => {
 8070                Self::query_lsp_locally::<GetDocumentColor>(
 8071                    lsp_store,
 8072                    sender_id,
 8073                    lsp_request_id,
 8074                    get_document_color,
 8075                    None,
 8076                    cx.clone(),
 8077                )
 8078                .await?;
 8079            }
 8080            Request::GetHover(get_hover) => {
 8081                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8082                Self::query_lsp_locally::<GetHover>(
 8083                    lsp_store,
 8084                    sender_id,
 8085                    lsp_request_id,
 8086                    get_hover,
 8087                    position,
 8088                    cx.clone(),
 8089                )
 8090                .await?;
 8091            }
 8092            Request::GetCodeActions(get_code_actions) => {
 8093                Self::query_lsp_locally::<GetCodeActions>(
 8094                    lsp_store,
 8095                    sender_id,
 8096                    lsp_request_id,
 8097                    get_code_actions,
 8098                    None,
 8099                    cx.clone(),
 8100                )
 8101                .await?;
 8102            }
 8103            Request::GetSignatureHelp(get_signature_help) => {
 8104                let position = get_signature_help
 8105                    .position
 8106                    .clone()
 8107                    .and_then(deserialize_anchor);
 8108                Self::query_lsp_locally::<GetSignatureHelp>(
 8109                    lsp_store,
 8110                    sender_id,
 8111                    lsp_request_id,
 8112                    get_signature_help,
 8113                    position,
 8114                    cx.clone(),
 8115                )
 8116                .await?;
 8117            }
 8118            Request::GetCodeLens(get_code_lens) => {
 8119                Self::query_lsp_locally::<GetCodeLens>(
 8120                    lsp_store,
 8121                    sender_id,
 8122                    lsp_request_id,
 8123                    get_code_lens,
 8124                    None,
 8125                    cx.clone(),
 8126                )
 8127                .await?;
 8128            }
 8129            Request::GetDefinition(get_definition) => {
 8130                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8131                Self::query_lsp_locally::<GetDefinitions>(
 8132                    lsp_store,
 8133                    sender_id,
 8134                    lsp_request_id,
 8135                    get_definition,
 8136                    position,
 8137                    cx.clone(),
 8138                )
 8139                .await?;
 8140            }
 8141            Request::GetDeclaration(get_declaration) => {
 8142                let position = get_declaration
 8143                    .position
 8144                    .clone()
 8145                    .and_then(deserialize_anchor);
 8146                Self::query_lsp_locally::<GetDeclarations>(
 8147                    lsp_store,
 8148                    sender_id,
 8149                    lsp_request_id,
 8150                    get_declaration,
 8151                    position,
 8152                    cx.clone(),
 8153                )
 8154                .await?;
 8155            }
 8156            Request::GetTypeDefinition(get_type_definition) => {
 8157                let position = get_type_definition
 8158                    .position
 8159                    .clone()
 8160                    .and_then(deserialize_anchor);
 8161                Self::query_lsp_locally::<GetTypeDefinitions>(
 8162                    lsp_store,
 8163                    sender_id,
 8164                    lsp_request_id,
 8165                    get_type_definition,
 8166                    position,
 8167                    cx.clone(),
 8168                )
 8169                .await?;
 8170            }
 8171            Request::GetImplementation(get_implementation) => {
 8172                let position = get_implementation
 8173                    .position
 8174                    .clone()
 8175                    .and_then(deserialize_anchor);
 8176                Self::query_lsp_locally::<GetImplementations>(
 8177                    lsp_store,
 8178                    sender_id,
 8179                    lsp_request_id,
 8180                    get_implementation,
 8181                    position,
 8182                    cx.clone(),
 8183                )
 8184                .await?;
 8185            }
 8186            // Diagnostics pull synchronizes internally via the buffer state, and cannot be handled generically as the other requests.
 8187            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8188                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8189                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8190                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8191                    this.buffer_store.read(cx).get_existing(buffer_id)
 8192                })??;
 8193                buffer
 8194                    .update(&mut cx, |buffer, _| {
 8195                        buffer.wait_for_version(version.clone())
 8196                    })?
 8197                    .await?;
 8198                lsp_store.update(&mut cx, |lsp_store, cx| {
 8199                    let existing_queries = lsp_store
 8200                        .running_lsp_requests
 8201                        .entry(TypeId::of::<GetDocumentDiagnostics>())
 8202                        .or_default();
 8203                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8204                    ) || buffer.read(cx).version.changed_since(&existing_queries.0)
 8205                    {
 8206                        existing_queries.1.clear();
 8207                    }
 8208                    existing_queries.1.insert(
 8209                        lsp_request_id,
 8210                        cx.spawn(async move |lsp_store, cx| {
 8211                            let diagnostics_pull = lsp_store
 8212                                .update(cx, |lsp_store, cx| {
 8213                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8214                                })
 8215                                .ok();
 8216                            if let Some(diagnostics_pull) = diagnostics_pull {
 8217                                match diagnostics_pull.await {
 8218                                    Ok(()) => {}
 8219                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8220                                };
 8221                            }
 8222                        }),
 8223                    );
 8224                })?;
 8225            }
 8226        }
 8227        Ok(proto::Ack {})
 8228    }
 8229
 8230    async fn handle_lsp_query_response(
 8231        lsp_store: Entity<Self>,
 8232        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8233        cx: AsyncApp,
 8234    ) -> Result<()> {
 8235        lsp_store.read_with(&cx, |lsp_store, _| {
 8236            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8237                upstream_client.handle_lsp_response(envelope.clone());
 8238            }
 8239        })?;
 8240        Ok(())
 8241    }
 8242
 8243    async fn handle_apply_code_action(
 8244        this: Entity<Self>,
 8245        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8246        mut cx: AsyncApp,
 8247    ) -> Result<proto::ApplyCodeActionResponse> {
 8248        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8249        let action =
 8250            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8251        let apply_code_action = this.update(&mut cx, |this, cx| {
 8252            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8253            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8254            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8255        })??;
 8256
 8257        let project_transaction = apply_code_action.await?;
 8258        let project_transaction = this.update(&mut cx, |this, cx| {
 8259            this.buffer_store.update(cx, |buffer_store, cx| {
 8260                buffer_store.serialize_project_transaction_for_peer(
 8261                    project_transaction,
 8262                    sender_id,
 8263                    cx,
 8264                )
 8265            })
 8266        })?;
 8267        Ok(proto::ApplyCodeActionResponse {
 8268            transaction: Some(project_transaction),
 8269        })
 8270    }
 8271
 8272    async fn handle_register_buffer_with_language_servers(
 8273        this: Entity<Self>,
 8274        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8275        mut cx: AsyncApp,
 8276    ) -> Result<proto::Ack> {
 8277        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8278        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8279        this.update(&mut cx, |this, cx| {
 8280            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8281                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8282                    project_id: upstream_project_id,
 8283                    buffer_id: buffer_id.to_proto(),
 8284                    only_servers: envelope.payload.only_servers,
 8285                });
 8286            }
 8287
 8288            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8289                anyhow::bail!("buffer is not open");
 8290            };
 8291
 8292            let handle = this.register_buffer_with_language_servers(
 8293                &buffer,
 8294                envelope
 8295                    .payload
 8296                    .only_servers
 8297                    .into_iter()
 8298                    .filter_map(|selector| {
 8299                        Some(match selector.selector? {
 8300                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8301                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8302                            }
 8303                            proto::language_server_selector::Selector::Name(name) => {
 8304                                LanguageServerSelector::Name(LanguageServerName(
 8305                                    SharedString::from(name),
 8306                                ))
 8307                            }
 8308                        })
 8309                    })
 8310                    .collect(),
 8311                false,
 8312                cx,
 8313            );
 8314            this.buffer_store().update(cx, |buffer_store, _| {
 8315                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8316            });
 8317
 8318            Ok(())
 8319        })??;
 8320        Ok(proto::Ack {})
 8321    }
 8322
 8323    async fn handle_rename_project_entry(
 8324        this: Entity<Self>,
 8325        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8326        mut cx: AsyncApp,
 8327    ) -> Result<proto::ProjectEntryResponse> {
 8328        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8329        let (worktree_id, worktree, old_path, is_dir) = this
 8330            .update(&mut cx, |this, cx| {
 8331                this.worktree_store
 8332                    .read(cx)
 8333                    .worktree_and_entry_for_id(entry_id, cx)
 8334                    .map(|(worktree, entry)| {
 8335                        (
 8336                            worktree.read(cx).id(),
 8337                            worktree,
 8338                            entry.path.clone(),
 8339                            entry.is_dir(),
 8340                        )
 8341                    })
 8342            })?
 8343            .context("worktree not found")?;
 8344        let (old_abs_path, new_abs_path) = {
 8345            let root_path = worktree.read_with(&cx, |this, _| this.abs_path())?;
 8346            let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
 8347            (root_path.join(&old_path), root_path.join(&new_path))
 8348        };
 8349
 8350        let _transaction = Self::will_rename_entry(
 8351            this.downgrade(),
 8352            worktree_id,
 8353            &old_abs_path,
 8354            &new_abs_path,
 8355            is_dir,
 8356            cx.clone(),
 8357        )
 8358        .await;
 8359        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
 8360        this.read_with(&cx, |this, _| {
 8361            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
 8362        })
 8363        .ok();
 8364        response
 8365    }
 8366
 8367    async fn handle_update_diagnostic_summary(
 8368        this: Entity<Self>,
 8369        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8370        mut cx: AsyncApp,
 8371    ) -> Result<()> {
 8372        this.update(&mut cx, |lsp_store, cx| {
 8373            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8374            let mut updated_diagnostics_paths = HashMap::default();
 8375            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8376            for message_summary in envelope
 8377                .payload
 8378                .summary
 8379                .into_iter()
 8380                .chain(envelope.payload.more_summaries)
 8381            {
 8382                let project_path = ProjectPath {
 8383                    worktree_id,
 8384                    path: Arc::<Path>::from_proto(message_summary.path),
 8385                };
 8386                let path = project_path.path.clone();
 8387                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8388                let summary = DiagnosticSummary {
 8389                    error_count: message_summary.error_count as usize,
 8390                    warning_count: message_summary.warning_count as usize,
 8391                };
 8392
 8393                if summary.is_empty() {
 8394                    if let Some(worktree_summaries) =
 8395                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8396                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8397                    {
 8398                        summaries.remove(&server_id);
 8399                        if summaries.is_empty() {
 8400                            worktree_summaries.remove(&path);
 8401                        }
 8402                    }
 8403                } else {
 8404                    lsp_store
 8405                        .diagnostic_summaries
 8406                        .entry(worktree_id)
 8407                        .or_default()
 8408                        .entry(path)
 8409                        .or_default()
 8410                        .insert(server_id, summary);
 8411                }
 8412
 8413                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8414                    match &mut diagnostics_summary {
 8415                        Some(diagnostics_summary) => {
 8416                            diagnostics_summary
 8417                                .more_summaries
 8418                                .push(proto::DiagnosticSummary {
 8419                                    path: project_path.path.as_ref().to_proto(),
 8420                                    language_server_id: server_id.0 as u64,
 8421                                    error_count: summary.error_count as u32,
 8422                                    warning_count: summary.warning_count as u32,
 8423                                })
 8424                        }
 8425                        None => {
 8426                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8427                                project_id: *project_id,
 8428                                worktree_id: worktree_id.to_proto(),
 8429                                summary: Some(proto::DiagnosticSummary {
 8430                                    path: project_path.path.as_ref().to_proto(),
 8431                                    language_server_id: server_id.0 as u64,
 8432                                    error_count: summary.error_count as u32,
 8433                                    warning_count: summary.warning_count as u32,
 8434                                }),
 8435                                more_summaries: Vec::new(),
 8436                            })
 8437                        }
 8438                    }
 8439                }
 8440                updated_diagnostics_paths
 8441                    .entry(server_id)
 8442                    .or_insert_with(Vec::new)
 8443                    .push(project_path);
 8444            }
 8445
 8446            if let Some((diagnostics_summary, (downstream_client, _))) =
 8447                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8448            {
 8449                downstream_client.send(diagnostics_summary).log_err();
 8450            }
 8451            for (server_id, paths) in updated_diagnostics_paths {
 8452                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8453            }
 8454            Ok(())
 8455        })?
 8456    }
 8457
 8458    async fn handle_start_language_server(
 8459        lsp_store: Entity<Self>,
 8460        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8461        mut cx: AsyncApp,
 8462    ) -> Result<()> {
 8463        let server = envelope.payload.server.context("invalid server")?;
 8464        let server_capabilities =
 8465            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8466                .with_context(|| {
 8467                    format!(
 8468                        "incorrect server capabilities {}",
 8469                        envelope.payload.capabilities
 8470                    )
 8471                })?;
 8472        lsp_store.update(&mut cx, |lsp_store, cx| {
 8473            let server_id = LanguageServerId(server.id as usize);
 8474            let server_name = LanguageServerName::from_proto(server.name.clone());
 8475            lsp_store
 8476                .lsp_server_capabilities
 8477                .insert(server_id, server_capabilities);
 8478            lsp_store.language_server_statuses.insert(
 8479                server_id,
 8480                LanguageServerStatus {
 8481                    name: server_name.clone(),
 8482                    pending_work: Default::default(),
 8483                    has_pending_diagnostic_updates: false,
 8484                    progress_tokens: Default::default(),
 8485                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8486                },
 8487            );
 8488            cx.emit(LspStoreEvent::LanguageServerAdded(
 8489                server_id,
 8490                server_name,
 8491                server.worktree_id.map(WorktreeId::from_proto),
 8492            ));
 8493            cx.notify();
 8494        })?;
 8495        Ok(())
 8496    }
 8497
 8498    async fn handle_update_language_server(
 8499        lsp_store: Entity<Self>,
 8500        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8501        mut cx: AsyncApp,
 8502    ) -> Result<()> {
 8503        lsp_store.update(&mut cx, |lsp_store, cx| {
 8504            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8505
 8506            match envelope.payload.variant.context("invalid variant")? {
 8507                proto::update_language_server::Variant::WorkStart(payload) => {
 8508                    lsp_store.on_lsp_work_start(
 8509                        language_server_id,
 8510                        payload.token,
 8511                        LanguageServerProgress {
 8512                            title: payload.title,
 8513                            is_disk_based_diagnostics_progress: false,
 8514                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8515                            message: payload.message,
 8516                            percentage: payload.percentage.map(|p| p as usize),
 8517                            last_update_at: cx.background_executor().now(),
 8518                        },
 8519                        cx,
 8520                    );
 8521                }
 8522                proto::update_language_server::Variant::WorkProgress(payload) => {
 8523                    lsp_store.on_lsp_work_progress(
 8524                        language_server_id,
 8525                        payload.token,
 8526                        LanguageServerProgress {
 8527                            title: None,
 8528                            is_disk_based_diagnostics_progress: false,
 8529                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8530                            message: payload.message,
 8531                            percentage: payload.percentage.map(|p| p as usize),
 8532                            last_update_at: cx.background_executor().now(),
 8533                        },
 8534                        cx,
 8535                    );
 8536                }
 8537
 8538                proto::update_language_server::Variant::WorkEnd(payload) => {
 8539                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8540                }
 8541
 8542                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8543                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8544                }
 8545
 8546                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8547                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8548                }
 8549
 8550                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8551                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8552                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8553                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 8554                        language_server_id,
 8555                        name: envelope
 8556                            .payload
 8557                            .server_name
 8558                            .map(SharedString::new)
 8559                            .map(LanguageServerName),
 8560                        message: non_lsp,
 8561                    });
 8562                }
 8563            }
 8564
 8565            Ok(())
 8566        })?
 8567    }
 8568
 8569    async fn handle_language_server_log(
 8570        this: Entity<Self>,
 8571        envelope: TypedEnvelope<proto::LanguageServerLog>,
 8572        mut cx: AsyncApp,
 8573    ) -> Result<()> {
 8574        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8575        let log_type = envelope
 8576            .payload
 8577            .log_type
 8578            .map(LanguageServerLogType::from_proto)
 8579            .context("invalid language server log type")?;
 8580
 8581        let message = envelope.payload.message;
 8582
 8583        this.update(&mut cx, |_, cx| {
 8584            cx.emit(LspStoreEvent::LanguageServerLog(
 8585                language_server_id,
 8586                log_type,
 8587                message,
 8588            ));
 8589        })
 8590    }
 8591
 8592    async fn handle_lsp_ext_cancel_flycheck(
 8593        lsp_store: Entity<Self>,
 8594        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 8595        cx: AsyncApp,
 8596    ) -> Result<proto::Ack> {
 8597        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8598        lsp_store.read_with(&cx, |lsp_store, _| {
 8599            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8600                server
 8601                    .notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())
 8602                    .context("handling lsp ext cancel flycheck")
 8603            } else {
 8604                anyhow::Ok(())
 8605            }
 8606        })??;
 8607
 8608        Ok(proto::Ack {})
 8609    }
 8610
 8611    async fn handle_lsp_ext_run_flycheck(
 8612        lsp_store: Entity<Self>,
 8613        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 8614        mut cx: AsyncApp,
 8615    ) -> Result<proto::Ack> {
 8616        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8617        lsp_store.update(&mut cx, |lsp_store, cx| {
 8618            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8619                let text_document = if envelope.payload.current_file_only {
 8620                    let buffer_id = envelope
 8621                        .payload
 8622                        .buffer_id
 8623                        .map(|id| BufferId::new(id))
 8624                        .transpose()?;
 8625                    buffer_id
 8626                        .and_then(|buffer_id| {
 8627                            lsp_store
 8628                                .buffer_store()
 8629                                .read(cx)
 8630                                .get(buffer_id)
 8631                                .and_then(|buffer| {
 8632                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 8633                                })
 8634                                .map(|path| make_text_document_identifier(&path))
 8635                        })
 8636                        .transpose()?
 8637                } else {
 8638                    None
 8639                };
 8640                server
 8641                    .notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 8642                        &lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 8643                    )
 8644                    .context("handling lsp ext run flycheck")
 8645            } else {
 8646                anyhow::Ok(())
 8647            }
 8648        })??;
 8649
 8650        Ok(proto::Ack {})
 8651    }
 8652
 8653    async fn handle_lsp_ext_clear_flycheck(
 8654        lsp_store: Entity<Self>,
 8655        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 8656        cx: AsyncApp,
 8657    ) -> Result<proto::Ack> {
 8658        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8659        lsp_store.read_with(&cx, |lsp_store, _| {
 8660            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8661                server
 8662                    .notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())
 8663                    .context("handling lsp ext clear flycheck")
 8664            } else {
 8665                anyhow::Ok(())
 8666            }
 8667        })??;
 8668
 8669        Ok(proto::Ack {})
 8670    }
 8671
 8672    pub fn disk_based_diagnostics_started(
 8673        &mut self,
 8674        language_server_id: LanguageServerId,
 8675        cx: &mut Context<Self>,
 8676    ) {
 8677        if let Some(language_server_status) =
 8678            self.language_server_statuses.get_mut(&language_server_id)
 8679        {
 8680            language_server_status.has_pending_diagnostic_updates = true;
 8681        }
 8682
 8683        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 8684        cx.emit(LspStoreEvent::LanguageServerUpdate {
 8685            language_server_id,
 8686            name: self
 8687                .language_server_adapter_for_id(language_server_id)
 8688                .map(|adapter| adapter.name()),
 8689            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 8690                Default::default(),
 8691            ),
 8692        })
 8693    }
 8694
 8695    pub fn disk_based_diagnostics_finished(
 8696        &mut self,
 8697        language_server_id: LanguageServerId,
 8698        cx: &mut Context<Self>,
 8699    ) {
 8700        if let Some(language_server_status) =
 8701            self.language_server_statuses.get_mut(&language_server_id)
 8702        {
 8703            language_server_status.has_pending_diagnostic_updates = false;
 8704        }
 8705
 8706        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 8707        cx.emit(LspStoreEvent::LanguageServerUpdate {
 8708            language_server_id,
 8709            name: self
 8710                .language_server_adapter_for_id(language_server_id)
 8711                .map(|adapter| adapter.name()),
 8712            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 8713                Default::default(),
 8714            ),
 8715        })
 8716    }
 8717
 8718    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 8719    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 8720    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 8721    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 8722    // the language server might take some time to publish diagnostics.
 8723    fn simulate_disk_based_diagnostics_events_if_needed(
 8724        &mut self,
 8725        language_server_id: LanguageServerId,
 8726        cx: &mut Context<Self>,
 8727    ) {
 8728        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 8729
 8730        let Some(LanguageServerState::Running {
 8731            simulate_disk_based_diagnostics_completion,
 8732            adapter,
 8733            ..
 8734        }) = self
 8735            .as_local_mut()
 8736            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 8737        else {
 8738            return;
 8739        };
 8740
 8741        if adapter.disk_based_diagnostics_progress_token.is_some() {
 8742            return;
 8743        }
 8744
 8745        let prev_task =
 8746            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 8747                cx.background_executor()
 8748                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 8749                    .await;
 8750
 8751                this.update(cx, |this, cx| {
 8752                    this.disk_based_diagnostics_finished(language_server_id, cx);
 8753
 8754                    if let Some(LanguageServerState::Running {
 8755                        simulate_disk_based_diagnostics_completion,
 8756                        ..
 8757                    }) = this.as_local_mut().and_then(|local_store| {
 8758                        local_store.language_servers.get_mut(&language_server_id)
 8759                    }) {
 8760                        *simulate_disk_based_diagnostics_completion = None;
 8761                    }
 8762                })
 8763                .ok();
 8764            }));
 8765
 8766        if prev_task.is_none() {
 8767            self.disk_based_diagnostics_started(language_server_id, cx);
 8768        }
 8769    }
 8770
 8771    pub fn language_server_statuses(
 8772        &self,
 8773    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 8774        self.language_server_statuses
 8775            .iter()
 8776            .map(|(key, value)| (*key, value))
 8777    }
 8778
 8779    pub(super) fn did_rename_entry(
 8780        &self,
 8781        worktree_id: WorktreeId,
 8782        old_path: &Path,
 8783        new_path: &Path,
 8784        is_dir: bool,
 8785    ) {
 8786        maybe!({
 8787            let local_store = self.as_local()?;
 8788
 8789            let old_uri = lsp::Uri::from_file_path(old_path)
 8790                .ok()
 8791                .map(|uri| uri.to_string())?;
 8792            let new_uri = lsp::Uri::from_file_path(new_path)
 8793                .ok()
 8794                .map(|uri| uri.to_string())?;
 8795
 8796            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 8797                let Some(filter) = local_store
 8798                    .language_server_paths_watched_for_rename
 8799                    .get(&language_server.server_id())
 8800                else {
 8801                    continue;
 8802                };
 8803
 8804                if filter.should_send_did_rename(&old_uri, is_dir) {
 8805                    language_server
 8806                        .notify::<DidRenameFiles>(&RenameFilesParams {
 8807                            files: vec![FileRename {
 8808                                old_uri: old_uri.clone(),
 8809                                new_uri: new_uri.clone(),
 8810                            }],
 8811                        })
 8812                        .ok();
 8813                }
 8814            }
 8815            Some(())
 8816        });
 8817    }
 8818
 8819    pub(super) fn will_rename_entry(
 8820        this: WeakEntity<Self>,
 8821        worktree_id: WorktreeId,
 8822        old_path: &Path,
 8823        new_path: &Path,
 8824        is_dir: bool,
 8825        cx: AsyncApp,
 8826    ) -> Task<ProjectTransaction> {
 8827        let old_uri = lsp::Uri::from_file_path(old_path)
 8828            .ok()
 8829            .map(|uri| uri.to_string());
 8830        let new_uri = lsp::Uri::from_file_path(new_path)
 8831            .ok()
 8832            .map(|uri| uri.to_string());
 8833        cx.spawn(async move |cx| {
 8834            let mut tasks = vec![];
 8835            this.update(cx, |this, cx| {
 8836                let local_store = this.as_local()?;
 8837                let old_uri = old_uri?;
 8838                let new_uri = new_uri?;
 8839                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 8840                    let Some(filter) = local_store
 8841                        .language_server_paths_watched_for_rename
 8842                        .get(&language_server.server_id())
 8843                    else {
 8844                        continue;
 8845                    };
 8846
 8847                    if filter.should_send_will_rename(&old_uri, is_dir) {
 8848                        let apply_edit = cx.spawn({
 8849                            let old_uri = old_uri.clone();
 8850                            let new_uri = new_uri.clone();
 8851                            let language_server = language_server.clone();
 8852                            async move |this, cx| {
 8853                                let edit = language_server
 8854                                    .request::<WillRenameFiles>(RenameFilesParams {
 8855                                        files: vec![FileRename { old_uri, new_uri }],
 8856                                    })
 8857                                    .await
 8858                                    .into_response()
 8859                                    .context("will rename files")
 8860                                    .log_err()
 8861                                    .flatten()?;
 8862
 8863                                let transaction = LocalLspStore::deserialize_workspace_edit(
 8864                                    this.upgrade()?,
 8865                                    edit,
 8866                                    false,
 8867                                    language_server.clone(),
 8868                                    cx,
 8869                                )
 8870                                .await
 8871                                .ok()?;
 8872                                Some(transaction)
 8873                            }
 8874                        });
 8875                        tasks.push(apply_edit);
 8876                    }
 8877                }
 8878                Some(())
 8879            })
 8880            .ok()
 8881            .flatten();
 8882            let mut merged_transaction = ProjectTransaction::default();
 8883            for task in tasks {
 8884                // Await on tasks sequentially so that the order of application of edits is deterministic
 8885                // (at least with regards to the order of registration of language servers)
 8886                if let Some(transaction) = task.await {
 8887                    for (buffer, buffer_transaction) in transaction.0 {
 8888                        merged_transaction.0.insert(buffer, buffer_transaction);
 8889                    }
 8890                }
 8891            }
 8892            merged_transaction
 8893        })
 8894    }
 8895
 8896    fn lsp_notify_abs_paths_changed(
 8897        &mut self,
 8898        server_id: LanguageServerId,
 8899        changes: Vec<PathEvent>,
 8900    ) {
 8901        maybe!({
 8902            let server = self.language_server_for_id(server_id)?;
 8903            let changes = changes
 8904                .into_iter()
 8905                .filter_map(|event| {
 8906                    let typ = match event.kind? {
 8907                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 8908                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 8909                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 8910                    };
 8911                    Some(lsp::FileEvent {
 8912                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 8913                        typ,
 8914                    })
 8915                })
 8916                .collect::<Vec<_>>();
 8917            if !changes.is_empty() {
 8918                server
 8919                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 8920                        &lsp::DidChangeWatchedFilesParams { changes },
 8921                    )
 8922                    .ok();
 8923            }
 8924            Some(())
 8925        });
 8926    }
 8927
 8928    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 8929        self.as_local()?.language_server_for_id(id)
 8930    }
 8931
 8932    fn on_lsp_progress(
 8933        &mut self,
 8934        progress: lsp::ProgressParams,
 8935        language_server_id: LanguageServerId,
 8936        disk_based_diagnostics_progress_token: Option<String>,
 8937        cx: &mut Context<Self>,
 8938    ) {
 8939        let token = match progress.token {
 8940            lsp::NumberOrString::String(token) => token,
 8941            lsp::NumberOrString::Number(token) => {
 8942                log::info!("skipping numeric progress token {}", token);
 8943                return;
 8944            }
 8945        };
 8946
 8947        match progress.value {
 8948            lsp::ProgressParamsValue::WorkDone(progress) => {
 8949                self.handle_work_done_progress(
 8950                    progress,
 8951                    language_server_id,
 8952                    disk_based_diagnostics_progress_token,
 8953                    token,
 8954                    cx,
 8955                );
 8956            }
 8957            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 8958                if let Some(LanguageServerState::Running {
 8959                    workspace_refresh_task: Some(workspace_refresh_task),
 8960                    ..
 8961                }) = self
 8962                    .as_local_mut()
 8963                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 8964                {
 8965                    workspace_refresh_task.progress_tx.try_send(()).ok();
 8966                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 8967                }
 8968            }
 8969        }
 8970    }
 8971
 8972    fn handle_work_done_progress(
 8973        &mut self,
 8974        progress: lsp::WorkDoneProgress,
 8975        language_server_id: LanguageServerId,
 8976        disk_based_diagnostics_progress_token: Option<String>,
 8977        token: String,
 8978        cx: &mut Context<Self>,
 8979    ) {
 8980        let language_server_status =
 8981            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 8982                status
 8983            } else {
 8984                return;
 8985            };
 8986
 8987        if !language_server_status.progress_tokens.contains(&token) {
 8988            return;
 8989        }
 8990
 8991        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 8992            .as_ref()
 8993            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 8994
 8995        match progress {
 8996            lsp::WorkDoneProgress::Begin(report) => {
 8997                if is_disk_based_diagnostics_progress {
 8998                    self.disk_based_diagnostics_started(language_server_id, cx);
 8999                }
 9000                self.on_lsp_work_start(
 9001                    language_server_id,
 9002                    token.clone(),
 9003                    LanguageServerProgress {
 9004                        title: Some(report.title),
 9005                        is_disk_based_diagnostics_progress,
 9006                        is_cancellable: report.cancellable.unwrap_or(false),
 9007                        message: report.message.clone(),
 9008                        percentage: report.percentage.map(|p| p as usize),
 9009                        last_update_at: cx.background_executor().now(),
 9010                    },
 9011                    cx,
 9012                );
 9013            }
 9014            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9015                language_server_id,
 9016                token,
 9017                LanguageServerProgress {
 9018                    title: None,
 9019                    is_disk_based_diagnostics_progress,
 9020                    is_cancellable: report.cancellable.unwrap_or(false),
 9021                    message: report.message,
 9022                    percentage: report.percentage.map(|p| p as usize),
 9023                    last_update_at: cx.background_executor().now(),
 9024                },
 9025                cx,
 9026            ),
 9027            lsp::WorkDoneProgress::End(_) => {
 9028                language_server_status.progress_tokens.remove(&token);
 9029                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9030                if is_disk_based_diagnostics_progress {
 9031                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9032                }
 9033            }
 9034        }
 9035    }
 9036
 9037    fn on_lsp_work_start(
 9038        &mut self,
 9039        language_server_id: LanguageServerId,
 9040        token: String,
 9041        progress: LanguageServerProgress,
 9042        cx: &mut Context<Self>,
 9043    ) {
 9044        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9045            status.pending_work.insert(token.clone(), progress.clone());
 9046            cx.notify();
 9047        }
 9048        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9049            language_server_id,
 9050            name: self
 9051                .language_server_adapter_for_id(language_server_id)
 9052                .map(|adapter| adapter.name()),
 9053            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9054                token,
 9055                title: progress.title,
 9056                message: progress.message,
 9057                percentage: progress.percentage.map(|p| p as u32),
 9058                is_cancellable: Some(progress.is_cancellable),
 9059            }),
 9060        })
 9061    }
 9062
 9063    fn on_lsp_work_progress(
 9064        &mut self,
 9065        language_server_id: LanguageServerId,
 9066        token: String,
 9067        progress: LanguageServerProgress,
 9068        cx: &mut Context<Self>,
 9069    ) {
 9070        let mut did_update = false;
 9071        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9072            match status.pending_work.entry(token.clone()) {
 9073                btree_map::Entry::Vacant(entry) => {
 9074                    entry.insert(progress.clone());
 9075                    did_update = true;
 9076                }
 9077                btree_map::Entry::Occupied(mut entry) => {
 9078                    let entry = entry.get_mut();
 9079                    if (progress.last_update_at - entry.last_update_at)
 9080                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9081                    {
 9082                        entry.last_update_at = progress.last_update_at;
 9083                        if progress.message.is_some() {
 9084                            entry.message = progress.message.clone();
 9085                        }
 9086                        if progress.percentage.is_some() {
 9087                            entry.percentage = progress.percentage;
 9088                        }
 9089                        if progress.is_cancellable != entry.is_cancellable {
 9090                            entry.is_cancellable = progress.is_cancellable;
 9091                        }
 9092                        did_update = true;
 9093                    }
 9094                }
 9095            }
 9096        }
 9097
 9098        if did_update {
 9099            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9100                language_server_id,
 9101                name: self
 9102                    .language_server_adapter_for_id(language_server_id)
 9103                    .map(|adapter| adapter.name()),
 9104                message: proto::update_language_server::Variant::WorkProgress(
 9105                    proto::LspWorkProgress {
 9106                        token,
 9107                        message: progress.message,
 9108                        percentage: progress.percentage.map(|p| p as u32),
 9109                        is_cancellable: Some(progress.is_cancellable),
 9110                    },
 9111                ),
 9112            })
 9113        }
 9114    }
 9115
 9116    fn on_lsp_work_end(
 9117        &mut self,
 9118        language_server_id: LanguageServerId,
 9119        token: String,
 9120        cx: &mut Context<Self>,
 9121    ) {
 9122        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9123            if let Some(work) = status.pending_work.remove(&token)
 9124                && !work.is_disk_based_diagnostics_progress
 9125            {
 9126                cx.emit(LspStoreEvent::RefreshInlayHints);
 9127            }
 9128            cx.notify();
 9129        }
 9130
 9131        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9132            language_server_id,
 9133            name: self
 9134                .language_server_adapter_for_id(language_server_id)
 9135                .map(|adapter| adapter.name()),
 9136            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9137        })
 9138    }
 9139
 9140    pub async fn handle_resolve_completion_documentation(
 9141        this: Entity<Self>,
 9142        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9143        mut cx: AsyncApp,
 9144    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9145        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9146
 9147        let completion = this
 9148            .read_with(&cx, |this, cx| {
 9149                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9150                let server = this
 9151                    .language_server_for_id(id)
 9152                    .with_context(|| format!("No language server {id}"))?;
 9153
 9154                anyhow::Ok(cx.background_spawn(async move {
 9155                    let can_resolve = server
 9156                        .capabilities()
 9157                        .completion_provider
 9158                        .as_ref()
 9159                        .and_then(|options| options.resolve_provider)
 9160                        .unwrap_or(false);
 9161                    if can_resolve {
 9162                        server
 9163                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9164                            .await
 9165                            .into_response()
 9166                            .context("resolve completion item")
 9167                    } else {
 9168                        anyhow::Ok(lsp_completion)
 9169                    }
 9170                }))
 9171            })??
 9172            .await?;
 9173
 9174        let mut documentation_is_markdown = false;
 9175        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9176        let documentation = match completion.documentation {
 9177            Some(lsp::Documentation::String(text)) => text,
 9178
 9179            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9180                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9181                value
 9182            }
 9183
 9184            _ => String::new(),
 9185        };
 9186
 9187        // If we have a new buffer_id, that means we're talking to a new client
 9188        // and want to check for new text_edits in the completion too.
 9189        let mut old_replace_start = None;
 9190        let mut old_replace_end = None;
 9191        let mut old_insert_start = None;
 9192        let mut old_insert_end = None;
 9193        let mut new_text = String::default();
 9194        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9195            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9196                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9197                anyhow::Ok(buffer.read(cx).snapshot())
 9198            })??;
 9199
 9200            if let Some(text_edit) = completion.text_edit.as_ref() {
 9201                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9202
 9203                if let Some(mut edit) = edit {
 9204                    LineEnding::normalize(&mut edit.new_text);
 9205
 9206                    new_text = edit.new_text;
 9207                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9208                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9209                    if let Some(insert_range) = edit.insert_range {
 9210                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9211                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9212                    }
 9213                }
 9214            }
 9215        }
 9216
 9217        Ok(proto::ResolveCompletionDocumentationResponse {
 9218            documentation,
 9219            documentation_is_markdown,
 9220            old_replace_start,
 9221            old_replace_end,
 9222            new_text,
 9223            lsp_completion,
 9224            old_insert_start,
 9225            old_insert_end,
 9226        })
 9227    }
 9228
 9229    async fn handle_on_type_formatting(
 9230        this: Entity<Self>,
 9231        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9232        mut cx: AsyncApp,
 9233    ) -> Result<proto::OnTypeFormattingResponse> {
 9234        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9235            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9236            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9237            let position = envelope
 9238                .payload
 9239                .position
 9240                .and_then(deserialize_anchor)
 9241                .context("invalid position")?;
 9242            anyhow::Ok(this.apply_on_type_formatting(
 9243                buffer,
 9244                position,
 9245                envelope.payload.trigger.clone(),
 9246                cx,
 9247            ))
 9248        })??;
 9249
 9250        let transaction = on_type_formatting
 9251            .await?
 9252            .as_ref()
 9253            .map(language::proto::serialize_transaction);
 9254        Ok(proto::OnTypeFormattingResponse { transaction })
 9255    }
 9256
 9257    async fn handle_refresh_inlay_hints(
 9258        this: Entity<Self>,
 9259        _: TypedEnvelope<proto::RefreshInlayHints>,
 9260        mut cx: AsyncApp,
 9261    ) -> Result<proto::Ack> {
 9262        this.update(&mut cx, |_, cx| {
 9263            cx.emit(LspStoreEvent::RefreshInlayHints);
 9264        })?;
 9265        Ok(proto::Ack {})
 9266    }
 9267
 9268    async fn handle_pull_workspace_diagnostics(
 9269        lsp_store: Entity<Self>,
 9270        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9271        mut cx: AsyncApp,
 9272    ) -> Result<proto::Ack> {
 9273        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9274        lsp_store.update(&mut cx, |lsp_store, _| {
 9275            lsp_store.pull_workspace_diagnostics(server_id);
 9276        })?;
 9277        Ok(proto::Ack {})
 9278    }
 9279
 9280    async fn handle_inlay_hints(
 9281        this: Entity<Self>,
 9282        envelope: TypedEnvelope<proto::InlayHints>,
 9283        mut cx: AsyncApp,
 9284    ) -> Result<proto::InlayHintsResponse> {
 9285        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9286        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9287        let buffer = this.update(&mut cx, |this, cx| {
 9288            this.buffer_store.read(cx).get_existing(buffer_id)
 9289        })??;
 9290        buffer
 9291            .update(&mut cx, |buffer, _| {
 9292                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9293            })?
 9294            .await
 9295            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9296
 9297        let start = envelope
 9298            .payload
 9299            .start
 9300            .and_then(deserialize_anchor)
 9301            .context("missing range start")?;
 9302        let end = envelope
 9303            .payload
 9304            .end
 9305            .and_then(deserialize_anchor)
 9306            .context("missing range end")?;
 9307        let buffer_hints = this
 9308            .update(&mut cx, |lsp_store, cx| {
 9309                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9310            })?
 9311            .await
 9312            .context("inlay hints fetch")?;
 9313
 9314        this.update(&mut cx, |project, cx| {
 9315            InlayHints::response_to_proto(
 9316                buffer_hints,
 9317                project,
 9318                sender_id,
 9319                &buffer.read(cx).version(),
 9320                cx,
 9321            )
 9322        })
 9323    }
 9324
 9325    async fn handle_get_color_presentation(
 9326        lsp_store: Entity<Self>,
 9327        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9328        mut cx: AsyncApp,
 9329    ) -> Result<proto::GetColorPresentationResponse> {
 9330        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9331        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9332            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9333        })??;
 9334
 9335        let color = envelope
 9336            .payload
 9337            .color
 9338            .context("invalid color resolve request")?;
 9339        let start = color
 9340            .lsp_range_start
 9341            .context("invalid color resolve request")?;
 9342        let end = color
 9343            .lsp_range_end
 9344            .context("invalid color resolve request")?;
 9345
 9346        let color = DocumentColor {
 9347            lsp_range: lsp::Range {
 9348                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9349                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9350            },
 9351            color: lsp::Color {
 9352                red: color.red,
 9353                green: color.green,
 9354                blue: color.blue,
 9355                alpha: color.alpha,
 9356            },
 9357            resolved: false,
 9358            color_presentations: Vec::new(),
 9359        };
 9360        let resolved_color = lsp_store
 9361            .update(&mut cx, |lsp_store, cx| {
 9362                lsp_store.resolve_color_presentation(
 9363                    color,
 9364                    buffer.clone(),
 9365                    LanguageServerId(envelope.payload.server_id as usize),
 9366                    cx,
 9367                )
 9368            })?
 9369            .await
 9370            .context("resolving color presentation")?;
 9371
 9372        Ok(proto::GetColorPresentationResponse {
 9373            presentations: resolved_color
 9374                .color_presentations
 9375                .into_iter()
 9376                .map(|presentation| proto::ColorPresentation {
 9377                    label: presentation.label.to_string(),
 9378                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9379                    additional_text_edits: presentation
 9380                        .additional_text_edits
 9381                        .into_iter()
 9382                        .map(serialize_lsp_edit)
 9383                        .collect(),
 9384                })
 9385                .collect(),
 9386        })
 9387    }
 9388
 9389    async fn handle_resolve_inlay_hint(
 9390        this: Entity<Self>,
 9391        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9392        mut cx: AsyncApp,
 9393    ) -> Result<proto::ResolveInlayHintResponse> {
 9394        let proto_hint = envelope
 9395            .payload
 9396            .hint
 9397            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9398        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9399            .context("resolved proto inlay hint conversion")?;
 9400        let buffer = this.update(&mut cx, |this, cx| {
 9401            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9402            this.buffer_store.read(cx).get_existing(buffer_id)
 9403        })??;
 9404        let response_hint = this
 9405            .update(&mut cx, |this, cx| {
 9406                this.resolve_inlay_hint(
 9407                    hint,
 9408                    buffer,
 9409                    LanguageServerId(envelope.payload.language_server_id as usize),
 9410                    cx,
 9411                )
 9412            })?
 9413            .await
 9414            .context("inlay hints fetch")?;
 9415        Ok(proto::ResolveInlayHintResponse {
 9416            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9417        })
 9418    }
 9419
 9420    async fn handle_refresh_code_lens(
 9421        this: Entity<Self>,
 9422        _: TypedEnvelope<proto::RefreshCodeLens>,
 9423        mut cx: AsyncApp,
 9424    ) -> Result<proto::Ack> {
 9425        this.update(&mut cx, |_, cx| {
 9426            cx.emit(LspStoreEvent::RefreshCodeLens);
 9427        })?;
 9428        Ok(proto::Ack {})
 9429    }
 9430
 9431    async fn handle_open_buffer_for_symbol(
 9432        this: Entity<Self>,
 9433        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9434        mut cx: AsyncApp,
 9435    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9436        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9437        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9438        let symbol = Self::deserialize_symbol(symbol)?;
 9439        let symbol = this.read_with(&cx, |this, _| {
 9440            let signature = this.symbol_signature(&symbol.path);
 9441            anyhow::ensure!(signature == symbol.signature, "invalid symbol signature");
 9442            Ok(symbol)
 9443        })??;
 9444        let buffer = this
 9445            .update(&mut cx, |this, cx| {
 9446                this.open_buffer_for_symbol(
 9447                    &Symbol {
 9448                        language_server_name: symbol.language_server_name,
 9449                        source_worktree_id: symbol.source_worktree_id,
 9450                        source_language_server_id: symbol.source_language_server_id,
 9451                        path: symbol.path,
 9452                        name: symbol.name,
 9453                        kind: symbol.kind,
 9454                        range: symbol.range,
 9455                        signature: symbol.signature,
 9456                        label: CodeLabel {
 9457                            text: Default::default(),
 9458                            runs: Default::default(),
 9459                            filter_range: Default::default(),
 9460                        },
 9461                    },
 9462                    cx,
 9463                )
 9464            })?
 9465            .await?;
 9466
 9467        this.update(&mut cx, |this, cx| {
 9468            let is_private = buffer
 9469                .read(cx)
 9470                .file()
 9471                .map(|f| f.is_private())
 9472                .unwrap_or_default();
 9473            if is_private {
 9474                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9475            } else {
 9476                this.buffer_store
 9477                    .update(cx, |buffer_store, cx| {
 9478                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9479                    })
 9480                    .detach_and_log_err(cx);
 9481                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9482                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9483            }
 9484        })?
 9485    }
 9486
 9487    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
 9488        let mut hasher = Sha256::new();
 9489        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
 9490        hasher.update(project_path.path.to_string_lossy().as_bytes());
 9491        hasher.update(self.nonce.to_be_bytes());
 9492        hasher.finalize().as_slice().try_into().unwrap()
 9493    }
 9494
 9495    pub async fn handle_get_project_symbols(
 9496        this: Entity<Self>,
 9497        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9498        mut cx: AsyncApp,
 9499    ) -> Result<proto::GetProjectSymbolsResponse> {
 9500        let symbols = this
 9501            .update(&mut cx, |this, cx| {
 9502                this.symbols(&envelope.payload.query, cx)
 9503            })?
 9504            .await?;
 9505
 9506        Ok(proto::GetProjectSymbolsResponse {
 9507            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9508        })
 9509    }
 9510
 9511    pub async fn handle_restart_language_servers(
 9512        this: Entity<Self>,
 9513        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9514        mut cx: AsyncApp,
 9515    ) -> Result<proto::Ack> {
 9516        this.update(&mut cx, |lsp_store, cx| {
 9517            let buffers =
 9518                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9519            lsp_store.restart_language_servers_for_buffers(
 9520                buffers,
 9521                envelope
 9522                    .payload
 9523                    .only_servers
 9524                    .into_iter()
 9525                    .filter_map(|selector| {
 9526                        Some(match selector.selector? {
 9527                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9528                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9529                            }
 9530                            proto::language_server_selector::Selector::Name(name) => {
 9531                                LanguageServerSelector::Name(LanguageServerName(
 9532                                    SharedString::from(name),
 9533                                ))
 9534                            }
 9535                        })
 9536                    })
 9537                    .collect(),
 9538                cx,
 9539            );
 9540        })?;
 9541
 9542        Ok(proto::Ack {})
 9543    }
 9544
 9545    pub async fn handle_stop_language_servers(
 9546        lsp_store: Entity<Self>,
 9547        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9548        mut cx: AsyncApp,
 9549    ) -> Result<proto::Ack> {
 9550        lsp_store.update(&mut cx, |lsp_store, cx| {
 9551            if envelope.payload.all
 9552                && envelope.payload.also_servers.is_empty()
 9553                && envelope.payload.buffer_ids.is_empty()
 9554            {
 9555                lsp_store.stop_all_language_servers(cx);
 9556            } else {
 9557                let buffers =
 9558                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9559                lsp_store
 9560                    .stop_language_servers_for_buffers(
 9561                        buffers,
 9562                        envelope
 9563                            .payload
 9564                            .also_servers
 9565                            .into_iter()
 9566                            .filter_map(|selector| {
 9567                                Some(match selector.selector? {
 9568                                    proto::language_server_selector::Selector::ServerId(
 9569                                        server_id,
 9570                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9571                                        server_id,
 9572                                    )),
 9573                                    proto::language_server_selector::Selector::Name(name) => {
 9574                                        LanguageServerSelector::Name(LanguageServerName(
 9575                                            SharedString::from(name),
 9576                                        ))
 9577                                    }
 9578                                })
 9579                            })
 9580                            .collect(),
 9581                        cx,
 9582                    )
 9583                    .detach_and_log_err(cx);
 9584            }
 9585        })?;
 9586
 9587        Ok(proto::Ack {})
 9588    }
 9589
 9590    pub async fn handle_cancel_language_server_work(
 9591        this: Entity<Self>,
 9592        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
 9593        mut cx: AsyncApp,
 9594    ) -> Result<proto::Ack> {
 9595        this.update(&mut cx, |this, cx| {
 9596            if let Some(work) = envelope.payload.work {
 9597                match work {
 9598                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
 9599                        let buffers =
 9600                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
 9601                        this.cancel_language_server_work_for_buffers(buffers, cx);
 9602                    }
 9603                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
 9604                        let server_id = LanguageServerId::from_proto(work.language_server_id);
 9605                        this.cancel_language_server_work(server_id, work.token, cx);
 9606                    }
 9607                }
 9608            }
 9609        })?;
 9610
 9611        Ok(proto::Ack {})
 9612    }
 9613
 9614    fn buffer_ids_to_buffers(
 9615        &mut self,
 9616        buffer_ids: impl Iterator<Item = u64>,
 9617        cx: &mut Context<Self>,
 9618    ) -> Vec<Entity<Buffer>> {
 9619        buffer_ids
 9620            .into_iter()
 9621            .flat_map(|buffer_id| {
 9622                self.buffer_store
 9623                    .read(cx)
 9624                    .get(BufferId::new(buffer_id).log_err()?)
 9625            })
 9626            .collect::<Vec<_>>()
 9627    }
 9628
 9629    async fn handle_apply_additional_edits_for_completion(
 9630        this: Entity<Self>,
 9631        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
 9632        mut cx: AsyncApp,
 9633    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
 9634        let (buffer, completion) = this.update(&mut cx, |this, cx| {
 9635            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9636            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9637            let completion = Self::deserialize_completion(
 9638                envelope.payload.completion.context("invalid completion")?,
 9639            )?;
 9640            anyhow::Ok((buffer, completion))
 9641        })??;
 9642
 9643        let apply_additional_edits = this.update(&mut cx, |this, cx| {
 9644            this.apply_additional_edits_for_completion(
 9645                buffer,
 9646                Rc::new(RefCell::new(Box::new([Completion {
 9647                    replace_range: completion.replace_range,
 9648                    new_text: completion.new_text,
 9649                    source: completion.source,
 9650                    documentation: None,
 9651                    label: CodeLabel {
 9652                        text: Default::default(),
 9653                        runs: Default::default(),
 9654                        filter_range: Default::default(),
 9655                    },
 9656                    insert_text_mode: None,
 9657                    icon_path: None,
 9658                    confirm: None,
 9659                }]))),
 9660                0,
 9661                false,
 9662                cx,
 9663            )
 9664        })?;
 9665
 9666        Ok(proto::ApplyCompletionAdditionalEditsResponse {
 9667            transaction: apply_additional_edits
 9668                .await?
 9669                .as_ref()
 9670                .map(language::proto::serialize_transaction),
 9671        })
 9672    }
 9673
 9674    pub fn last_formatting_failure(&self) -> Option<&str> {
 9675        self.last_formatting_failure.as_deref()
 9676    }
 9677
 9678    pub fn reset_last_formatting_failure(&mut self) {
 9679        self.last_formatting_failure = None;
 9680    }
 9681
 9682    pub fn environment_for_buffer(
 9683        &self,
 9684        buffer: &Entity<Buffer>,
 9685        cx: &mut Context<Self>,
 9686    ) -> Shared<Task<Option<HashMap<String, String>>>> {
 9687        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
 9688            environment.update(cx, |env, cx| {
 9689                env.get_buffer_environment(buffer, &self.worktree_store, cx)
 9690            })
 9691        } else {
 9692            Task::ready(None).shared()
 9693        }
 9694    }
 9695
 9696    pub fn format(
 9697        &mut self,
 9698        buffers: HashSet<Entity<Buffer>>,
 9699        target: LspFormatTarget,
 9700        push_to_history: bool,
 9701        trigger: FormatTrigger,
 9702        cx: &mut Context<Self>,
 9703    ) -> Task<anyhow::Result<ProjectTransaction>> {
 9704        let logger = zlog::scoped!("format");
 9705        if self.as_local().is_some() {
 9706            zlog::trace!(logger => "Formatting locally");
 9707            let logger = zlog::scoped!(logger => "local");
 9708            let buffers = buffers
 9709                .into_iter()
 9710                .map(|buffer_handle| {
 9711                    let buffer = buffer_handle.read(cx);
 9712                    let buffer_abs_path = File::from_dyn(buffer.file())
 9713                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
 9714
 9715                    (buffer_handle, buffer_abs_path, buffer.remote_id())
 9716                })
 9717                .collect::<Vec<_>>();
 9718
 9719            cx.spawn(async move |lsp_store, cx| {
 9720                let mut formattable_buffers = Vec::with_capacity(buffers.len());
 9721
 9722                for (handle, abs_path, id) in buffers {
 9723                    let env = lsp_store
 9724                        .update(cx, |lsp_store, cx| {
 9725                            lsp_store.environment_for_buffer(&handle, cx)
 9726                        })?
 9727                        .await;
 9728
 9729                    let ranges = match &target {
 9730                        LspFormatTarget::Buffers => None,
 9731                        LspFormatTarget::Ranges(ranges) => {
 9732                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
 9733                        }
 9734                    };
 9735
 9736                    formattable_buffers.push(FormattableBuffer {
 9737                        handle,
 9738                        abs_path,
 9739                        env,
 9740                        ranges,
 9741                    });
 9742                }
 9743                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
 9744
 9745                let format_timer = zlog::time!(logger => "Formatting buffers");
 9746                let result = LocalLspStore::format_locally(
 9747                    lsp_store.clone(),
 9748                    formattable_buffers,
 9749                    push_to_history,
 9750                    trigger,
 9751                    logger,
 9752                    cx,
 9753                )
 9754                .await;
 9755                format_timer.end();
 9756
 9757                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
 9758
 9759                lsp_store.update(cx, |lsp_store, _| {
 9760                    lsp_store.update_last_formatting_failure(&result);
 9761                })?;
 9762
 9763                result
 9764            })
 9765        } else if let Some((client, project_id)) = self.upstream_client() {
 9766            zlog::trace!(logger => "Formatting remotely");
 9767            let logger = zlog::scoped!(logger => "remote");
 9768            // Don't support formatting ranges via remote
 9769            match target {
 9770                LspFormatTarget::Buffers => {}
 9771                LspFormatTarget::Ranges(_) => {
 9772                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
 9773                    return Task::ready(Ok(ProjectTransaction::default()));
 9774                }
 9775            }
 9776
 9777            let buffer_store = self.buffer_store();
 9778            cx.spawn(async move |lsp_store, cx| {
 9779                zlog::trace!(logger => "Sending remote format request");
 9780                let request_timer = zlog::time!(logger => "remote format request");
 9781                let result = client
 9782                    .request(proto::FormatBuffers {
 9783                        project_id,
 9784                        trigger: trigger as i32,
 9785                        buffer_ids: buffers
 9786                            .iter()
 9787                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
 9788                            .collect::<Result<_>>()?,
 9789                    })
 9790                    .await
 9791                    .and_then(|result| result.transaction.context("missing transaction"));
 9792                request_timer.end();
 9793
 9794                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
 9795
 9796                lsp_store.update(cx, |lsp_store, _| {
 9797                    lsp_store.update_last_formatting_failure(&result);
 9798                })?;
 9799
 9800                let transaction_response = result?;
 9801                let _timer = zlog::time!(logger => "deserializing project transaction");
 9802                buffer_store
 9803                    .update(cx, |buffer_store, cx| {
 9804                        buffer_store.deserialize_project_transaction(
 9805                            transaction_response,
 9806                            push_to_history,
 9807                            cx,
 9808                        )
 9809                    })?
 9810                    .await
 9811            })
 9812        } else {
 9813            zlog::trace!(logger => "Not formatting");
 9814            Task::ready(Ok(ProjectTransaction::default()))
 9815        }
 9816    }
 9817
 9818    async fn handle_format_buffers(
 9819        this: Entity<Self>,
 9820        envelope: TypedEnvelope<proto::FormatBuffers>,
 9821        mut cx: AsyncApp,
 9822    ) -> Result<proto::FormatBuffersResponse> {
 9823        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9824        let format = this.update(&mut cx, |this, cx| {
 9825            let mut buffers = HashSet::default();
 9826            for buffer_id in &envelope.payload.buffer_ids {
 9827                let buffer_id = BufferId::new(*buffer_id)?;
 9828                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
 9829            }
 9830            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
 9831            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
 9832        })??;
 9833
 9834        let project_transaction = format.await?;
 9835        let project_transaction = this.update(&mut cx, |this, cx| {
 9836            this.buffer_store.update(cx, |buffer_store, cx| {
 9837                buffer_store.serialize_project_transaction_for_peer(
 9838                    project_transaction,
 9839                    sender_id,
 9840                    cx,
 9841                )
 9842            })
 9843        })?;
 9844        Ok(proto::FormatBuffersResponse {
 9845            transaction: Some(project_transaction),
 9846        })
 9847    }
 9848
 9849    async fn handle_apply_code_action_kind(
 9850        this: Entity<Self>,
 9851        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
 9852        mut cx: AsyncApp,
 9853    ) -> Result<proto::ApplyCodeActionKindResponse> {
 9854        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9855        let format = this.update(&mut cx, |this, cx| {
 9856            let mut buffers = HashSet::default();
 9857            for buffer_id in &envelope.payload.buffer_ids {
 9858                let buffer_id = BufferId::new(*buffer_id)?;
 9859                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
 9860            }
 9861            let kind = match envelope.payload.kind.as_str() {
 9862                "" => CodeActionKind::EMPTY,
 9863                "quickfix" => CodeActionKind::QUICKFIX,
 9864                "refactor" => CodeActionKind::REFACTOR,
 9865                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
 9866                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
 9867                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
 9868                "source" => CodeActionKind::SOURCE,
 9869                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
 9870                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
 9871                _ => anyhow::bail!(
 9872                    "Invalid code action kind {}",
 9873                    envelope.payload.kind.as_str()
 9874                ),
 9875            };
 9876            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
 9877        })??;
 9878
 9879        let project_transaction = format.await?;
 9880        let project_transaction = this.update(&mut cx, |this, cx| {
 9881            this.buffer_store.update(cx, |buffer_store, cx| {
 9882                buffer_store.serialize_project_transaction_for_peer(
 9883                    project_transaction,
 9884                    sender_id,
 9885                    cx,
 9886                )
 9887            })
 9888        })?;
 9889        Ok(proto::ApplyCodeActionKindResponse {
 9890            transaction: Some(project_transaction),
 9891        })
 9892    }
 9893
 9894    async fn shutdown_language_server(
 9895        server_state: Option<LanguageServerState>,
 9896        name: LanguageServerName,
 9897        cx: &mut AsyncApp,
 9898    ) {
 9899        let server = match server_state {
 9900            Some(LanguageServerState::Starting { startup, .. }) => {
 9901                let mut timer = cx
 9902                    .background_executor()
 9903                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
 9904                    .fuse();
 9905
 9906                select! {
 9907                    server = startup.fuse() => server,
 9908                    () = timer => {
 9909                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
 9910                        None
 9911                    },
 9912                }
 9913            }
 9914
 9915            Some(LanguageServerState::Running { server, .. }) => Some(server),
 9916
 9917            None => None,
 9918        };
 9919
 9920        if let Some(server) = server
 9921            && let Some(shutdown) = server.shutdown()
 9922        {
 9923            shutdown.await;
 9924        }
 9925    }
 9926
 9927    // Returns a list of all of the worktrees which no longer have a language server and the root path
 9928    // for the stopped server
 9929    fn stop_local_language_server(
 9930        &mut self,
 9931        server_id: LanguageServerId,
 9932        cx: &mut Context<Self>,
 9933    ) -> Task<()> {
 9934        let local = match &mut self.mode {
 9935            LspStoreMode::Local(local) => local,
 9936            _ => {
 9937                return Task::ready(());
 9938            }
 9939        };
 9940
 9941        // Remove this server ID from all entries in the given worktree.
 9942        local
 9943            .language_server_ids
 9944            .retain(|_, state| state.id != server_id);
 9945        self.buffer_store.update(cx, |buffer_store, cx| {
 9946            for buffer in buffer_store.buffers() {
 9947                buffer.update(cx, |buffer, cx| {
 9948                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 9949                    buffer.set_completion_triggers(server_id, Default::default(), cx);
 9950                });
 9951            }
 9952        });
 9953
 9954        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
 9955            summaries.retain(|path, summaries_by_server_id| {
 9956                if summaries_by_server_id.remove(&server_id).is_some() {
 9957                    if let Some((client, project_id)) = self.downstream_client.clone() {
 9958                        client
 9959                            .send(proto::UpdateDiagnosticSummary {
 9960                                project_id,
 9961                                worktree_id: worktree_id.to_proto(),
 9962                                summary: Some(proto::DiagnosticSummary {
 9963                                    path: path.as_ref().to_proto(),
 9964                                    language_server_id: server_id.0 as u64,
 9965                                    error_count: 0,
 9966                                    warning_count: 0,
 9967                                }),
 9968                                more_summaries: Vec::new(),
 9969                            })
 9970                            .log_err();
 9971                    }
 9972                    !summaries_by_server_id.is_empty()
 9973                } else {
 9974                    true
 9975                }
 9976            });
 9977        }
 9978
 9979        let local = self.as_local_mut().unwrap();
 9980        for diagnostics in local.diagnostics.values_mut() {
 9981            diagnostics.retain(|_, diagnostics_by_server_id| {
 9982                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 9983                    diagnostics_by_server_id.remove(ix);
 9984                    !diagnostics_by_server_id.is_empty()
 9985                } else {
 9986                    true
 9987                }
 9988            });
 9989        }
 9990        local.language_server_watched_paths.remove(&server_id);
 9991
 9992        let server_state = local.language_servers.remove(&server_id);
 9993        self.cleanup_lsp_data(server_id);
 9994        let name = self
 9995            .language_server_statuses
 9996            .remove(&server_id)
 9997            .map(|status| status.name)
 9998            .or_else(|| {
 9999                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10000                    Some(adapter.name())
10001                } else {
10002                    None
10003                }
10004            });
10005
10006        if let Some(name) = name {
10007            log::info!("stopping language server {name}");
10008            self.languages
10009                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10010            cx.notify();
10011
10012            return cx.spawn(async move |lsp_store, cx| {
10013                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10014                lsp_store
10015                    .update(cx, |lsp_store, cx| {
10016                        lsp_store
10017                            .languages
10018                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10019                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10020                        cx.notify();
10021                    })
10022                    .ok();
10023            });
10024        }
10025
10026        if server_state.is_some() {
10027            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10028        }
10029        Task::ready(())
10030    }
10031
10032    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10033        if let Some((client, project_id)) = self.upstream_client() {
10034            let request = client.request(proto::StopLanguageServers {
10035                project_id,
10036                buffer_ids: Vec::new(),
10037                also_servers: Vec::new(),
10038                all: true,
10039            });
10040            cx.background_spawn(request).detach_and_log_err(cx);
10041        } else {
10042            let Some(local) = self.as_local_mut() else {
10043                return;
10044            };
10045            let language_servers_to_stop = local
10046                .language_server_ids
10047                .values()
10048                .map(|state| state.id)
10049                .collect();
10050            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10051            let tasks = language_servers_to_stop
10052                .into_iter()
10053                .map(|server| self.stop_local_language_server(server, cx))
10054                .collect::<Vec<_>>();
10055            cx.background_spawn(async move {
10056                futures::future::join_all(tasks).await;
10057            })
10058            .detach();
10059        }
10060    }
10061
10062    pub fn restart_language_servers_for_buffers(
10063        &mut self,
10064        buffers: Vec<Entity<Buffer>>,
10065        only_restart_servers: HashSet<LanguageServerSelector>,
10066        cx: &mut Context<Self>,
10067    ) {
10068        if let Some((client, project_id)) = self.upstream_client() {
10069            let request = client.request(proto::RestartLanguageServers {
10070                project_id,
10071                buffer_ids: buffers
10072                    .into_iter()
10073                    .map(|b| b.read(cx).remote_id().to_proto())
10074                    .collect(),
10075                only_servers: only_restart_servers
10076                    .into_iter()
10077                    .map(|selector| {
10078                        let selector = match selector {
10079                            LanguageServerSelector::Id(language_server_id) => {
10080                                proto::language_server_selector::Selector::ServerId(
10081                                    language_server_id.to_proto(),
10082                                )
10083                            }
10084                            LanguageServerSelector::Name(language_server_name) => {
10085                                proto::language_server_selector::Selector::Name(
10086                                    language_server_name.to_string(),
10087                                )
10088                            }
10089                        };
10090                        proto::LanguageServerSelector {
10091                            selector: Some(selector),
10092                        }
10093                    })
10094                    .collect(),
10095                all: false,
10096            });
10097            cx.background_spawn(request).detach_and_log_err(cx);
10098        } else {
10099            let stop_task = if only_restart_servers.is_empty() {
10100                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10101            } else {
10102                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10103            };
10104            cx.spawn(async move |lsp_store, cx| {
10105                stop_task.await;
10106                lsp_store
10107                    .update(cx, |lsp_store, cx| {
10108                        for buffer in buffers {
10109                            lsp_store.register_buffer_with_language_servers(
10110                                &buffer,
10111                                only_restart_servers.clone(),
10112                                true,
10113                                cx,
10114                            );
10115                        }
10116                    })
10117                    .ok()
10118            })
10119            .detach();
10120        }
10121    }
10122
10123    pub fn stop_language_servers_for_buffers(
10124        &mut self,
10125        buffers: Vec<Entity<Buffer>>,
10126        also_stop_servers: HashSet<LanguageServerSelector>,
10127        cx: &mut Context<Self>,
10128    ) -> Task<Result<()>> {
10129        if let Some((client, project_id)) = self.upstream_client() {
10130            let request = client.request(proto::StopLanguageServers {
10131                project_id,
10132                buffer_ids: buffers
10133                    .into_iter()
10134                    .map(|b| b.read(cx).remote_id().to_proto())
10135                    .collect(),
10136                also_servers: also_stop_servers
10137                    .into_iter()
10138                    .map(|selector| {
10139                        let selector = match selector {
10140                            LanguageServerSelector::Id(language_server_id) => {
10141                                proto::language_server_selector::Selector::ServerId(
10142                                    language_server_id.to_proto(),
10143                                )
10144                            }
10145                            LanguageServerSelector::Name(language_server_name) => {
10146                                proto::language_server_selector::Selector::Name(
10147                                    language_server_name.to_string(),
10148                                )
10149                            }
10150                        };
10151                        proto::LanguageServerSelector {
10152                            selector: Some(selector),
10153                        }
10154                    })
10155                    .collect(),
10156                all: false,
10157            });
10158            cx.background_spawn(async move {
10159                let _ = request.await?;
10160                Ok(())
10161            })
10162        } else {
10163            let task =
10164                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10165            cx.background_spawn(async move {
10166                task.await;
10167                Ok(())
10168            })
10169        }
10170    }
10171
10172    fn stop_local_language_servers_for_buffers(
10173        &mut self,
10174        buffers: &[Entity<Buffer>],
10175        also_stop_servers: HashSet<LanguageServerSelector>,
10176        cx: &mut Context<Self>,
10177    ) -> Task<()> {
10178        let Some(local) = self.as_local_mut() else {
10179            return Task::ready(());
10180        };
10181        let mut language_server_names_to_stop = BTreeSet::default();
10182        let mut language_servers_to_stop = also_stop_servers
10183            .into_iter()
10184            .flat_map(|selector| match selector {
10185                LanguageServerSelector::Id(id) => Some(id),
10186                LanguageServerSelector::Name(name) => {
10187                    language_server_names_to_stop.insert(name);
10188                    None
10189                }
10190            })
10191            .collect::<BTreeSet<_>>();
10192
10193        let mut covered_worktrees = HashSet::default();
10194        for buffer in buffers {
10195            buffer.update(cx, |buffer, cx| {
10196                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10197                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10198                    && covered_worktrees.insert(worktree_id)
10199                {
10200                    language_server_names_to_stop.retain(|name| {
10201                        let old_ids_count = language_servers_to_stop.len();
10202                        let all_language_servers_with_this_name = local
10203                            .language_server_ids
10204                            .iter()
10205                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10206                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10207                        old_ids_count == language_servers_to_stop.len()
10208                    });
10209                }
10210            });
10211        }
10212        for name in language_server_names_to_stop {
10213            language_servers_to_stop.extend(
10214                local
10215                    .language_server_ids
10216                    .iter()
10217                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10218            );
10219        }
10220
10221        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10222        let tasks = language_servers_to_stop
10223            .into_iter()
10224            .map(|server| self.stop_local_language_server(server, cx))
10225            .collect::<Vec<_>>();
10226
10227        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10228    }
10229
10230    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10231        let (worktree, relative_path) =
10232            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10233
10234        let project_path = ProjectPath {
10235            worktree_id: worktree.read(cx).id(),
10236            path: relative_path.into(),
10237        };
10238
10239        Some(
10240            self.buffer_store()
10241                .read(cx)
10242                .get_by_path(&project_path)?
10243                .read(cx),
10244        )
10245    }
10246
10247    #[cfg(any(test, feature = "test-support"))]
10248    pub fn update_diagnostics(
10249        &mut self,
10250        server_id: LanguageServerId,
10251        diagnostics: lsp::PublishDiagnosticsParams,
10252        result_id: Option<String>,
10253        source_kind: DiagnosticSourceKind,
10254        disk_based_sources: &[String],
10255        cx: &mut Context<Self>,
10256    ) -> Result<()> {
10257        self.merge_lsp_diagnostics(
10258            source_kind,
10259            vec![DocumentDiagnosticsUpdate {
10260                diagnostics,
10261                result_id,
10262                server_id,
10263                disk_based_sources: Cow::Borrowed(disk_based_sources),
10264            }],
10265            |_, _, _| false,
10266            cx,
10267        )
10268    }
10269
10270    pub fn merge_lsp_diagnostics(
10271        &mut self,
10272        source_kind: DiagnosticSourceKind,
10273        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10274        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10275        cx: &mut Context<Self>,
10276    ) -> Result<()> {
10277        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10278        let updates = lsp_diagnostics
10279            .into_iter()
10280            .filter_map(|update| {
10281                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10282                Some(DocumentDiagnosticsUpdate {
10283                    diagnostics: self.lsp_to_document_diagnostics(
10284                        abs_path,
10285                        source_kind,
10286                        update.server_id,
10287                        update.diagnostics,
10288                        &update.disk_based_sources,
10289                    ),
10290                    result_id: update.result_id,
10291                    server_id: update.server_id,
10292                    disk_based_sources: update.disk_based_sources,
10293                })
10294            })
10295            .collect();
10296        self.merge_diagnostic_entries(updates, merge, cx)?;
10297        Ok(())
10298    }
10299
10300    fn lsp_to_document_diagnostics(
10301        &mut self,
10302        document_abs_path: PathBuf,
10303        source_kind: DiagnosticSourceKind,
10304        server_id: LanguageServerId,
10305        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10306        disk_based_sources: &[String],
10307    ) -> DocumentDiagnostics {
10308        let mut diagnostics = Vec::default();
10309        let mut primary_diagnostic_group_ids = HashMap::default();
10310        let mut sources_by_group_id = HashMap::default();
10311        let mut supporting_diagnostics = HashMap::default();
10312
10313        let adapter = self.language_server_adapter_for_id(server_id);
10314
10315        // Ensure that primary diagnostics are always the most severe
10316        lsp_diagnostics
10317            .diagnostics
10318            .sort_by_key(|item| item.severity);
10319
10320        for diagnostic in &lsp_diagnostics.diagnostics {
10321            let source = diagnostic.source.as_ref();
10322            let range = range_from_lsp(diagnostic.range);
10323            let is_supporting = diagnostic
10324                .related_information
10325                .as_ref()
10326                .is_some_and(|infos| {
10327                    infos.iter().any(|info| {
10328                        primary_diagnostic_group_ids.contains_key(&(
10329                            source,
10330                            diagnostic.code.clone(),
10331                            range_from_lsp(info.location.range),
10332                        ))
10333                    })
10334                });
10335
10336            let is_unnecessary = diagnostic
10337                .tags
10338                .as_ref()
10339                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10340
10341            let underline = self
10342                .language_server_adapter_for_id(server_id)
10343                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10344
10345            if is_supporting {
10346                supporting_diagnostics.insert(
10347                    (source, diagnostic.code.clone(), range),
10348                    (diagnostic.severity, is_unnecessary),
10349                );
10350            } else {
10351                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10352                let is_disk_based =
10353                    source.is_some_and(|source| disk_based_sources.contains(source));
10354
10355                sources_by_group_id.insert(group_id, source);
10356                primary_diagnostic_group_ids
10357                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10358
10359                diagnostics.push(DiagnosticEntry {
10360                    range,
10361                    diagnostic: Diagnostic {
10362                        source: diagnostic.source.clone(),
10363                        source_kind,
10364                        code: diagnostic.code.clone(),
10365                        code_description: diagnostic
10366                            .code_description
10367                            .as_ref()
10368                            .and_then(|d| d.href.clone()),
10369                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10370                        markdown: adapter.as_ref().and_then(|adapter| {
10371                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10372                        }),
10373                        message: diagnostic.message.trim().to_string(),
10374                        group_id,
10375                        is_primary: true,
10376                        is_disk_based,
10377                        is_unnecessary,
10378                        underline,
10379                        data: diagnostic.data.clone(),
10380                    },
10381                });
10382                if let Some(infos) = &diagnostic.related_information {
10383                    for info in infos {
10384                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10385                            let range = range_from_lsp(info.location.range);
10386                            diagnostics.push(DiagnosticEntry {
10387                                range,
10388                                diagnostic: Diagnostic {
10389                                    source: diagnostic.source.clone(),
10390                                    source_kind,
10391                                    code: diagnostic.code.clone(),
10392                                    code_description: diagnostic
10393                                        .code_description
10394                                        .as_ref()
10395                                        .and_then(|d| d.href.clone()),
10396                                    severity: DiagnosticSeverity::INFORMATION,
10397                                    markdown: adapter.as_ref().and_then(|adapter| {
10398                                        adapter.diagnostic_message_to_markdown(&info.message)
10399                                    }),
10400                                    message: info.message.trim().to_string(),
10401                                    group_id,
10402                                    is_primary: false,
10403                                    is_disk_based,
10404                                    is_unnecessary: false,
10405                                    underline,
10406                                    data: diagnostic.data.clone(),
10407                                },
10408                            });
10409                        }
10410                    }
10411                }
10412            }
10413        }
10414
10415        for entry in &mut diagnostics {
10416            let diagnostic = &mut entry.diagnostic;
10417            if !diagnostic.is_primary {
10418                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10419                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10420                    source,
10421                    diagnostic.code.clone(),
10422                    entry.range.clone(),
10423                )) {
10424                    if let Some(severity) = severity {
10425                        diagnostic.severity = severity;
10426                    }
10427                    diagnostic.is_unnecessary = is_unnecessary;
10428                }
10429            }
10430        }
10431
10432        DocumentDiagnostics {
10433            diagnostics,
10434            document_abs_path,
10435            version: lsp_diagnostics.version,
10436        }
10437    }
10438
10439    fn insert_newly_running_language_server(
10440        &mut self,
10441        adapter: Arc<CachedLspAdapter>,
10442        language_server: Arc<LanguageServer>,
10443        server_id: LanguageServerId,
10444        key: LanguageServerSeed,
10445        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10446        cx: &mut Context<Self>,
10447    ) {
10448        let Some(local) = self.as_local_mut() else {
10449            return;
10450        };
10451        // If the language server for this key doesn't match the server id, don't store the
10452        // server. Which will cause it to be dropped, killing the process
10453        if local
10454            .language_server_ids
10455            .get(&key)
10456            .map(|state| state.id != server_id)
10457            .unwrap_or(false)
10458        {
10459            return;
10460        }
10461
10462        // Update language_servers collection with Running variant of LanguageServerState
10463        // indicating that the server is up and running and ready
10464        let workspace_folders = workspace_folders.lock().clone();
10465        language_server.set_workspace_folders(workspace_folders);
10466
10467        local.language_servers.insert(
10468            server_id,
10469            LanguageServerState::Running {
10470                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10471                    language_server.clone(),
10472                    cx,
10473                ),
10474                adapter: adapter.clone(),
10475                server: language_server.clone(),
10476                simulate_disk_based_diagnostics_completion: None,
10477            },
10478        );
10479        local
10480            .languages
10481            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10482        if let Some(file_ops_caps) = language_server
10483            .capabilities()
10484            .workspace
10485            .as_ref()
10486            .and_then(|ws| ws.file_operations.as_ref())
10487        {
10488            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10489            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10490            if did_rename_caps.or(will_rename_caps).is_some() {
10491                let watcher = RenamePathsWatchedForServer::default()
10492                    .with_did_rename_patterns(did_rename_caps)
10493                    .with_will_rename_patterns(will_rename_caps);
10494                local
10495                    .language_server_paths_watched_for_rename
10496                    .insert(server_id, watcher);
10497            }
10498        }
10499
10500        self.language_server_statuses.insert(
10501            server_id,
10502            LanguageServerStatus {
10503                name: language_server.name(),
10504                pending_work: Default::default(),
10505                has_pending_diagnostic_updates: false,
10506                progress_tokens: Default::default(),
10507                worktree: Some(key.worktree_id),
10508            },
10509        );
10510
10511        cx.emit(LspStoreEvent::LanguageServerAdded(
10512            server_id,
10513            language_server.name(),
10514            Some(key.worktree_id),
10515        ));
10516        cx.emit(LspStoreEvent::RefreshInlayHints);
10517
10518        let server_capabilities = language_server.capabilities();
10519        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10520            downstream_client
10521                .send(proto::StartLanguageServer {
10522                    project_id: *project_id,
10523                    server: Some(proto::LanguageServer {
10524                        id: server_id.to_proto(),
10525                        name: language_server.name().to_string(),
10526                        worktree_id: Some(key.worktree_id.to_proto()),
10527                    }),
10528                    capabilities: serde_json::to_string(&server_capabilities)
10529                        .expect("serializing server LSP capabilities"),
10530                })
10531                .log_err();
10532        }
10533        self.lsp_server_capabilities
10534            .insert(server_id, server_capabilities);
10535
10536        // Tell the language server about every open buffer in the worktree that matches the language.
10537        // Also check for buffers in worktrees that reused this server
10538        let mut worktrees_using_server = vec![key.worktree_id];
10539        if let Some(local) = self.as_local() {
10540            // Find all worktrees that have this server in their language server tree
10541            for (worktree_id, servers) in &local.lsp_tree.instances {
10542                if *worktree_id != key.worktree_id {
10543                    for server_map in servers.roots.values() {
10544                        if server_map
10545                            .values()
10546                            .any(|(node, _)| node.id() == Some(server_id))
10547                        {
10548                            worktrees_using_server.push(*worktree_id);
10549                        }
10550                    }
10551                }
10552            }
10553        }
10554
10555        let mut buffer_paths_registered = Vec::new();
10556        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10557            let mut lsp_adapters = HashMap::default();
10558            for buffer_handle in buffer_store.buffers() {
10559                let buffer = buffer_handle.read(cx);
10560                let file = match File::from_dyn(buffer.file()) {
10561                    Some(file) => file,
10562                    None => continue,
10563                };
10564                let language = match buffer.language() {
10565                    Some(language) => language,
10566                    None => continue,
10567                };
10568
10569                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10570                    || !lsp_adapters
10571                        .entry(language.name())
10572                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
10573                        .iter()
10574                        .any(|a| a.name == key.name)
10575                {
10576                    continue;
10577                }
10578                // didOpen
10579                let file = match file.as_local() {
10580                    Some(file) => file,
10581                    None => continue,
10582                };
10583
10584                let local = self.as_local_mut().unwrap();
10585
10586                let buffer_id = buffer.remote_id();
10587                if local.registered_buffers.contains_key(&buffer_id) {
10588                    let versions = local
10589                        .buffer_snapshots
10590                        .entry(buffer_id)
10591                        .or_default()
10592                        .entry(server_id)
10593                        .and_modify(|_| {
10594                            assert!(
10595                            false,
10596                            "There should not be an existing snapshot for a newly inserted buffer"
10597                        )
10598                        })
10599                        .or_insert_with(|| {
10600                            vec![LspBufferSnapshot {
10601                                version: 0,
10602                                snapshot: buffer.text_snapshot(),
10603                            }]
10604                        });
10605
10606                    let snapshot = versions.last().unwrap();
10607                    let version = snapshot.version;
10608                    let initial_snapshot = &snapshot.snapshot;
10609                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
10610                    language_server.register_buffer(
10611                        uri,
10612                        adapter.language_id(&language.name()),
10613                        version,
10614                        initial_snapshot.text(),
10615                    );
10616                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
10617                    local
10618                        .buffers_opened_in_servers
10619                        .entry(buffer_id)
10620                        .or_default()
10621                        .insert(server_id);
10622                }
10623                buffer_handle.update(cx, |buffer, cx| {
10624                    buffer.set_completion_triggers(
10625                        server_id,
10626                        language_server
10627                            .capabilities()
10628                            .completion_provider
10629                            .as_ref()
10630                            .and_then(|provider| {
10631                                provider
10632                                    .trigger_characters
10633                                    .as_ref()
10634                                    .map(|characters| characters.iter().cloned().collect())
10635                            })
10636                            .unwrap_or_default(),
10637                        cx,
10638                    )
10639                });
10640            }
10641        });
10642
10643        for (buffer_id, abs_path) in buffer_paths_registered {
10644            cx.emit(LspStoreEvent::LanguageServerUpdate {
10645                language_server_id: server_id,
10646                name: Some(adapter.name()),
10647                message: proto::update_language_server::Variant::RegisteredForBuffer(
10648                    proto::RegisteredForBuffer {
10649                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
10650                        buffer_id: buffer_id.to_proto(),
10651                    },
10652                ),
10653            });
10654        }
10655
10656        cx.notify();
10657    }
10658
10659    pub fn language_servers_running_disk_based_diagnostics(
10660        &self,
10661    ) -> impl Iterator<Item = LanguageServerId> + '_ {
10662        self.language_server_statuses
10663            .iter()
10664            .filter_map(|(id, status)| {
10665                if status.has_pending_diagnostic_updates {
10666                    Some(*id)
10667                } else {
10668                    None
10669                }
10670            })
10671    }
10672
10673    pub(crate) fn cancel_language_server_work_for_buffers(
10674        &mut self,
10675        buffers: impl IntoIterator<Item = Entity<Buffer>>,
10676        cx: &mut Context<Self>,
10677    ) {
10678        if let Some((client, project_id)) = self.upstream_client() {
10679            let request = client.request(proto::CancelLanguageServerWork {
10680                project_id,
10681                work: Some(proto::cancel_language_server_work::Work::Buffers(
10682                    proto::cancel_language_server_work::Buffers {
10683                        buffer_ids: buffers
10684                            .into_iter()
10685                            .map(|b| b.read(cx).remote_id().to_proto())
10686                            .collect(),
10687                    },
10688                )),
10689            });
10690            cx.background_spawn(request).detach_and_log_err(cx);
10691        } else if let Some(local) = self.as_local() {
10692            let servers = buffers
10693                .into_iter()
10694                .flat_map(|buffer| {
10695                    buffer.update(cx, |buffer, cx| {
10696                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
10697                    })
10698                })
10699                .collect::<HashSet<_>>();
10700            for server_id in servers {
10701                self.cancel_language_server_work(server_id, None, cx);
10702            }
10703        }
10704    }
10705
10706    pub(crate) fn cancel_language_server_work(
10707        &mut self,
10708        server_id: LanguageServerId,
10709        token_to_cancel: Option<String>,
10710        cx: &mut Context<Self>,
10711    ) {
10712        if let Some(local) = self.as_local() {
10713            let status = self.language_server_statuses.get(&server_id);
10714            let server = local.language_servers.get(&server_id);
10715            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
10716            {
10717                for (token, progress) in &status.pending_work {
10718                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
10719                        && token != token_to_cancel
10720                    {
10721                        continue;
10722                    }
10723                    if progress.is_cancellable {
10724                        server
10725                            .notify::<lsp::notification::WorkDoneProgressCancel>(
10726                                &WorkDoneProgressCancelParams {
10727                                    token: lsp::NumberOrString::String(token.clone()),
10728                                },
10729                            )
10730                            .ok();
10731                    }
10732                }
10733            }
10734        } else if let Some((client, project_id)) = self.upstream_client() {
10735            let request = client.request(proto::CancelLanguageServerWork {
10736                project_id,
10737                work: Some(
10738                    proto::cancel_language_server_work::Work::LanguageServerWork(
10739                        proto::cancel_language_server_work::LanguageServerWork {
10740                            language_server_id: server_id.to_proto(),
10741                            token: token_to_cancel,
10742                        },
10743                    ),
10744                ),
10745            });
10746            cx.background_spawn(request).detach_and_log_err(cx);
10747        }
10748    }
10749
10750    fn register_supplementary_language_server(
10751        &mut self,
10752        id: LanguageServerId,
10753        name: LanguageServerName,
10754        server: Arc<LanguageServer>,
10755        cx: &mut Context<Self>,
10756    ) {
10757        if let Some(local) = self.as_local_mut() {
10758            local
10759                .supplementary_language_servers
10760                .insert(id, (name.clone(), server));
10761            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
10762        }
10763    }
10764
10765    fn unregister_supplementary_language_server(
10766        &mut self,
10767        id: LanguageServerId,
10768        cx: &mut Context<Self>,
10769    ) {
10770        if let Some(local) = self.as_local_mut() {
10771            local.supplementary_language_servers.remove(&id);
10772            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
10773        }
10774    }
10775
10776    pub(crate) fn supplementary_language_servers(
10777        &self,
10778    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
10779        self.as_local().into_iter().flat_map(|local| {
10780            local
10781                .supplementary_language_servers
10782                .iter()
10783                .map(|(id, (name, _))| (*id, name.clone()))
10784        })
10785    }
10786
10787    pub fn language_server_adapter_for_id(
10788        &self,
10789        id: LanguageServerId,
10790    ) -> Option<Arc<CachedLspAdapter>> {
10791        self.as_local()
10792            .and_then(|local| local.language_servers.get(&id))
10793            .and_then(|language_server_state| match language_server_state {
10794                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
10795                _ => None,
10796            })
10797    }
10798
10799    pub(super) fn update_local_worktree_language_servers(
10800        &mut self,
10801        worktree_handle: &Entity<Worktree>,
10802        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
10803        cx: &mut Context<Self>,
10804    ) {
10805        if changes.is_empty() {
10806            return;
10807        }
10808
10809        let Some(local) = self.as_local() else { return };
10810
10811        local.prettier_store.update(cx, |prettier_store, cx| {
10812            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
10813        });
10814
10815        let worktree_id = worktree_handle.read(cx).id();
10816        let mut language_server_ids = local
10817            .language_server_ids
10818            .iter()
10819            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
10820            .collect::<Vec<_>>();
10821        language_server_ids.sort();
10822        language_server_ids.dedup();
10823
10824        let abs_path = worktree_handle.read(cx).abs_path();
10825        for server_id in &language_server_ids {
10826            if let Some(LanguageServerState::Running { server, .. }) =
10827                local.language_servers.get(server_id)
10828                && let Some(watched_paths) = local
10829                    .language_server_watched_paths
10830                    .get(server_id)
10831                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
10832            {
10833                let params = lsp::DidChangeWatchedFilesParams {
10834                    changes: changes
10835                        .iter()
10836                        .filter_map(|(path, _, change)| {
10837                            if !watched_paths.is_match(path) {
10838                                return None;
10839                            }
10840                            let typ = match change {
10841                                PathChange::Loaded => return None,
10842                                PathChange::Added => lsp::FileChangeType::CREATED,
10843                                PathChange::Removed => lsp::FileChangeType::DELETED,
10844                                PathChange::Updated => lsp::FileChangeType::CHANGED,
10845                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
10846                            };
10847                            Some(lsp::FileEvent {
10848                                uri: lsp::Uri::from_file_path(abs_path.join(path)).unwrap(),
10849                                typ,
10850                            })
10851                        })
10852                        .collect(),
10853                };
10854                if !params.changes.is_empty() {
10855                    server
10856                        .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
10857                        .ok();
10858                }
10859            }
10860        }
10861        for (path, _, _) in changes {
10862            if let Some(file_name) = path.file_name().and_then(|file_name| file_name.to_str())
10863                && local.watched_manifest_filenames.contains(file_name)
10864            {
10865                self.request_workspace_config_refresh();
10866                break;
10867            }
10868        }
10869    }
10870
10871    pub fn wait_for_remote_buffer(
10872        &mut self,
10873        id: BufferId,
10874        cx: &mut Context<Self>,
10875    ) -> Task<Result<Entity<Buffer>>> {
10876        self.buffer_store.update(cx, |buffer_store, cx| {
10877            buffer_store.wait_for_remote_buffer(id, cx)
10878        })
10879    }
10880
10881    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
10882        proto::Symbol {
10883            language_server_name: symbol.language_server_name.0.to_string(),
10884            source_worktree_id: symbol.source_worktree_id.to_proto(),
10885            language_server_id: symbol.source_language_server_id.to_proto(),
10886            worktree_id: symbol.path.worktree_id.to_proto(),
10887            path: symbol.path.path.as_ref().to_proto(),
10888            name: symbol.name.clone(),
10889            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
10890            start: Some(proto::PointUtf16 {
10891                row: symbol.range.start.0.row,
10892                column: symbol.range.start.0.column,
10893            }),
10894            end: Some(proto::PointUtf16 {
10895                row: symbol.range.end.0.row,
10896                column: symbol.range.end.0.column,
10897            }),
10898            signature: symbol.signature.to_vec(),
10899        }
10900    }
10901
10902    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
10903        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
10904        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
10905        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
10906        let path = ProjectPath {
10907            worktree_id,
10908            path: Arc::<Path>::from_proto(serialized_symbol.path),
10909        };
10910
10911        let start = serialized_symbol.start.context("invalid start")?;
10912        let end = serialized_symbol.end.context("invalid end")?;
10913        Ok(CoreSymbol {
10914            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
10915            source_worktree_id,
10916            source_language_server_id: LanguageServerId::from_proto(
10917                serialized_symbol.language_server_id,
10918            ),
10919            path,
10920            name: serialized_symbol.name,
10921            range: Unclipped(PointUtf16::new(start.row, start.column))
10922                ..Unclipped(PointUtf16::new(end.row, end.column)),
10923            kind,
10924            signature: serialized_symbol
10925                .signature
10926                .try_into()
10927                .map_err(|_| anyhow!("invalid signature"))?,
10928        })
10929    }
10930
10931    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
10932        let mut serialized_completion = proto::Completion {
10933            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
10934            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
10935            new_text: completion.new_text.clone(),
10936            ..proto::Completion::default()
10937        };
10938        match &completion.source {
10939            CompletionSource::Lsp {
10940                insert_range,
10941                server_id,
10942                lsp_completion,
10943                lsp_defaults,
10944                resolved,
10945            } => {
10946                let (old_insert_start, old_insert_end) = insert_range
10947                    .as_ref()
10948                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
10949                    .unzip();
10950
10951                serialized_completion.old_insert_start = old_insert_start;
10952                serialized_completion.old_insert_end = old_insert_end;
10953                serialized_completion.source = proto::completion::Source::Lsp as i32;
10954                serialized_completion.server_id = server_id.0 as u64;
10955                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
10956                serialized_completion.lsp_defaults = lsp_defaults
10957                    .as_deref()
10958                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
10959                serialized_completion.resolved = *resolved;
10960            }
10961            CompletionSource::BufferWord {
10962                word_range,
10963                resolved,
10964            } => {
10965                serialized_completion.source = proto::completion::Source::BufferWord as i32;
10966                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
10967                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
10968                serialized_completion.resolved = *resolved;
10969            }
10970            CompletionSource::Custom => {
10971                serialized_completion.source = proto::completion::Source::Custom as i32;
10972                serialized_completion.resolved = true;
10973            }
10974            CompletionSource::Dap { sort_text } => {
10975                serialized_completion.source = proto::completion::Source::Dap as i32;
10976                serialized_completion.sort_text = Some(sort_text.clone());
10977            }
10978        }
10979
10980        serialized_completion
10981    }
10982
10983    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
10984        let old_replace_start = completion
10985            .old_replace_start
10986            .and_then(deserialize_anchor)
10987            .context("invalid old start")?;
10988        let old_replace_end = completion
10989            .old_replace_end
10990            .and_then(deserialize_anchor)
10991            .context("invalid old end")?;
10992        let insert_range = {
10993            match completion.old_insert_start.zip(completion.old_insert_end) {
10994                Some((start, end)) => {
10995                    let start = deserialize_anchor(start).context("invalid insert old start")?;
10996                    let end = deserialize_anchor(end).context("invalid insert old end")?;
10997                    Some(start..end)
10998                }
10999                None => None,
11000            }
11001        };
11002        Ok(CoreCompletion {
11003            replace_range: old_replace_start..old_replace_end,
11004            new_text: completion.new_text,
11005            source: match proto::completion::Source::from_i32(completion.source) {
11006                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11007                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11008                    insert_range,
11009                    server_id: LanguageServerId::from_proto(completion.server_id),
11010                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11011                    lsp_defaults: completion
11012                        .lsp_defaults
11013                        .as_deref()
11014                        .map(serde_json::from_slice)
11015                        .transpose()?,
11016                    resolved: completion.resolved,
11017                },
11018                Some(proto::completion::Source::BufferWord) => {
11019                    let word_range = completion
11020                        .buffer_word_start
11021                        .and_then(deserialize_anchor)
11022                        .context("invalid buffer word start")?
11023                        ..completion
11024                            .buffer_word_end
11025                            .and_then(deserialize_anchor)
11026                            .context("invalid buffer word end")?;
11027                    CompletionSource::BufferWord {
11028                        word_range,
11029                        resolved: completion.resolved,
11030                    }
11031                }
11032                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11033                    sort_text: completion
11034                        .sort_text
11035                        .context("expected sort text to exist")?,
11036                },
11037                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11038            },
11039        })
11040    }
11041
11042    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11043        let (kind, lsp_action) = match &action.lsp_action {
11044            LspAction::Action(code_action) => (
11045                proto::code_action::Kind::Action as i32,
11046                serde_json::to_vec(code_action).unwrap(),
11047            ),
11048            LspAction::Command(command) => (
11049                proto::code_action::Kind::Command as i32,
11050                serde_json::to_vec(command).unwrap(),
11051            ),
11052            LspAction::CodeLens(code_lens) => (
11053                proto::code_action::Kind::CodeLens as i32,
11054                serde_json::to_vec(code_lens).unwrap(),
11055            ),
11056        };
11057
11058        proto::CodeAction {
11059            server_id: action.server_id.0 as u64,
11060            start: Some(serialize_anchor(&action.range.start)),
11061            end: Some(serialize_anchor(&action.range.end)),
11062            lsp_action,
11063            kind,
11064            resolved: action.resolved,
11065        }
11066    }
11067
11068    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11069        let start = action
11070            .start
11071            .and_then(deserialize_anchor)
11072            .context("invalid start")?;
11073        let end = action
11074            .end
11075            .and_then(deserialize_anchor)
11076            .context("invalid end")?;
11077        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11078            Some(proto::code_action::Kind::Action) => {
11079                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11080            }
11081            Some(proto::code_action::Kind::Command) => {
11082                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11083            }
11084            Some(proto::code_action::Kind::CodeLens) => {
11085                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11086            }
11087            None => anyhow::bail!("Unknown action kind {}", action.kind),
11088        };
11089        Ok(CodeAction {
11090            server_id: LanguageServerId(action.server_id as usize),
11091            range: start..end,
11092            resolved: action.resolved,
11093            lsp_action,
11094        })
11095    }
11096
11097    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11098        match &formatting_result {
11099            Ok(_) => self.last_formatting_failure = None,
11100            Err(error) => {
11101                let error_string = format!("{error:#}");
11102                log::error!("Formatting failed: {error_string}");
11103                self.last_formatting_failure
11104                    .replace(error_string.lines().join(" "));
11105            }
11106        }
11107    }
11108
11109    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11110        self.lsp_server_capabilities.remove(&for_server);
11111        for buffer_colors in self.lsp_document_colors.values_mut() {
11112            buffer_colors.colors.remove(&for_server);
11113            buffer_colors.cache_version += 1;
11114        }
11115        for buffer_lens in self.lsp_code_lens.values_mut() {
11116            buffer_lens.lens.remove(&for_server);
11117        }
11118        if let Some(local) = self.as_local_mut() {
11119            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11120            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11121                buffer_servers.remove(&for_server);
11122            }
11123        }
11124    }
11125
11126    pub fn result_id(
11127        &self,
11128        server_id: LanguageServerId,
11129        buffer_id: BufferId,
11130        cx: &App,
11131    ) -> Option<String> {
11132        let abs_path = self
11133            .buffer_store
11134            .read(cx)
11135            .get(buffer_id)
11136            .and_then(|b| File::from_dyn(b.read(cx).file()))
11137            .map(|f| f.abs_path(cx))?;
11138        self.as_local()?
11139            .buffer_pull_diagnostics_result_ids
11140            .get(&server_id)?
11141            .get(&abs_path)?
11142            .clone()
11143    }
11144
11145    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11146        let Some(local) = self.as_local() else {
11147            return HashMap::default();
11148        };
11149        local
11150            .buffer_pull_diagnostics_result_ids
11151            .get(&server_id)
11152            .into_iter()
11153            .flatten()
11154            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11155            .collect()
11156    }
11157
11158    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11159        if let Some(LanguageServerState::Running {
11160            workspace_refresh_task: Some(workspace_refresh_task),
11161            ..
11162        }) = self
11163            .as_local_mut()
11164            .and_then(|local| local.language_servers.get_mut(&server_id))
11165        {
11166            workspace_refresh_task.refresh_tx.try_send(()).ok();
11167        }
11168    }
11169
11170    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11171        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11172            return;
11173        };
11174        let Some(local) = self.as_local_mut() else {
11175            return;
11176        };
11177
11178        for server_id in buffer.update(cx, |buffer, cx| {
11179            local.language_server_ids_for_buffer(buffer, cx)
11180        }) {
11181            if let Some(LanguageServerState::Running {
11182                workspace_refresh_task: Some(workspace_refresh_task),
11183                ..
11184            }) = local.language_servers.get_mut(&server_id)
11185            {
11186                workspace_refresh_task.refresh_tx.try_send(()).ok();
11187            }
11188        }
11189    }
11190
11191    fn apply_workspace_diagnostic_report(
11192        &mut self,
11193        server_id: LanguageServerId,
11194        report: lsp::WorkspaceDiagnosticReportResult,
11195        cx: &mut Context<Self>,
11196    ) {
11197        let workspace_diagnostics =
11198            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11199        let mut unchanged_buffers = HashSet::default();
11200        let mut changed_buffers = HashSet::default();
11201        let workspace_diagnostics_updates = workspace_diagnostics
11202            .into_iter()
11203            .filter_map(
11204                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11205                    LspPullDiagnostics::Response {
11206                        server_id,
11207                        uri,
11208                        diagnostics,
11209                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11210                    LspPullDiagnostics::Default => None,
11211                },
11212            )
11213            .fold(
11214                HashMap::default(),
11215                |mut acc, (server_id, uri, diagnostics, version)| {
11216                    let (result_id, diagnostics) = match diagnostics {
11217                        PulledDiagnostics::Unchanged { result_id } => {
11218                            unchanged_buffers.insert(uri.clone());
11219                            (Some(result_id), Vec::new())
11220                        }
11221                        PulledDiagnostics::Changed {
11222                            result_id,
11223                            diagnostics,
11224                        } => {
11225                            changed_buffers.insert(uri.clone());
11226                            (result_id, diagnostics)
11227                        }
11228                    };
11229                    let disk_based_sources = Cow::Owned(
11230                        self.language_server_adapter_for_id(server_id)
11231                            .as_ref()
11232                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11233                            .unwrap_or(&[])
11234                            .to_vec(),
11235                    );
11236                    acc.entry(server_id)
11237                        .or_insert_with(Vec::new)
11238                        .push(DocumentDiagnosticsUpdate {
11239                            server_id,
11240                            diagnostics: lsp::PublishDiagnosticsParams {
11241                                uri,
11242                                diagnostics,
11243                                version,
11244                            },
11245                            result_id,
11246                            disk_based_sources,
11247                        });
11248                    acc
11249                },
11250            );
11251
11252        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11253            self.merge_lsp_diagnostics(
11254                DiagnosticSourceKind::Pulled,
11255                diagnostic_updates,
11256                |buffer, old_diagnostic, cx| {
11257                    File::from_dyn(buffer.file())
11258                        .and_then(|file| {
11259                            let abs_path = file.as_local()?.abs_path(cx);
11260                            lsp::Uri::from_file_path(abs_path).ok()
11261                        })
11262                        .is_none_or(|buffer_uri| {
11263                            unchanged_buffers.contains(&buffer_uri)
11264                                || match old_diagnostic.source_kind {
11265                                    DiagnosticSourceKind::Pulled => {
11266                                        !changed_buffers.contains(&buffer_uri)
11267                                    }
11268                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11269                                        true
11270                                    }
11271                                }
11272                        })
11273                },
11274                cx,
11275            )
11276            .log_err();
11277        }
11278    }
11279
11280    fn register_server_capabilities(
11281        &mut self,
11282        server_id: LanguageServerId,
11283        params: lsp::RegistrationParams,
11284        cx: &mut Context<Self>,
11285    ) -> anyhow::Result<()> {
11286        let server = self
11287            .language_server_for_id(server_id)
11288            .with_context(|| format!("no server {server_id} found"))?;
11289        for reg in params.registrations {
11290            match reg.method.as_str() {
11291                "workspace/didChangeWatchedFiles" => {
11292                    if let Some(options) = reg.register_options {
11293                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11294                            let caps = serde_json::from_value(options)?;
11295                            local_lsp_store
11296                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11297                            true
11298                        } else {
11299                            false
11300                        };
11301                        if notify {
11302                            notify_server_capabilities_updated(&server, cx);
11303                        }
11304                    }
11305                }
11306                "workspace/didChangeConfiguration" => {
11307                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11308                }
11309                "workspace/didChangeWorkspaceFolders" => {
11310                    // In this case register options is an empty object, we can ignore it
11311                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11312                        supported: Some(true),
11313                        change_notifications: Some(OneOf::Right(reg.id)),
11314                    };
11315                    server.update_capabilities(|capabilities| {
11316                        capabilities
11317                            .workspace
11318                            .get_or_insert_default()
11319                            .workspace_folders = Some(caps);
11320                    });
11321                    notify_server_capabilities_updated(&server, cx);
11322                }
11323                "workspace/symbol" => {
11324                    let options = parse_register_capabilities(reg)?;
11325                    server.update_capabilities(|capabilities| {
11326                        capabilities.workspace_symbol_provider = Some(options);
11327                    });
11328                    notify_server_capabilities_updated(&server, cx);
11329                }
11330                "workspace/fileOperations" => {
11331                    if let Some(options) = reg.register_options {
11332                        let caps = serde_json::from_value(options)?;
11333                        server.update_capabilities(|capabilities| {
11334                            capabilities
11335                                .workspace
11336                                .get_or_insert_default()
11337                                .file_operations = Some(caps);
11338                        });
11339                        notify_server_capabilities_updated(&server, cx);
11340                    }
11341                }
11342                "workspace/executeCommand" => {
11343                    if let Some(options) = reg.register_options {
11344                        let options = serde_json::from_value(options)?;
11345                        server.update_capabilities(|capabilities| {
11346                            capabilities.execute_command_provider = Some(options);
11347                        });
11348                        notify_server_capabilities_updated(&server, cx);
11349                    }
11350                }
11351                "textDocument/rangeFormatting" => {
11352                    let options = parse_register_capabilities(reg)?;
11353                    server.update_capabilities(|capabilities| {
11354                        capabilities.document_range_formatting_provider = Some(options);
11355                    });
11356                    notify_server_capabilities_updated(&server, cx);
11357                }
11358                "textDocument/onTypeFormatting" => {
11359                    if let Some(options) = reg
11360                        .register_options
11361                        .map(serde_json::from_value)
11362                        .transpose()?
11363                    {
11364                        server.update_capabilities(|capabilities| {
11365                            capabilities.document_on_type_formatting_provider = Some(options);
11366                        });
11367                        notify_server_capabilities_updated(&server, cx);
11368                    }
11369                }
11370                "textDocument/formatting" => {
11371                    let options = parse_register_capabilities(reg)?;
11372                    server.update_capabilities(|capabilities| {
11373                        capabilities.document_formatting_provider = Some(options);
11374                    });
11375                    notify_server_capabilities_updated(&server, cx);
11376                }
11377                "textDocument/rename" => {
11378                    let options = parse_register_capabilities(reg)?;
11379                    server.update_capabilities(|capabilities| {
11380                        capabilities.rename_provider = Some(options);
11381                    });
11382                    notify_server_capabilities_updated(&server, cx);
11383                }
11384                "textDocument/inlayHint" => {
11385                    let options = parse_register_capabilities(reg)?;
11386                    server.update_capabilities(|capabilities| {
11387                        capabilities.inlay_hint_provider = Some(options);
11388                    });
11389                    notify_server_capabilities_updated(&server, cx);
11390                }
11391                "textDocument/documentSymbol" => {
11392                    let options = parse_register_capabilities(reg)?;
11393                    server.update_capabilities(|capabilities| {
11394                        capabilities.document_symbol_provider = Some(options);
11395                    });
11396                    notify_server_capabilities_updated(&server, cx);
11397                }
11398                "textDocument/codeAction" => {
11399                    let options = parse_register_capabilities(reg)?;
11400                    let provider = match options {
11401                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11402                        OneOf::Right(caps) => caps,
11403                    };
11404                    server.update_capabilities(|capabilities| {
11405                        capabilities.code_action_provider = Some(provider);
11406                    });
11407                    notify_server_capabilities_updated(&server, cx);
11408                }
11409                "textDocument/definition" => {
11410                    let options = parse_register_capabilities(reg)?;
11411                    server.update_capabilities(|capabilities| {
11412                        capabilities.definition_provider = Some(options);
11413                    });
11414                    notify_server_capabilities_updated(&server, cx);
11415                }
11416                "textDocument/completion" => {
11417                    if let Some(caps) = reg
11418                        .register_options
11419                        .map(serde_json::from_value)
11420                        .transpose()?
11421                    {
11422                        server.update_capabilities(|capabilities| {
11423                            capabilities.completion_provider = Some(caps);
11424                        });
11425                        notify_server_capabilities_updated(&server, cx);
11426                    }
11427                }
11428                "textDocument/hover" => {
11429                    let options = parse_register_capabilities(reg)?;
11430                    let provider = match options {
11431                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11432                        OneOf::Right(caps) => caps,
11433                    };
11434                    server.update_capabilities(|capabilities| {
11435                        capabilities.hover_provider = Some(provider);
11436                    });
11437                    notify_server_capabilities_updated(&server, cx);
11438                }
11439                "textDocument/signatureHelp" => {
11440                    if let Some(caps) = reg
11441                        .register_options
11442                        .map(serde_json::from_value)
11443                        .transpose()?
11444                    {
11445                        server.update_capabilities(|capabilities| {
11446                            capabilities.signature_help_provider = Some(caps);
11447                        });
11448                        notify_server_capabilities_updated(&server, cx);
11449                    }
11450                }
11451                "textDocument/didChange" => {
11452                    if let Some(sync_kind) = reg
11453                        .register_options
11454                        .and_then(|opts| opts.get("syncKind").cloned())
11455                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11456                        .transpose()?
11457                    {
11458                        server.update_capabilities(|capabilities| {
11459                            let mut sync_options =
11460                                Self::take_text_document_sync_options(capabilities);
11461                            sync_options.change = Some(sync_kind);
11462                            capabilities.text_document_sync =
11463                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11464                        });
11465                        notify_server_capabilities_updated(&server, cx);
11466                    }
11467                }
11468                "textDocument/didSave" => {
11469                    if let Some(include_text) = reg
11470                        .register_options
11471                        .map(|opts| {
11472                            let transpose = opts
11473                                .get("includeText")
11474                                .cloned()
11475                                .map(serde_json::from_value::<Option<bool>>)
11476                                .transpose();
11477                            match transpose {
11478                                Ok(value) => Ok(value.flatten()),
11479                                Err(e) => Err(e),
11480                            }
11481                        })
11482                        .transpose()?
11483                    {
11484                        server.update_capabilities(|capabilities| {
11485                            let mut sync_options =
11486                                Self::take_text_document_sync_options(capabilities);
11487                            sync_options.save =
11488                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11489                                    include_text,
11490                                }));
11491                            capabilities.text_document_sync =
11492                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11493                        });
11494                        notify_server_capabilities_updated(&server, cx);
11495                    }
11496                }
11497                "textDocument/codeLens" => {
11498                    if let Some(caps) = reg
11499                        .register_options
11500                        .map(serde_json::from_value)
11501                        .transpose()?
11502                    {
11503                        server.update_capabilities(|capabilities| {
11504                            capabilities.code_lens_provider = Some(caps);
11505                        });
11506                        notify_server_capabilities_updated(&server, cx);
11507                    }
11508                }
11509                "textDocument/diagnostic" => {
11510                    if let Some(caps) = reg
11511                        .register_options
11512                        .map(serde_json::from_value)
11513                        .transpose()?
11514                    {
11515                        server.update_capabilities(|capabilities| {
11516                            capabilities.diagnostic_provider = Some(caps);
11517                        });
11518                        notify_server_capabilities_updated(&server, cx);
11519                    }
11520                }
11521                "textDocument/documentColor" => {
11522                    let options = parse_register_capabilities(reg)?;
11523                    let provider = match options {
11524                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
11525                        OneOf::Right(caps) => caps,
11526                    };
11527                    server.update_capabilities(|capabilities| {
11528                        capabilities.color_provider = Some(provider);
11529                    });
11530                    notify_server_capabilities_updated(&server, cx);
11531                }
11532                _ => log::warn!("unhandled capability registration: {reg:?}"),
11533            }
11534        }
11535
11536        Ok(())
11537    }
11538
11539    fn unregister_server_capabilities(
11540        &mut self,
11541        server_id: LanguageServerId,
11542        params: lsp::UnregistrationParams,
11543        cx: &mut Context<Self>,
11544    ) -> anyhow::Result<()> {
11545        let server = self
11546            .language_server_for_id(server_id)
11547            .with_context(|| format!("no server {server_id} found"))?;
11548        for unreg in params.unregisterations.iter() {
11549            match unreg.method.as_str() {
11550                "workspace/didChangeWatchedFiles" => {
11551                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11552                        local_lsp_store
11553                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11554                        true
11555                    } else {
11556                        false
11557                    };
11558                    if notify {
11559                        notify_server_capabilities_updated(&server, cx);
11560                    }
11561                }
11562                "workspace/didChangeConfiguration" => {
11563                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11564                }
11565                "workspace/didChangeWorkspaceFolders" => {
11566                    server.update_capabilities(|capabilities| {
11567                        capabilities
11568                            .workspace
11569                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11570                                workspace_folders: None,
11571                                file_operations: None,
11572                            })
11573                            .workspace_folders = None;
11574                    });
11575                    notify_server_capabilities_updated(&server, cx);
11576                }
11577                "workspace/symbol" => {
11578                    server.update_capabilities(|capabilities| {
11579                        capabilities.workspace_symbol_provider = None
11580                    });
11581                    notify_server_capabilities_updated(&server, cx);
11582                }
11583                "workspace/fileOperations" => {
11584                    server.update_capabilities(|capabilities| {
11585                        capabilities
11586                            .workspace
11587                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11588                                workspace_folders: None,
11589                                file_operations: None,
11590                            })
11591                            .file_operations = None;
11592                    });
11593                    notify_server_capabilities_updated(&server, cx);
11594                }
11595                "workspace/executeCommand" => {
11596                    server.update_capabilities(|capabilities| {
11597                        capabilities.execute_command_provider = None;
11598                    });
11599                    notify_server_capabilities_updated(&server, cx);
11600                }
11601                "textDocument/rangeFormatting" => {
11602                    server.update_capabilities(|capabilities| {
11603                        capabilities.document_range_formatting_provider = None
11604                    });
11605                    notify_server_capabilities_updated(&server, cx);
11606                }
11607                "textDocument/onTypeFormatting" => {
11608                    server.update_capabilities(|capabilities| {
11609                        capabilities.document_on_type_formatting_provider = None;
11610                    });
11611                    notify_server_capabilities_updated(&server, cx);
11612                }
11613                "textDocument/formatting" => {
11614                    server.update_capabilities(|capabilities| {
11615                        capabilities.document_formatting_provider = None;
11616                    });
11617                    notify_server_capabilities_updated(&server, cx);
11618                }
11619                "textDocument/rename" => {
11620                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
11621                    notify_server_capabilities_updated(&server, cx);
11622                }
11623                "textDocument/codeAction" => {
11624                    server.update_capabilities(|capabilities| {
11625                        capabilities.code_action_provider = None;
11626                    });
11627                    notify_server_capabilities_updated(&server, cx);
11628                }
11629                "textDocument/definition" => {
11630                    server.update_capabilities(|capabilities| {
11631                        capabilities.definition_provider = None;
11632                    });
11633                    notify_server_capabilities_updated(&server, cx);
11634                }
11635                "textDocument/completion" => {
11636                    server.update_capabilities(|capabilities| {
11637                        capabilities.completion_provider = None;
11638                    });
11639                    notify_server_capabilities_updated(&server, cx);
11640                }
11641                "textDocument/hover" => {
11642                    server.update_capabilities(|capabilities| {
11643                        capabilities.hover_provider = None;
11644                    });
11645                    notify_server_capabilities_updated(&server, cx);
11646                }
11647                "textDocument/signatureHelp" => {
11648                    server.update_capabilities(|capabilities| {
11649                        capabilities.signature_help_provider = None;
11650                    });
11651                    notify_server_capabilities_updated(&server, cx);
11652                }
11653                "textDocument/didChange" => {
11654                    server.update_capabilities(|capabilities| {
11655                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11656                        sync_options.change = None;
11657                        capabilities.text_document_sync =
11658                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11659                    });
11660                    notify_server_capabilities_updated(&server, cx);
11661                }
11662                "textDocument/didSave" => {
11663                    server.update_capabilities(|capabilities| {
11664                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11665                        sync_options.save = None;
11666                        capabilities.text_document_sync =
11667                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11668                    });
11669                    notify_server_capabilities_updated(&server, cx);
11670                }
11671                "textDocument/codeLens" => {
11672                    server.update_capabilities(|capabilities| {
11673                        capabilities.code_lens_provider = None;
11674                    });
11675                    notify_server_capabilities_updated(&server, cx);
11676                }
11677                "textDocument/diagnostic" => {
11678                    server.update_capabilities(|capabilities| {
11679                        capabilities.diagnostic_provider = None;
11680                    });
11681                    notify_server_capabilities_updated(&server, cx);
11682                }
11683                "textDocument/documentColor" => {
11684                    server.update_capabilities(|capabilities| {
11685                        capabilities.color_provider = None;
11686                    });
11687                    notify_server_capabilities_updated(&server, cx);
11688                }
11689                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
11690            }
11691        }
11692
11693        Ok(())
11694    }
11695
11696    async fn query_lsp_locally<T>(
11697        lsp_store: Entity<Self>,
11698        sender_id: proto::PeerId,
11699        lsp_request_id: LspRequestId,
11700        proto_request: T::ProtoRequest,
11701        position: Option<Anchor>,
11702        mut cx: AsyncApp,
11703    ) -> Result<()>
11704    where
11705        T: LspCommand + Clone,
11706        T::ProtoRequest: proto::LspRequestMessage,
11707        <T::ProtoRequest as proto::RequestMessage>::Response:
11708            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
11709    {
11710        let buffer_id = BufferId::new(proto_request.buffer_id())?;
11711        let version = deserialize_version(proto_request.buffer_version());
11712        let buffer = lsp_store.update(&mut cx, |this, cx| {
11713            this.buffer_store.read(cx).get_existing(buffer_id)
11714        })??;
11715        buffer
11716            .update(&mut cx, |buffer, _| {
11717                buffer.wait_for_version(version.clone())
11718            })?
11719            .await?;
11720        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
11721        let request =
11722            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
11723        lsp_store.update(&mut cx, |lsp_store, cx| {
11724            let request_task =
11725                lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx);
11726            let existing_queries = lsp_store
11727                .running_lsp_requests
11728                .entry(TypeId::of::<T>())
11729                .or_default();
11730            if T::ProtoRequest::stop_previous_requests()
11731                || buffer_version.changed_since(&existing_queries.0)
11732            {
11733                existing_queries.1.clear();
11734            }
11735            existing_queries.1.insert(
11736                lsp_request_id,
11737                cx.spawn(async move |lsp_store, cx| {
11738                    let response = request_task.await;
11739                    lsp_store
11740                        .update(cx, |lsp_store, cx| {
11741                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
11742                            {
11743                                let response = response
11744                                    .into_iter()
11745                                    .map(|(server_id, response)| {
11746                                        (
11747                                            server_id.to_proto(),
11748                                            T::response_to_proto(
11749                                                response,
11750                                                lsp_store,
11751                                                sender_id,
11752                                                &buffer_version,
11753                                                cx,
11754                                            )
11755                                            .into(),
11756                                        )
11757                                    })
11758                                    .collect::<HashMap<_, _>>();
11759                                match client.send_lsp_response::<T::ProtoRequest>(
11760                                    project_id,
11761                                    lsp_request_id,
11762                                    response,
11763                                ) {
11764                                    Ok(()) => {}
11765                                    Err(e) => {
11766                                        log::error!("Failed to send LSP response: {e:#}",)
11767                                    }
11768                                }
11769                            }
11770                        })
11771                        .ok();
11772                }),
11773            );
11774        })?;
11775        Ok(())
11776    }
11777
11778    fn take_text_document_sync_options(
11779        capabilities: &mut lsp::ServerCapabilities,
11780    ) -> lsp::TextDocumentSyncOptions {
11781        match capabilities.text_document_sync.take() {
11782            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
11783            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
11784                let mut sync_options = lsp::TextDocumentSyncOptions::default();
11785                sync_options.change = Some(sync_kind);
11786                sync_options
11787            }
11788            None => lsp::TextDocumentSyncOptions::default(),
11789        }
11790    }
11791
11792    #[cfg(any(test, feature = "test-support"))]
11793    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
11794        let data = self.lsp_code_lens.get_mut(&buffer_id)?;
11795        Some(data.update.take()?.1)
11796    }
11797
11798    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
11799        self.downstream_client.clone()
11800    }
11801
11802    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
11803        self.worktree_store.clone()
11804    }
11805}
11806
11807// Registration with registerOptions as null, should fallback to true.
11808// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
11809fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
11810    reg: lsp::Registration,
11811) -> Result<OneOf<bool, T>> {
11812    Ok(match reg.register_options {
11813        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
11814        None => OneOf::Left(true),
11815    })
11816}
11817
11818fn subscribe_to_binary_statuses(
11819    languages: &Arc<LanguageRegistry>,
11820    cx: &mut Context<'_, LspStore>,
11821) -> Task<()> {
11822    let mut server_statuses = languages.language_server_binary_statuses();
11823    cx.spawn(async move |lsp_store, cx| {
11824        while let Some((server_name, binary_status)) = server_statuses.next().await {
11825            if lsp_store
11826                .update(cx, |_, cx| {
11827                    let mut message = None;
11828                    let binary_status = match binary_status {
11829                        BinaryStatus::None => proto::ServerBinaryStatus::None,
11830                        BinaryStatus::CheckingForUpdate => {
11831                            proto::ServerBinaryStatus::CheckingForUpdate
11832                        }
11833                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
11834                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
11835                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
11836                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
11837                        BinaryStatus::Failed { error } => {
11838                            message = Some(error);
11839                            proto::ServerBinaryStatus::Failed
11840                        }
11841                    };
11842                    cx.emit(LspStoreEvent::LanguageServerUpdate {
11843                        // Binary updates are about the binary that might not have any language server id at that point.
11844                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
11845                        language_server_id: LanguageServerId(0),
11846                        name: Some(server_name),
11847                        message: proto::update_language_server::Variant::StatusUpdate(
11848                            proto::StatusUpdate {
11849                                message,
11850                                status: Some(proto::status_update::Status::Binary(
11851                                    binary_status as i32,
11852                                )),
11853                            },
11854                        ),
11855                    });
11856                })
11857                .is_err()
11858            {
11859                break;
11860            }
11861        }
11862    })
11863}
11864
11865fn lsp_workspace_diagnostics_refresh(
11866    server: Arc<LanguageServer>,
11867    cx: &mut Context<'_, LspStore>,
11868) -> Option<WorkspaceRefreshTask> {
11869    let identifier = match server.capabilities().diagnostic_provider? {
11870        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
11871            if !diagnostic_options.workspace_diagnostics {
11872                return None;
11873            }
11874            diagnostic_options.identifier
11875        }
11876        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
11877            let diagnostic_options = registration_options.diagnostic_options;
11878            if !diagnostic_options.workspace_diagnostics {
11879                return None;
11880            }
11881            diagnostic_options.identifier
11882        }
11883    };
11884
11885    let (progress_tx, mut progress_rx) = mpsc::channel(1);
11886    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
11887    refresh_tx.try_send(()).ok();
11888
11889    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
11890        let mut attempts = 0;
11891        let max_attempts = 50;
11892        let mut requests = 0;
11893
11894        loop {
11895            let Some(()) = refresh_rx.recv().await else {
11896                return;
11897            };
11898
11899            'request: loop {
11900                requests += 1;
11901                if attempts > max_attempts {
11902                    log::error!(
11903                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
11904                    );
11905                    return;
11906                }
11907                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
11908                cx.background_executor()
11909                    .timer(Duration::from_millis(backoff_millis))
11910                    .await;
11911                attempts += 1;
11912
11913                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
11914                    lsp_store
11915                        .all_result_ids(server.server_id())
11916                        .into_iter()
11917                        .filter_map(|(abs_path, result_id)| {
11918                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
11919                            Some(lsp::PreviousResultId {
11920                                uri,
11921                                value: result_id,
11922                            })
11923                        })
11924                        .collect()
11925                }) else {
11926                    return;
11927                };
11928
11929                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
11930
11931                progress_rx.try_recv().ok();
11932                let timer =
11933                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
11934                let progress = pin!(progress_rx.recv().fuse());
11935                let response_result = server
11936                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
11937                        lsp::WorkspaceDiagnosticParams {
11938                            previous_result_ids,
11939                            identifier: identifier.clone(),
11940                            work_done_progress_params: Default::default(),
11941                            partial_result_params: lsp::PartialResultParams {
11942                                partial_result_token: Some(lsp::ProgressToken::String(token)),
11943                            },
11944                        },
11945                        select(timer, progress).then(|either| match either {
11946                            Either::Left((message, ..)) => ready(message).left_future(),
11947                            Either::Right(..) => pending::<String>().right_future(),
11948                        }),
11949                    )
11950                    .await;
11951
11952                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
11953                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
11954                match response_result {
11955                    ConnectionResult::Timeout => {
11956                        log::error!("Timeout during workspace diagnostics pull");
11957                        continue 'request;
11958                    }
11959                    ConnectionResult::ConnectionReset => {
11960                        log::error!("Server closed a workspace diagnostics pull request");
11961                        continue 'request;
11962                    }
11963                    ConnectionResult::Result(Err(e)) => {
11964                        log::error!("Error during workspace diagnostics pull: {e:#}");
11965                        break 'request;
11966                    }
11967                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
11968                        attempts = 0;
11969                        if lsp_store
11970                            .update(cx, |lsp_store, cx| {
11971                                lsp_store.apply_workspace_diagnostic_report(
11972                                    server.server_id(),
11973                                    pulled_diagnostics,
11974                                    cx,
11975                                )
11976                            })
11977                            .is_err()
11978                        {
11979                            return;
11980                        }
11981                        break 'request;
11982                    }
11983                }
11984            }
11985        }
11986    });
11987
11988    Some(WorkspaceRefreshTask {
11989        refresh_tx,
11990        progress_tx,
11991        task: workspace_query_language_server,
11992    })
11993}
11994
11995fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
11996    let CompletionSource::BufferWord {
11997        word_range,
11998        resolved,
11999    } = &mut completion.source
12000    else {
12001        return;
12002    };
12003    if *resolved {
12004        return;
12005    }
12006
12007    if completion.new_text
12008        != snapshot
12009            .text_for_range(word_range.clone())
12010            .collect::<String>()
12011    {
12012        return;
12013    }
12014
12015    let mut offset = 0;
12016    for chunk in snapshot.chunks(word_range.clone(), true) {
12017        let end_offset = offset + chunk.text.len();
12018        if let Some(highlight_id) = chunk.syntax_highlight_id {
12019            completion
12020                .label
12021                .runs
12022                .push((offset..end_offset, highlight_id));
12023        }
12024        offset = end_offset;
12025    }
12026    *resolved = true;
12027}
12028
12029impl EventEmitter<LspStoreEvent> for LspStore {}
12030
12031fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12032    hover
12033        .contents
12034        .retain(|hover_block| !hover_block.text.trim().is_empty());
12035    if hover.contents.is_empty() {
12036        None
12037    } else {
12038        Some(hover)
12039    }
12040}
12041
12042async fn populate_labels_for_completions(
12043    new_completions: Vec<CoreCompletion>,
12044    language: Option<Arc<Language>>,
12045    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12046) -> Vec<Completion> {
12047    let lsp_completions = new_completions
12048        .iter()
12049        .filter_map(|new_completion| {
12050            new_completion
12051                .source
12052                .lsp_completion(true)
12053                .map(|lsp_completion| lsp_completion.into_owned())
12054        })
12055        .collect::<Vec<_>>();
12056
12057    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12058        lsp_adapter
12059            .labels_for_completions(&lsp_completions, language)
12060            .await
12061            .log_err()
12062            .unwrap_or_default()
12063    } else {
12064        Vec::new()
12065    }
12066    .into_iter()
12067    .fuse();
12068
12069    let mut completions = Vec::new();
12070    for completion in new_completions {
12071        match completion.source.lsp_completion(true) {
12072            Some(lsp_completion) => {
12073                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12074
12075                let mut label = labels.next().flatten().unwrap_or_else(|| {
12076                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12077                });
12078                ensure_uniform_list_compatible_label(&mut label);
12079                completions.push(Completion {
12080                    label,
12081                    documentation,
12082                    replace_range: completion.replace_range,
12083                    new_text: completion.new_text,
12084                    insert_text_mode: lsp_completion.insert_text_mode,
12085                    source: completion.source,
12086                    icon_path: None,
12087                    confirm: None,
12088                });
12089            }
12090            None => {
12091                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12092                ensure_uniform_list_compatible_label(&mut label);
12093                completions.push(Completion {
12094                    label,
12095                    documentation: None,
12096                    replace_range: completion.replace_range,
12097                    new_text: completion.new_text,
12098                    source: completion.source,
12099                    insert_text_mode: None,
12100                    icon_path: None,
12101                    confirm: None,
12102                });
12103            }
12104        }
12105    }
12106    completions
12107}
12108
12109#[derive(Debug)]
12110pub enum LanguageServerToQuery {
12111    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12112    FirstCapable,
12113    /// Query a specific language server.
12114    Other(LanguageServerId),
12115}
12116
12117#[derive(Default)]
12118struct RenamePathsWatchedForServer {
12119    did_rename: Vec<RenameActionPredicate>,
12120    will_rename: Vec<RenameActionPredicate>,
12121}
12122
12123impl RenamePathsWatchedForServer {
12124    fn with_did_rename_patterns(
12125        mut self,
12126        did_rename: Option<&FileOperationRegistrationOptions>,
12127    ) -> Self {
12128        if let Some(did_rename) = did_rename {
12129            self.did_rename = did_rename
12130                .filters
12131                .iter()
12132                .filter_map(|filter| filter.try_into().log_err())
12133                .collect();
12134        }
12135        self
12136    }
12137    fn with_will_rename_patterns(
12138        mut self,
12139        will_rename: Option<&FileOperationRegistrationOptions>,
12140    ) -> Self {
12141        if let Some(will_rename) = will_rename {
12142            self.will_rename = will_rename
12143                .filters
12144                .iter()
12145                .filter_map(|filter| filter.try_into().log_err())
12146                .collect();
12147        }
12148        self
12149    }
12150
12151    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12152        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12153    }
12154    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12155        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12156    }
12157}
12158
12159impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12160    type Error = globset::Error;
12161    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12162        Ok(Self {
12163            kind: ops.pattern.matches.clone(),
12164            glob: GlobBuilder::new(&ops.pattern.glob)
12165                .case_insensitive(
12166                    ops.pattern
12167                        .options
12168                        .as_ref()
12169                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12170                )
12171                .build()?
12172                .compile_matcher(),
12173        })
12174    }
12175}
12176struct RenameActionPredicate {
12177    glob: GlobMatcher,
12178    kind: Option<FileOperationPatternKind>,
12179}
12180
12181impl RenameActionPredicate {
12182    // Returns true if language server should be notified
12183    fn eval(&self, path: &str, is_dir: bool) -> bool {
12184        self.kind.as_ref().is_none_or(|kind| {
12185            let expected_kind = if is_dir {
12186                FileOperationPatternKind::Folder
12187            } else {
12188                FileOperationPatternKind::File
12189            };
12190            kind == &expected_kind
12191        }) && self.glob.is_match(path)
12192    }
12193}
12194
12195#[derive(Default)]
12196struct LanguageServerWatchedPaths {
12197    worktree_paths: HashMap<WorktreeId, GlobSet>,
12198    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12199}
12200
12201#[derive(Default)]
12202struct LanguageServerWatchedPathsBuilder {
12203    worktree_paths: HashMap<WorktreeId, GlobSet>,
12204    abs_paths: HashMap<Arc<Path>, GlobSet>,
12205}
12206
12207impl LanguageServerWatchedPathsBuilder {
12208    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12209        self.worktree_paths.insert(worktree_id, glob_set);
12210    }
12211    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12212        self.abs_paths.insert(path, glob_set);
12213    }
12214    fn build(
12215        self,
12216        fs: Arc<dyn Fs>,
12217        language_server_id: LanguageServerId,
12218        cx: &mut Context<LspStore>,
12219    ) -> LanguageServerWatchedPaths {
12220        let project = cx.weak_entity();
12221
12222        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12223        let abs_paths = self
12224            .abs_paths
12225            .into_iter()
12226            .map(|(abs_path, globset)| {
12227                let task = cx.spawn({
12228                    let abs_path = abs_path.clone();
12229                    let fs = fs.clone();
12230
12231                    let lsp_store = project.clone();
12232                    async move |_, cx| {
12233                        maybe!(async move {
12234                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12235                            while let Some(update) = push_updates.0.next().await {
12236                                let action = lsp_store
12237                                    .update(cx, |this, _| {
12238                                        let Some(local) = this.as_local() else {
12239                                            return ControlFlow::Break(());
12240                                        };
12241                                        let Some(watcher) = local
12242                                            .language_server_watched_paths
12243                                            .get(&language_server_id)
12244                                        else {
12245                                            return ControlFlow::Break(());
12246                                        };
12247                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12248                                            "Watched abs path is not registered with a watcher",
12249                                        );
12250                                        let matching_entries = update
12251                                            .into_iter()
12252                                            .filter(|event| globs.is_match(&event.path))
12253                                            .collect::<Vec<_>>();
12254                                        this.lsp_notify_abs_paths_changed(
12255                                            language_server_id,
12256                                            matching_entries,
12257                                        );
12258                                        ControlFlow::Continue(())
12259                                    })
12260                                    .ok()?;
12261
12262                                if action.is_break() {
12263                                    break;
12264                                }
12265                            }
12266                            Some(())
12267                        })
12268                        .await;
12269                    }
12270                });
12271                (abs_path, (globset, task))
12272            })
12273            .collect();
12274        LanguageServerWatchedPaths {
12275            worktree_paths: self.worktree_paths,
12276            abs_paths,
12277        }
12278    }
12279}
12280
12281struct LspBufferSnapshot {
12282    version: i32,
12283    snapshot: TextBufferSnapshot,
12284}
12285
12286/// A prompt requested by LSP server.
12287#[derive(Clone, Debug)]
12288pub struct LanguageServerPromptRequest {
12289    pub level: PromptLevel,
12290    pub message: String,
12291    pub actions: Vec<MessageActionItem>,
12292    pub lsp_name: String,
12293    pub(crate) response_channel: Sender<MessageActionItem>,
12294}
12295
12296impl LanguageServerPromptRequest {
12297    pub async fn respond(self, index: usize) -> Option<()> {
12298        if let Some(response) = self.actions.into_iter().nth(index) {
12299            self.response_channel.send(response).await.ok()
12300        } else {
12301            None
12302        }
12303    }
12304}
12305impl PartialEq for LanguageServerPromptRequest {
12306    fn eq(&self, other: &Self) -> bool {
12307        self.message == other.message && self.actions == other.actions
12308    }
12309}
12310
12311#[derive(Clone, Debug, PartialEq)]
12312pub enum LanguageServerLogType {
12313    Log(MessageType),
12314    Trace { verbose_info: Option<String> },
12315    Rpc { received: bool },
12316}
12317
12318impl LanguageServerLogType {
12319    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12320        match self {
12321            Self::Log(log_type) => {
12322                use proto::log_message::LogLevel;
12323                let level = match *log_type {
12324                    MessageType::ERROR => LogLevel::Error,
12325                    MessageType::WARNING => LogLevel::Warning,
12326                    MessageType::INFO => LogLevel::Info,
12327                    MessageType::LOG => LogLevel::Log,
12328                    other => {
12329                        log::warn!("Unknown lsp log message type: {other:?}");
12330                        LogLevel::Log
12331                    }
12332                };
12333                proto::language_server_log::LogType::Log(proto::LogMessage {
12334                    level: level as i32,
12335                })
12336            }
12337            Self::Trace { verbose_info } => {
12338                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12339                    verbose_info: verbose_info.to_owned(),
12340                })
12341            }
12342            Self::Rpc { received } => {
12343                let kind = if *received {
12344                    proto::rpc_message::Kind::Received
12345                } else {
12346                    proto::rpc_message::Kind::Sent
12347                };
12348                let kind = kind as i32;
12349                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12350            }
12351        }
12352    }
12353
12354    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12355        use proto::log_message::LogLevel;
12356        use proto::rpc_message;
12357        match log_type {
12358            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12359                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12360                    LogLevel::Error => MessageType::ERROR,
12361                    LogLevel::Warning => MessageType::WARNING,
12362                    LogLevel::Info => MessageType::INFO,
12363                    LogLevel::Log => MessageType::LOG,
12364                },
12365            ),
12366            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12367                verbose_info: trace_message.verbose_info,
12368            },
12369            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12370                received: match rpc_message::Kind::from_i32(message.kind)
12371                    .unwrap_or(rpc_message::Kind::Received)
12372                {
12373                    rpc_message::Kind::Received => true,
12374                    rpc_message::Kind::Sent => false,
12375                },
12376            },
12377        }
12378    }
12379}
12380
12381pub struct WorkspaceRefreshTask {
12382    refresh_tx: mpsc::Sender<()>,
12383    progress_tx: mpsc::Sender<()>,
12384    #[allow(dead_code)]
12385    task: Task<()>,
12386}
12387
12388pub enum LanguageServerState {
12389    Starting {
12390        startup: Task<Option<Arc<LanguageServer>>>,
12391        /// List of language servers that will be added to the workspace once it's initialization completes.
12392        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
12393    },
12394
12395    Running {
12396        adapter: Arc<CachedLspAdapter>,
12397        server: Arc<LanguageServer>,
12398        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12399        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12400    },
12401}
12402
12403impl LanguageServerState {
12404    fn add_workspace_folder(&self, uri: Uri) {
12405        match self {
12406            LanguageServerState::Starting {
12407                pending_workspace_folders,
12408                ..
12409            } => {
12410                pending_workspace_folders.lock().insert(uri);
12411            }
12412            LanguageServerState::Running { server, .. } => {
12413                server.add_workspace_folder(uri);
12414            }
12415        }
12416    }
12417    fn _remove_workspace_folder(&self, uri: Uri) {
12418        match self {
12419            LanguageServerState::Starting {
12420                pending_workspace_folders,
12421                ..
12422            } => {
12423                pending_workspace_folders.lock().remove(&uri);
12424            }
12425            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12426        }
12427    }
12428}
12429
12430impl std::fmt::Debug for LanguageServerState {
12431    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12432        match self {
12433            LanguageServerState::Starting { .. } => {
12434                f.debug_struct("LanguageServerState::Starting").finish()
12435            }
12436            LanguageServerState::Running { .. } => {
12437                f.debug_struct("LanguageServerState::Running").finish()
12438            }
12439        }
12440    }
12441}
12442
12443#[derive(Clone, Debug, Serialize)]
12444pub struct LanguageServerProgress {
12445    pub is_disk_based_diagnostics_progress: bool,
12446    pub is_cancellable: bool,
12447    pub title: Option<String>,
12448    pub message: Option<String>,
12449    pub percentage: Option<usize>,
12450    #[serde(skip_serializing)]
12451    pub last_update_at: Instant,
12452}
12453
12454#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12455pub struct DiagnosticSummary {
12456    pub error_count: usize,
12457    pub warning_count: usize,
12458}
12459
12460impl DiagnosticSummary {
12461    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12462        let mut this = Self {
12463            error_count: 0,
12464            warning_count: 0,
12465        };
12466
12467        for entry in diagnostics {
12468            if entry.diagnostic.is_primary {
12469                match entry.diagnostic.severity {
12470                    DiagnosticSeverity::ERROR => this.error_count += 1,
12471                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12472                    _ => {}
12473                }
12474            }
12475        }
12476
12477        this
12478    }
12479
12480    pub fn is_empty(&self) -> bool {
12481        self.error_count == 0 && self.warning_count == 0
12482    }
12483
12484    pub fn to_proto(
12485        self,
12486        language_server_id: LanguageServerId,
12487        path: &Path,
12488    ) -> proto::DiagnosticSummary {
12489        proto::DiagnosticSummary {
12490            path: path.to_proto(),
12491            language_server_id: language_server_id.0 as u64,
12492            error_count: self.error_count as u32,
12493            warning_count: self.warning_count as u32,
12494        }
12495    }
12496}
12497
12498#[derive(Clone, Debug)]
12499pub enum CompletionDocumentation {
12500    /// There is no documentation for this completion.
12501    Undocumented,
12502    /// A single line of documentation.
12503    SingleLine(SharedString),
12504    /// Multiple lines of plain text documentation.
12505    MultiLinePlainText(SharedString),
12506    /// Markdown documentation.
12507    MultiLineMarkdown(SharedString),
12508    /// Both single line and multiple lines of plain text documentation.
12509    SingleLineAndMultiLinePlainText {
12510        single_line: SharedString,
12511        plain_text: Option<SharedString>,
12512    },
12513}
12514
12515impl CompletionDocumentation {
12516    #[cfg(any(test, feature = "test-support"))]
12517    pub fn text(&self) -> SharedString {
12518        match self {
12519            CompletionDocumentation::Undocumented => "".into(),
12520            CompletionDocumentation::SingleLine(s) => s.clone(),
12521            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
12522            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
12523            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
12524                single_line.clone()
12525            }
12526        }
12527    }
12528}
12529
12530impl From<lsp::Documentation> for CompletionDocumentation {
12531    fn from(docs: lsp::Documentation) -> Self {
12532        match docs {
12533            lsp::Documentation::String(text) => {
12534                if text.lines().count() <= 1 {
12535                    CompletionDocumentation::SingleLine(text.into())
12536                } else {
12537                    CompletionDocumentation::MultiLinePlainText(text.into())
12538                }
12539            }
12540
12541            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
12542                lsp::MarkupKind::PlainText => {
12543                    if value.lines().count() <= 1 {
12544                        CompletionDocumentation::SingleLine(value.into())
12545                    } else {
12546                        CompletionDocumentation::MultiLinePlainText(value.into())
12547                    }
12548                }
12549
12550                lsp::MarkupKind::Markdown => {
12551                    CompletionDocumentation::MultiLineMarkdown(value.into())
12552                }
12553            },
12554        }
12555    }
12556}
12557
12558fn glob_literal_prefix(glob: &Path) -> PathBuf {
12559    glob.components()
12560        .take_while(|component| match component {
12561            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
12562            _ => true,
12563        })
12564        .collect()
12565}
12566
12567pub struct SshLspAdapter {
12568    name: LanguageServerName,
12569    binary: LanguageServerBinary,
12570    initialization_options: Option<String>,
12571    code_action_kinds: Option<Vec<CodeActionKind>>,
12572}
12573
12574impl SshLspAdapter {
12575    pub fn new(
12576        name: LanguageServerName,
12577        binary: LanguageServerBinary,
12578        initialization_options: Option<String>,
12579        code_action_kinds: Option<String>,
12580    ) -> Self {
12581        Self {
12582            name,
12583            binary,
12584            initialization_options,
12585            code_action_kinds: code_action_kinds
12586                .as_ref()
12587                .and_then(|c| serde_json::from_str(c).ok()),
12588        }
12589    }
12590}
12591
12592impl LspInstaller for SshLspAdapter {
12593    type BinaryVersion = ();
12594    async fn check_if_user_installed(
12595        &self,
12596        _: &dyn LspAdapterDelegate,
12597        _: Option<Toolchain>,
12598        _: &AsyncApp,
12599    ) -> Option<LanguageServerBinary> {
12600        Some(self.binary.clone())
12601    }
12602
12603    async fn cached_server_binary(
12604        &self,
12605        _: PathBuf,
12606        _: &dyn LspAdapterDelegate,
12607    ) -> Option<LanguageServerBinary> {
12608        None
12609    }
12610
12611    async fn fetch_latest_server_version(
12612        &self,
12613        _: &dyn LspAdapterDelegate,
12614        _: bool,
12615        _: &mut AsyncApp,
12616    ) -> Result<()> {
12617        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
12618    }
12619
12620    async fn fetch_server_binary(
12621        &self,
12622        _: (),
12623        _: PathBuf,
12624        _: &dyn LspAdapterDelegate,
12625    ) -> Result<LanguageServerBinary> {
12626        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
12627    }
12628}
12629
12630#[async_trait(?Send)]
12631impl LspAdapter for SshLspAdapter {
12632    fn name(&self) -> LanguageServerName {
12633        self.name.clone()
12634    }
12635
12636    async fn initialization_options(
12637        self: Arc<Self>,
12638        _: &Arc<dyn LspAdapterDelegate>,
12639    ) -> Result<Option<serde_json::Value>> {
12640        let Some(options) = &self.initialization_options else {
12641            return Ok(None);
12642        };
12643        let result = serde_json::from_str(options)?;
12644        Ok(result)
12645    }
12646
12647    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
12648        self.code_action_kinds.clone()
12649    }
12650}
12651
12652pub fn language_server_settings<'a>(
12653    delegate: &'a dyn LspAdapterDelegate,
12654    language: &LanguageServerName,
12655    cx: &'a App,
12656) -> Option<&'a LspSettings> {
12657    language_server_settings_for(
12658        SettingsLocation {
12659            worktree_id: delegate.worktree_id(),
12660            path: delegate.worktree_root_path(),
12661        },
12662        language,
12663        cx,
12664    )
12665}
12666
12667pub(crate) fn language_server_settings_for<'a>(
12668    location: SettingsLocation<'a>,
12669    language: &LanguageServerName,
12670    cx: &'a App,
12671) -> Option<&'a LspSettings> {
12672    ProjectSettings::get(Some(location), cx).lsp.get(language)
12673}
12674
12675pub struct LocalLspAdapterDelegate {
12676    lsp_store: WeakEntity<LspStore>,
12677    worktree: worktree::Snapshot,
12678    fs: Arc<dyn Fs>,
12679    http_client: Arc<dyn HttpClient>,
12680    language_registry: Arc<LanguageRegistry>,
12681    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
12682}
12683
12684impl LocalLspAdapterDelegate {
12685    pub fn new(
12686        language_registry: Arc<LanguageRegistry>,
12687        environment: &Entity<ProjectEnvironment>,
12688        lsp_store: WeakEntity<LspStore>,
12689        worktree: &Entity<Worktree>,
12690        http_client: Arc<dyn HttpClient>,
12691        fs: Arc<dyn Fs>,
12692        cx: &mut App,
12693    ) -> Arc<Self> {
12694        let load_shell_env_task = environment.update(cx, |env, cx| {
12695            env.get_worktree_environment(worktree.clone(), cx)
12696        });
12697
12698        Arc::new(Self {
12699            lsp_store,
12700            worktree: worktree.read(cx).snapshot(),
12701            fs,
12702            http_client,
12703            language_registry,
12704            load_shell_env_task,
12705        })
12706    }
12707
12708    fn from_local_lsp(
12709        local: &LocalLspStore,
12710        worktree: &Entity<Worktree>,
12711        cx: &mut App,
12712    ) -> Arc<Self> {
12713        Self::new(
12714            local.languages.clone(),
12715            &local.environment,
12716            local.weak.clone(),
12717            worktree,
12718            local.http_client.clone(),
12719            local.fs.clone(),
12720            cx,
12721        )
12722    }
12723}
12724
12725#[async_trait]
12726impl LspAdapterDelegate for LocalLspAdapterDelegate {
12727    fn show_notification(&self, message: &str, cx: &mut App) {
12728        self.lsp_store
12729            .update(cx, |_, cx| {
12730                cx.emit(LspStoreEvent::Notification(message.to_owned()))
12731            })
12732            .ok();
12733    }
12734
12735    fn http_client(&self) -> Arc<dyn HttpClient> {
12736        self.http_client.clone()
12737    }
12738
12739    fn worktree_id(&self) -> WorktreeId {
12740        self.worktree.id()
12741    }
12742
12743    fn worktree_root_path(&self) -> &Path {
12744        self.worktree.abs_path().as_ref()
12745    }
12746
12747    async fn shell_env(&self) -> HashMap<String, String> {
12748        let task = self.load_shell_env_task.clone();
12749        task.await.unwrap_or_default()
12750    }
12751
12752    async fn npm_package_installed_version(
12753        &self,
12754        package_name: &str,
12755    ) -> Result<Option<(PathBuf, String)>> {
12756        let local_package_directory = self.worktree_root_path();
12757        let node_modules_directory = local_package_directory.join("node_modules");
12758
12759        if let Some(version) =
12760            read_package_installed_version(node_modules_directory.clone(), package_name).await?
12761        {
12762            return Ok(Some((node_modules_directory, version)));
12763        }
12764        let Some(npm) = self.which("npm".as_ref()).await else {
12765            log::warn!(
12766                "Failed to find npm executable for {:?}",
12767                local_package_directory
12768            );
12769            return Ok(None);
12770        };
12771
12772        let env = self.shell_env().await;
12773        let output = util::command::new_smol_command(&npm)
12774            .args(["root", "-g"])
12775            .envs(env)
12776            .current_dir(local_package_directory)
12777            .output()
12778            .await?;
12779        let global_node_modules =
12780            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
12781
12782        if let Some(version) =
12783            read_package_installed_version(global_node_modules.clone(), package_name).await?
12784        {
12785            return Ok(Some((global_node_modules, version)));
12786        }
12787        return Ok(None);
12788    }
12789
12790    #[cfg(not(target_os = "windows"))]
12791    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12792        let worktree_abs_path = self.worktree.abs_path();
12793        let shell_path = self.shell_env().await.get("PATH").cloned();
12794        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
12795    }
12796
12797    #[cfg(target_os = "windows")]
12798    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12799        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
12800        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
12801        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
12802        which::which(command).ok()
12803    }
12804
12805    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
12806        let working_dir = self.worktree_root_path();
12807        let output = util::command::new_smol_command(&command.path)
12808            .args(command.arguments)
12809            .envs(command.env.clone().unwrap_or_default())
12810            .current_dir(working_dir)
12811            .output()
12812            .await?;
12813
12814        anyhow::ensure!(
12815            output.status.success(),
12816            "{}, stdout: {:?}, stderr: {:?}",
12817            output.status,
12818            String::from_utf8_lossy(&output.stdout),
12819            String::from_utf8_lossy(&output.stderr)
12820        );
12821        Ok(())
12822    }
12823
12824    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
12825        self.language_registry
12826            .update_lsp_binary_status(server_name, status);
12827    }
12828
12829    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
12830        self.language_registry
12831            .all_lsp_adapters()
12832            .into_iter()
12833            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
12834            .collect()
12835    }
12836
12837    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
12838        let dir = self.language_registry.language_server_download_dir(name)?;
12839
12840        if !dir.exists() {
12841            smol::fs::create_dir_all(&dir)
12842                .await
12843                .context("failed to create container directory")
12844                .log_err()?;
12845        }
12846
12847        Some(dir)
12848    }
12849
12850    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
12851        let entry = self
12852            .worktree
12853            .entry_for_path(&path)
12854            .with_context(|| format!("no worktree entry for path {path:?}"))?;
12855        let abs_path = self
12856            .worktree
12857            .absolutize(&entry.path)
12858            .with_context(|| format!("cannot absolutize path {path:?}"))?;
12859
12860        self.fs.load(&abs_path).await
12861    }
12862}
12863
12864async fn populate_labels_for_symbols(
12865    symbols: Vec<CoreSymbol>,
12866    language_registry: &Arc<LanguageRegistry>,
12867    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12868    output: &mut Vec<Symbol>,
12869) {
12870    #[allow(clippy::mutable_key_type)]
12871    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
12872
12873    let mut unknown_paths = BTreeSet::new();
12874    for symbol in symbols {
12875        let language = language_registry
12876            .language_for_file_path(&symbol.path.path)
12877            .await
12878            .ok()
12879            .or_else(|| {
12880                unknown_paths.insert(symbol.path.path.clone());
12881                None
12882            });
12883        symbols_by_language
12884            .entry(language)
12885            .or_default()
12886            .push(symbol);
12887    }
12888
12889    for unknown_path in unknown_paths {
12890        log::info!(
12891            "no language found for symbol path {}",
12892            unknown_path.display()
12893        );
12894    }
12895
12896    let mut label_params = Vec::new();
12897    for (language, mut symbols) in symbols_by_language {
12898        label_params.clear();
12899        label_params.extend(
12900            symbols
12901                .iter_mut()
12902                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
12903        );
12904
12905        let mut labels = Vec::new();
12906        if let Some(language) = language {
12907            let lsp_adapter = lsp_adapter.clone().or_else(|| {
12908                language_registry
12909                    .lsp_adapters(&language.name())
12910                    .first()
12911                    .cloned()
12912            });
12913            if let Some(lsp_adapter) = lsp_adapter {
12914                labels = lsp_adapter
12915                    .labels_for_symbols(&label_params, &language)
12916                    .await
12917                    .log_err()
12918                    .unwrap_or_default();
12919            }
12920        }
12921
12922        for ((symbol, (name, _)), label) in symbols
12923            .into_iter()
12924            .zip(label_params.drain(..))
12925            .zip(labels.into_iter().chain(iter::repeat(None)))
12926        {
12927            output.push(Symbol {
12928                language_server_name: symbol.language_server_name,
12929                source_worktree_id: symbol.source_worktree_id,
12930                source_language_server_id: symbol.source_language_server_id,
12931                path: symbol.path,
12932                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
12933                name,
12934                kind: symbol.kind,
12935                range: symbol.range,
12936                signature: symbol.signature,
12937            });
12938        }
12939    }
12940}
12941
12942fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
12943    match server.capabilities().text_document_sync.as_ref()? {
12944        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
12945            // Server wants didSave but didn't specify includeText.
12946            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
12947            // Server doesn't want didSave at all.
12948            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
12949            // Server provided SaveOptions.
12950            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
12951                Some(save_options.include_text.unwrap_or(false))
12952            }
12953        },
12954        // We do not have any save info. Kind affects didChange only.
12955        lsp::TextDocumentSyncCapability::Kind(_) => None,
12956    }
12957}
12958
12959/// Completion items are displayed in a `UniformList`.
12960/// Usually, those items are single-line strings, but in LSP responses,
12961/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
12962/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
12963/// 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,
12964/// breaking the completions menu presentation.
12965///
12966/// 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.
12967fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
12968    let mut new_text = String::with_capacity(label.text.len());
12969    let mut offset_map = vec![0; label.text.len() + 1];
12970    let mut last_char_was_space = false;
12971    let mut new_idx = 0;
12972    let chars = label.text.char_indices().fuse();
12973    let mut newlines_removed = false;
12974
12975    for (idx, c) in chars {
12976        offset_map[idx] = new_idx;
12977
12978        match c {
12979            '\n' if last_char_was_space => {
12980                newlines_removed = true;
12981            }
12982            '\t' | ' ' if last_char_was_space => {}
12983            '\n' if !last_char_was_space => {
12984                new_text.push(' ');
12985                new_idx += 1;
12986                last_char_was_space = true;
12987                newlines_removed = true;
12988            }
12989            ' ' | '\t' => {
12990                new_text.push(' ');
12991                new_idx += 1;
12992                last_char_was_space = true;
12993            }
12994            _ => {
12995                new_text.push(c);
12996                new_idx += c.len_utf8();
12997                last_char_was_space = false;
12998            }
12999        }
13000    }
13001    offset_map[label.text.len()] = new_idx;
13002
13003    // Only modify the label if newlines were removed.
13004    if !newlines_removed {
13005        return;
13006    }
13007
13008    let last_index = new_idx;
13009    let mut run_ranges_errors = Vec::new();
13010    label.runs.retain_mut(|(range, _)| {
13011        match offset_map.get(range.start) {
13012            Some(&start) => range.start = start,
13013            None => {
13014                run_ranges_errors.push(range.clone());
13015                return false;
13016            }
13017        }
13018
13019        match offset_map.get(range.end) {
13020            Some(&end) => range.end = end,
13021            None => {
13022                run_ranges_errors.push(range.clone());
13023                range.end = last_index;
13024            }
13025        }
13026        true
13027    });
13028    if !run_ranges_errors.is_empty() {
13029        log::error!(
13030            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13031            label.text
13032        );
13033    }
13034
13035    let mut wrong_filter_range = None;
13036    if label.filter_range == (0..label.text.len()) {
13037        label.filter_range = 0..new_text.len();
13038    } else {
13039        let mut original_filter_range = Some(label.filter_range.clone());
13040        match offset_map.get(label.filter_range.start) {
13041            Some(&start) => label.filter_range.start = start,
13042            None => {
13043                wrong_filter_range = original_filter_range.take();
13044                label.filter_range.start = last_index;
13045            }
13046        }
13047
13048        match offset_map.get(label.filter_range.end) {
13049            Some(&end) => label.filter_range.end = end,
13050            None => {
13051                wrong_filter_range = original_filter_range.take();
13052                label.filter_range.end = last_index;
13053            }
13054        }
13055    }
13056    if let Some(wrong_filter_range) = wrong_filter_range {
13057        log::error!(
13058            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13059            label.text
13060        );
13061    }
13062
13063    label.text = new_text;
13064}
13065
13066#[cfg(test)]
13067mod tests {
13068    use language::HighlightId;
13069
13070    use super::*;
13071
13072    #[test]
13073    fn test_glob_literal_prefix() {
13074        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13075        assert_eq!(
13076            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13077            Path::new("node_modules")
13078        );
13079        assert_eq!(
13080            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13081            Path::new("foo")
13082        );
13083        assert_eq!(
13084            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13085            Path::new("foo/bar/baz.js")
13086        );
13087
13088        #[cfg(target_os = "windows")]
13089        {
13090            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13091            assert_eq!(
13092                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13093                Path::new("node_modules")
13094            );
13095            assert_eq!(
13096                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13097                Path::new("foo")
13098            );
13099            assert_eq!(
13100                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13101                Path::new("foo/bar/baz.js")
13102            );
13103        }
13104    }
13105
13106    #[test]
13107    fn test_multi_len_chars_normalization() {
13108        let mut label = CodeLabel {
13109            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13110            runs: vec![(0..6, HighlightId(1))],
13111            filter_range: 0..6,
13112        };
13113        ensure_uniform_list_compatible_label(&mut label);
13114        assert_eq!(
13115            label,
13116            CodeLabel {
13117                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13118                runs: vec![(0..6, HighlightId(1))],
13119                filter_range: 0..6,
13120            }
13121        );
13122    }
13123}