lsp_store.rs

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