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;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        log_store::{GlobalLogStore, LanguageServerKind},
   33    },
   34    manifest_tree::{
   35        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   36        ManifestTree,
   37    },
   38    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   39    project_settings::{LspSettings, ProjectSettings},
   40    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   41    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   59    Subscription, Task, WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76    row_chunk::RowChunk,
   77};
   78use lsp::{
   79    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   80    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   81    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   82    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   83    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   84    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   85    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   86    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   87};
   88use node_runtime::read_package_installed_version;
   89use parking_lot::Mutex;
   90use postage::{mpsc, sink::Sink, stream::Stream, watch};
   91use rand::prelude::*;
   92use rpc::{
   93    AnyProtoClient, ErrorCode, ErrorExt as _,
   94    proto::{LspRequestId, LspRequestMessage as _},
   95};
   96use semver::Version;
   97use serde::Serialize;
   98use serde_json::Value;
   99use settings::{Settings, SettingsLocation, SettingsStore};
  100use sha2::{Digest, Sha256};
  101use smol::channel::{Receiver, Sender};
  102use snippet::Snippet;
  103use std::{
  104    any::TypeId,
  105    borrow::Cow,
  106    cell::RefCell,
  107    cmp::{Ordering, Reverse},
  108    collections::hash_map,
  109    convert::TryInto,
  110    ffi::OsStr,
  111    future::ready,
  112    iter, mem,
  113    ops::{ControlFlow, Range},
  114    path::{self, Path, PathBuf},
  115    pin::pin,
  116    rc::Rc,
  117    sync::{
  118        Arc,
  119        atomic::{self, AtomicUsize},
  120    },
  121    time::{Duration, Instant},
  122    vec,
  123};
  124use sum_tree::Dimensions;
  125use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  126
  127use util::{
  128    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  129    paths::{PathStyle, SanitizedPath},
  130    post_inc,
  131    redact::redact_command,
  132    rel_path::RelPath,
  133};
  134
  135pub use fs::*;
  136pub use language::Location;
  137pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  138#[cfg(any(test, feature = "test-support"))]
  139pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  140pub use worktree::{
  141    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  142    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  143};
  144
  145const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  146pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  147const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  148const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  149
  150#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  151pub enum ProgressToken {
  152    Number(i32),
  153    String(SharedString),
  154}
  155
  156impl std::fmt::Display for ProgressToken {
  157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  158        match self {
  159            Self::Number(number) => write!(f, "{number}"),
  160            Self::String(string) => write!(f, "{string}"),
  161        }
  162    }
  163}
  164
  165impl ProgressToken {
  166    fn from_lsp(value: lsp::NumberOrString) -> Self {
  167        match value {
  168            lsp::NumberOrString::Number(number) => Self::Number(number),
  169            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  170        }
  171    }
  172
  173    fn to_lsp(&self) -> lsp::NumberOrString {
  174        match self {
  175            Self::Number(number) => lsp::NumberOrString::Number(*number),
  176            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  177        }
  178    }
  179
  180    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  181        Some(match value.value? {
  182            proto::progress_token::Value::Number(number) => Self::Number(number),
  183            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  184        })
  185    }
  186
  187    fn to_proto(&self) -> proto::ProgressToken {
  188        proto::ProgressToken {
  189            value: Some(match self {
  190                Self::Number(number) => proto::progress_token::Value::Number(*number),
  191                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  192            }),
  193        }
  194    }
  195}
  196
  197#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  198pub enum FormatTrigger {
  199    Save,
  200    Manual,
  201}
  202
  203pub enum LspFormatTarget {
  204    Buffers,
  205    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  206}
  207
  208#[derive(Clone, PartialEq, Eq, Hash)]
  209pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  210
  211struct OpenLspBuffer(Entity<Buffer>);
  212
  213impl FormatTrigger {
  214    fn from_proto(value: i32) -> FormatTrigger {
  215        match value {
  216            0 => FormatTrigger::Save,
  217            1 => FormatTrigger::Manual,
  218            _ => FormatTrigger::Save,
  219        }
  220    }
  221}
  222
  223#[derive(Clone)]
  224struct UnifiedLanguageServer {
  225    id: LanguageServerId,
  226    project_roots: HashSet<Arc<RelPath>>,
  227}
  228
  229#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  230struct LanguageServerSeed {
  231    worktree_id: WorktreeId,
  232    name: LanguageServerName,
  233    toolchain: Option<Toolchain>,
  234    settings: Arc<LspSettings>,
  235}
  236
  237#[derive(Debug)]
  238pub struct DocumentDiagnosticsUpdate<'a, D> {
  239    pub diagnostics: D,
  240    pub result_id: Option<SharedString>,
  241    pub registration_id: Option<SharedString>,
  242    pub server_id: LanguageServerId,
  243    pub disk_based_sources: Cow<'a, [String]>,
  244}
  245
  246pub struct DocumentDiagnostics {
  247    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  248    document_abs_path: PathBuf,
  249    version: Option<i32>,
  250}
  251
  252#[derive(Default, Debug)]
  253struct DynamicRegistrations {
  254    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  255    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  256}
  257
  258pub struct LocalLspStore {
  259    weak: WeakEntity<LspStore>,
  260    worktree_store: Entity<WorktreeStore>,
  261    toolchain_store: Entity<LocalToolchainStore>,
  262    http_client: Arc<dyn HttpClient>,
  263    environment: Entity<ProjectEnvironment>,
  264    fs: Arc<dyn Fs>,
  265    languages: Arc<LanguageRegistry>,
  266    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  267    yarn: Entity<YarnPathStore>,
  268    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  269    buffers_being_formatted: HashSet<BufferId>,
  270    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  271    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  272    watched_manifest_filenames: HashSet<ManifestName>,
  273    language_server_paths_watched_for_rename:
  274        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  275    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  276    supplementary_language_servers:
  277        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  278    prettier_store: Entity<PrettierStore>,
  279    next_diagnostic_group_id: usize,
  280    diagnostics: HashMap<
  281        WorktreeId,
  282        HashMap<
  283            Arc<RelPath>,
  284            Vec<(
  285                LanguageServerId,
  286                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  287            )>,
  288        >,
  289    >,
  290    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  291    _subscription: gpui::Subscription,
  292    lsp_tree: LanguageServerTree,
  293    registered_buffers: HashMap<BufferId, usize>,
  294    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  295    buffer_pull_diagnostics_result_ids: HashMap<
  296        LanguageServerId,
  297        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  298    >,
  299    workspace_pull_diagnostics_result_ids: HashMap<
  300        LanguageServerId,
  301        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  302    >,
  303    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, Receiver<()>)>,
  304}
  305
  306impl LocalLspStore {
  307    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  308    pub fn running_language_server_for_id(
  309        &self,
  310        id: LanguageServerId,
  311    ) -> Option<&Arc<LanguageServer>> {
  312        let language_server_state = self.language_servers.get(&id)?;
  313
  314        match language_server_state {
  315            LanguageServerState::Running { server, .. } => Some(server),
  316            LanguageServerState::Starting { .. } => None,
  317        }
  318    }
  319
  320    fn get_or_insert_language_server(
  321        &mut self,
  322        worktree_handle: &Entity<Worktree>,
  323        delegate: Arc<LocalLspAdapterDelegate>,
  324        disposition: &Arc<LaunchDisposition>,
  325        language_name: &LanguageName,
  326        cx: &mut App,
  327    ) -> LanguageServerId {
  328        let key = LanguageServerSeed {
  329            worktree_id: worktree_handle.read(cx).id(),
  330            name: disposition.server_name.clone(),
  331            settings: disposition.settings.clone(),
  332            toolchain: disposition.toolchain.clone(),
  333        };
  334        if let Some(state) = self.language_server_ids.get_mut(&key) {
  335            state.project_roots.insert(disposition.path.path.clone());
  336            state.id
  337        } else {
  338            let adapter = self
  339                .languages
  340                .lsp_adapters(language_name)
  341                .into_iter()
  342                .find(|adapter| adapter.name() == disposition.server_name)
  343                .expect("To find LSP adapter");
  344            let new_language_server_id = self.start_language_server(
  345                worktree_handle,
  346                delegate,
  347                adapter,
  348                disposition.settings.clone(),
  349                key.clone(),
  350                cx,
  351            );
  352            if let Some(state) = self.language_server_ids.get_mut(&key) {
  353                state.project_roots.insert(disposition.path.path.clone());
  354            } else {
  355                debug_assert!(
  356                    false,
  357                    "Expected `start_language_server` to ensure that `key` exists in a map"
  358                );
  359            }
  360            new_language_server_id
  361        }
  362    }
  363
  364    fn start_language_server(
  365        &mut self,
  366        worktree_handle: &Entity<Worktree>,
  367        delegate: Arc<LocalLspAdapterDelegate>,
  368        adapter: Arc<CachedLspAdapter>,
  369        settings: Arc<LspSettings>,
  370        key: LanguageServerSeed,
  371        cx: &mut App,
  372    ) -> LanguageServerId {
  373        let worktree = worktree_handle.read(cx);
  374
  375        let worktree_id = worktree.id();
  376        let worktree_abs_path = worktree.abs_path();
  377        let toolchain = key.toolchain.clone();
  378        let override_options = settings.initialization_options.clone();
  379
  380        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  381
  382        let server_id = self.languages.next_language_server_id();
  383        log::trace!(
  384            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  385            adapter.name.0
  386        );
  387
  388        let untrusted_worktree_task =
  389            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  390                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  391                    trusted_worktrees.can_trust(worktree_id, cx)
  392                });
  393                if can_trust {
  394                    self.restricted_worktrees_tasks.remove(&worktree_id);
  395                    None
  396                } else {
  397                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  398                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  399                        hash_map::Entry::Vacant(v) => {
  400                            let (tx, rx) = smol::channel::bounded::<()>(1);
  401                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, _| {
  402                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  403                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  404                                        tx.send_blocking(()).ok();
  405                                    }
  406                                }
  407                            });
  408                            v.insert((subscription, rx.clone()));
  409                            Some(rx)
  410                        }
  411                    }
  412                }
  413            });
  414        let update_binary_status = untrusted_worktree_task.is_none();
  415
  416        let binary = self.get_language_server_binary(
  417            worktree_abs_path.clone(),
  418            adapter.clone(),
  419            settings,
  420            toolchain.clone(),
  421            delegate.clone(),
  422            true,
  423            untrusted_worktree_task,
  424            cx,
  425        );
  426        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  427
  428        let pending_server = cx.spawn({
  429            let adapter = adapter.clone();
  430            let server_name = adapter.name.clone();
  431            let stderr_capture = stderr_capture.clone();
  432            #[cfg(any(test, feature = "test-support"))]
  433            let lsp_store = self.weak.clone();
  434            let pending_workspace_folders = pending_workspace_folders.clone();
  435            async move |cx| {
  436                let binary = binary.await?;
  437                #[cfg(any(test, feature = "test-support"))]
  438                if let Some(server) = lsp_store
  439                    .update(&mut cx.clone(), |this, cx| {
  440                        this.languages.create_fake_language_server(
  441                            server_id,
  442                            &server_name,
  443                            binary.clone(),
  444                            &mut cx.to_async(),
  445                        )
  446                    })
  447                    .ok()
  448                    .flatten()
  449                {
  450                    return Ok(server);
  451                }
  452
  453                let code_action_kinds = adapter.code_action_kinds();
  454                lsp::LanguageServer::new(
  455                    stderr_capture,
  456                    server_id,
  457                    server_name,
  458                    binary,
  459                    &worktree_abs_path,
  460                    code_action_kinds,
  461                    Some(pending_workspace_folders),
  462                    cx,
  463                )
  464            }
  465        });
  466
  467        let startup = {
  468            let server_name = adapter.name.0.clone();
  469            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  470            let key = key.clone();
  471            let adapter = adapter.clone();
  472            let lsp_store = self.weak.clone();
  473            let pending_workspace_folders = pending_workspace_folders.clone();
  474
  475            let pull_diagnostics = ProjectSettings::get_global(cx)
  476                .diagnostics
  477                .lsp_pull_diagnostics
  478                .enabled;
  479            cx.spawn(async move |cx| {
  480                let result = async {
  481                    let language_server = pending_server.await?;
  482
  483                    let workspace_config = Self::workspace_configuration_for_adapter(
  484                        adapter.adapter.clone(),
  485                        &delegate,
  486                        toolchain,
  487                        None,
  488                        cx,
  489                    )
  490                    .await?;
  491
  492                    let mut initialization_options = Self::initialization_options_for_adapter(
  493                        adapter.adapter.clone(),
  494                        &delegate,
  495                    )
  496                    .await?;
  497
  498                    match (&mut initialization_options, override_options) {
  499                        (Some(initialization_options), Some(override_options)) => {
  500                            merge_json_value_into(override_options, initialization_options);
  501                        }
  502                        (None, override_options) => initialization_options = override_options,
  503                        _ => {}
  504                    }
  505
  506                    let initialization_params = cx.update(|cx| {
  507                        let mut params =
  508                            language_server.default_initialize_params(pull_diagnostics, cx);
  509                        params.initialization_options = initialization_options;
  510                        adapter.adapter.prepare_initialize_params(params, cx)
  511                    })??;
  512
  513                    Self::setup_lsp_messages(
  514                        lsp_store.clone(),
  515                        &language_server,
  516                        delegate.clone(),
  517                        adapter.clone(),
  518                    );
  519
  520                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  521                        settings: workspace_config,
  522                    };
  523                    let language_server = cx
  524                        .update(|cx| {
  525                            language_server.initialize(
  526                                initialization_params,
  527                                Arc::new(did_change_configuration_params.clone()),
  528                                cx,
  529                            )
  530                        })?
  531                        .await
  532                        .inspect_err(|_| {
  533                            if let Some(lsp_store) = lsp_store.upgrade() {
  534                                lsp_store
  535                                    .update(cx, |lsp_store, cx| {
  536                                        lsp_store.cleanup_lsp_data(server_id);
  537                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  538                                    })
  539                                    .ok();
  540                            }
  541                        })?;
  542
  543                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  544                        did_change_configuration_params,
  545                    )?;
  546
  547                    anyhow::Ok(language_server)
  548                }
  549                .await;
  550
  551                match result {
  552                    Ok(server) => {
  553                        lsp_store
  554                            .update(cx, |lsp_store, cx| {
  555                                lsp_store.insert_newly_running_language_server(
  556                                    adapter,
  557                                    server.clone(),
  558                                    server_id,
  559                                    key,
  560                                    pending_workspace_folders,
  561                                    cx,
  562                                );
  563                            })
  564                            .ok();
  565                        stderr_capture.lock().take();
  566                        Some(server)
  567                    }
  568
  569                    Err(err) => {
  570                        let log = stderr_capture.lock().take().unwrap_or_default();
  571                        delegate.update_status(
  572                            adapter.name(),
  573                            BinaryStatus::Failed {
  574                                error: if log.is_empty() {
  575                                    format!("{err:#}")
  576                                } else {
  577                                    format!("{err:#}\n-- stderr --\n{log}")
  578                                },
  579                            },
  580                        );
  581                        log::error!(
  582                            "Failed to start language server {server_name:?}: {}",
  583                            redact_command(&format!("{err:?}"))
  584                        );
  585                        if !log.is_empty() {
  586                            log::error!("server stderr: {}", redact_command(&log));
  587                        }
  588                        None
  589                    }
  590                }
  591            })
  592        };
  593        let state = LanguageServerState::Starting {
  594            startup,
  595            pending_workspace_folders,
  596        };
  597
  598        if update_binary_status {
  599            self.languages
  600                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  601        }
  602
  603        self.language_servers.insert(server_id, state);
  604        self.language_server_ids
  605            .entry(key)
  606            .or_insert(UnifiedLanguageServer {
  607                id: server_id,
  608                project_roots: Default::default(),
  609            });
  610        server_id
  611    }
  612
  613    fn get_language_server_binary(
  614        &self,
  615        worktree_abs_path: Arc<Path>,
  616        adapter: Arc<CachedLspAdapter>,
  617        settings: Arc<LspSettings>,
  618        toolchain: Option<Toolchain>,
  619        delegate: Arc<dyn LspAdapterDelegate>,
  620        allow_binary_download: bool,
  621        untrusted_worktree_task: Option<Receiver<()>>,
  622        cx: &mut App,
  623    ) -> Task<Result<LanguageServerBinary>> {
  624        if let Some(settings) = &settings.binary
  625            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  626        {
  627            let settings = settings.clone();
  628            let languages = self.languages.clone();
  629            return cx.background_spawn(async move {
  630                if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  631                    log::info!(
  632                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  633                        adapter.name(),
  634                    );
  635                    untrusted_worktree_task.recv().await.ok();
  636                    log::info!(
  637                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  638                        adapter.name(),
  639                    );
  640                    languages
  641                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  642                }
  643                let mut env = delegate.shell_env().await;
  644                env.extend(settings.env.unwrap_or_default());
  645
  646                Ok(LanguageServerBinary {
  647                    path: delegate.resolve_executable_path(path),
  648                    env: Some(env),
  649                    arguments: settings
  650                        .arguments
  651                        .unwrap_or_default()
  652                        .iter()
  653                        .map(Into::into)
  654                        .collect(),
  655                })
  656            });
  657        }
  658        let lsp_binary_options = LanguageServerBinaryOptions {
  659            allow_path_lookup: !settings
  660                .binary
  661                .as_ref()
  662                .and_then(|b| b.ignore_system_version)
  663                .unwrap_or_default(),
  664            allow_binary_download,
  665            pre_release: settings
  666                .fetch
  667                .as_ref()
  668                .and_then(|f| f.pre_release)
  669                .unwrap_or(false),
  670        };
  671
  672        cx.spawn(async move |cx| {
  673            if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  674                log::info!(
  675                    "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  676                    adapter.name(),
  677                );
  678                untrusted_worktree_task.recv().await.ok();
  679                log::info!(
  680                    "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  681                    adapter.name(),
  682                );
  683            }
  684
  685            let (existing_binary, maybe_download_binary) = adapter
  686                .clone()
  687                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  688                .await
  689                .await;
  690
  691            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  692
  693            let mut binary = match (existing_binary, maybe_download_binary) {
  694                (binary, None) => binary?,
  695                (Err(_), Some(downloader)) => downloader.await?,
  696                (Ok(existing_binary), Some(downloader)) => {
  697                    let mut download_timeout = cx
  698                        .background_executor()
  699                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  700                        .fuse();
  701                    let mut downloader = downloader.fuse();
  702                    futures::select! {
  703                        _ = download_timeout => {
  704                            // Return existing binary and kick the existing work to the background.
  705                            cx.spawn(async move |_| downloader.await).detach();
  706                            Ok(existing_binary)
  707                        },
  708                        downloaded_or_existing_binary = downloader => {
  709                            // If download fails, this results in the existing binary.
  710                            downloaded_or_existing_binary
  711                        }
  712                    }?
  713                }
  714            };
  715            let mut shell_env = delegate.shell_env().await;
  716
  717            shell_env.extend(binary.env.unwrap_or_default());
  718
  719            if let Some(settings) = settings.binary.as_ref() {
  720                if let Some(arguments) = &settings.arguments {
  721                    binary.arguments = arguments.iter().map(Into::into).collect();
  722                }
  723                if let Some(env) = &settings.env {
  724                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  725                }
  726            }
  727
  728            binary.env = Some(shell_env);
  729            Ok(binary)
  730        })
  731    }
  732
  733    fn setup_lsp_messages(
  734        lsp_store: WeakEntity<LspStore>,
  735        language_server: &LanguageServer,
  736        delegate: Arc<dyn LspAdapterDelegate>,
  737        adapter: Arc<CachedLspAdapter>,
  738    ) {
  739        let name = language_server.name();
  740        let server_id = language_server.server_id();
  741        language_server
  742            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  743                let adapter = adapter.clone();
  744                let this = lsp_store.clone();
  745                move |mut params, cx| {
  746                    let adapter = adapter.clone();
  747                    if let Some(this) = this.upgrade() {
  748                        this.update(cx, |this, cx| {
  749                            {
  750                                let buffer = params
  751                                    .uri
  752                                    .to_file_path()
  753                                    .map(|file_path| this.get_buffer(&file_path, cx))
  754                                    .ok()
  755                                    .flatten();
  756                                adapter.process_diagnostics(&mut params, server_id, buffer);
  757                            }
  758
  759                            this.merge_lsp_diagnostics(
  760                                DiagnosticSourceKind::Pushed,
  761                                vec![DocumentDiagnosticsUpdate {
  762                                    server_id,
  763                                    diagnostics: params,
  764                                    result_id: None,
  765                                    disk_based_sources: Cow::Borrowed(
  766                                        &adapter.disk_based_diagnostic_sources,
  767                                    ),
  768                                    registration_id: None,
  769                                }],
  770                                |_, diagnostic, cx| match diagnostic.source_kind {
  771                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  772                                        adapter.retain_old_diagnostic(diagnostic, cx)
  773                                    }
  774                                    DiagnosticSourceKind::Pulled => true,
  775                                },
  776                                cx,
  777                            )
  778                            .log_err();
  779                        })
  780                        .ok();
  781                    }
  782                }
  783            })
  784            .detach();
  785        language_server
  786            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  787                let adapter = adapter.adapter.clone();
  788                let delegate = delegate.clone();
  789                let this = lsp_store.clone();
  790                move |params, cx| {
  791                    let adapter = adapter.clone();
  792                    let delegate = delegate.clone();
  793                    let this = this.clone();
  794                    let mut cx = cx.clone();
  795                    async move {
  796                        let toolchain_for_id = this
  797                            .update(&mut cx, |this, _| {
  798                                this.as_local()?.language_server_ids.iter().find_map(
  799                                    |(seed, value)| {
  800                                        (value.id == server_id).then(|| seed.toolchain.clone())
  801                                    },
  802                                )
  803                            })?
  804                            .context("Expected the LSP store to be in a local mode")?;
  805
  806                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  807                        for item in &params.items {
  808                            let scope_uri = item.scope_uri.clone();
  809                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  810                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  811                            else {
  812                                // We've already queried workspace configuration of this URI.
  813                                continue;
  814                            };
  815                            let workspace_config = Self::workspace_configuration_for_adapter(
  816                                adapter.clone(),
  817                                &delegate,
  818                                toolchain_for_id.clone(),
  819                                scope_uri,
  820                                &mut cx,
  821                            )
  822                            .await?;
  823                            new_scope_uri.insert(workspace_config);
  824                        }
  825
  826                        Ok(params
  827                            .items
  828                            .into_iter()
  829                            .filter_map(|item| {
  830                                let workspace_config =
  831                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  832                                if let Some(section) = &item.section {
  833                                    Some(
  834                                        workspace_config
  835                                            .get(section)
  836                                            .cloned()
  837                                            .unwrap_or(serde_json::Value::Null),
  838                                    )
  839                                } else {
  840                                    Some(workspace_config.clone())
  841                                }
  842                            })
  843                            .collect())
  844                    }
  845                }
  846            })
  847            .detach();
  848
  849        language_server
  850            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  851                let this = lsp_store.clone();
  852                move |_, cx| {
  853                    let this = this.clone();
  854                    let cx = cx.clone();
  855                    async move {
  856                        let Some(server) =
  857                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  858                        else {
  859                            return Ok(None);
  860                        };
  861                        let root = server.workspace_folders();
  862                        Ok(Some(
  863                            root.into_iter()
  864                                .map(|uri| WorkspaceFolder {
  865                                    uri,
  866                                    name: Default::default(),
  867                                })
  868                                .collect(),
  869                        ))
  870                    }
  871                }
  872            })
  873            .detach();
  874        // Even though we don't have handling for these requests, respond to them to
  875        // avoid stalling any language server like `gopls` which waits for a response
  876        // to these requests when initializing.
  877        language_server
  878            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  879                let this = lsp_store.clone();
  880                move |params, cx| {
  881                    let this = this.clone();
  882                    let mut cx = cx.clone();
  883                    async move {
  884                        this.update(&mut cx, |this, _| {
  885                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  886                            {
  887                                status
  888                                    .progress_tokens
  889                                    .insert(ProgressToken::from_lsp(params.token));
  890                            }
  891                        })?;
  892
  893                        Ok(())
  894                    }
  895                }
  896            })
  897            .detach();
  898
  899        language_server
  900            .on_request::<lsp::request::RegisterCapability, _, _>({
  901                let lsp_store = lsp_store.clone();
  902                move |params, cx| {
  903                    let lsp_store = lsp_store.clone();
  904                    let mut cx = cx.clone();
  905                    async move {
  906                        lsp_store
  907                            .update(&mut cx, |lsp_store, cx| {
  908                                if lsp_store.as_local().is_some() {
  909                                    match lsp_store
  910                                        .register_server_capabilities(server_id, params, cx)
  911                                    {
  912                                        Ok(()) => {}
  913                                        Err(e) => {
  914                                            log::error!(
  915                                                "Failed to register server capabilities: {e:#}"
  916                                            );
  917                                        }
  918                                    };
  919                                }
  920                            })
  921                            .ok();
  922                        Ok(())
  923                    }
  924                }
  925            })
  926            .detach();
  927
  928        language_server
  929            .on_request::<lsp::request::UnregisterCapability, _, _>({
  930                let lsp_store = lsp_store.clone();
  931                move |params, cx| {
  932                    let lsp_store = lsp_store.clone();
  933                    let mut cx = cx.clone();
  934                    async move {
  935                        lsp_store
  936                            .update(&mut cx, |lsp_store, cx| {
  937                                if lsp_store.as_local().is_some() {
  938                                    match lsp_store
  939                                        .unregister_server_capabilities(server_id, params, cx)
  940                                    {
  941                                        Ok(()) => {}
  942                                        Err(e) => {
  943                                            log::error!(
  944                                                "Failed to unregister server capabilities: {e:#}"
  945                                            );
  946                                        }
  947                                    }
  948                                }
  949                            })
  950                            .ok();
  951                        Ok(())
  952                    }
  953                }
  954            })
  955            .detach();
  956
  957        language_server
  958            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  959                let this = lsp_store.clone();
  960                move |params, cx| {
  961                    let mut cx = cx.clone();
  962                    let this = this.clone();
  963                    async move {
  964                        LocalLspStore::on_lsp_workspace_edit(
  965                            this.clone(),
  966                            params,
  967                            server_id,
  968                            &mut cx,
  969                        )
  970                        .await
  971                    }
  972                }
  973            })
  974            .detach();
  975
  976        language_server
  977            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  978                let lsp_store = lsp_store.clone();
  979                let request_id = Arc::new(AtomicUsize::new(0));
  980                move |(), cx| {
  981                    let lsp_store = lsp_store.clone();
  982                    let request_id = request_id.clone();
  983                    let mut cx = cx.clone();
  984                    async move {
  985                        lsp_store
  986                            .update(&mut cx, |lsp_store, cx| {
  987                                let request_id =
  988                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  989                                cx.emit(LspStoreEvent::RefreshInlayHints {
  990                                    server_id,
  991                                    request_id,
  992                                });
  993                                lsp_store
  994                                    .downstream_client
  995                                    .as_ref()
  996                                    .map(|(client, project_id)| {
  997                                        client.send(proto::RefreshInlayHints {
  998                                            project_id: *project_id,
  999                                            server_id: server_id.to_proto(),
 1000                                            request_id: request_id.map(|id| id as u64),
 1001                                        })
 1002                                    })
 1003                            })?
 1004                            .transpose()?;
 1005                        Ok(())
 1006                    }
 1007                }
 1008            })
 1009            .detach();
 1010
 1011        language_server
 1012            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1013                let this = lsp_store.clone();
 1014                move |(), cx| {
 1015                    let this = this.clone();
 1016                    let mut cx = cx.clone();
 1017                    async move {
 1018                        this.update(&mut cx, |this, cx| {
 1019                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1020                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1021                                client.send(proto::RefreshCodeLens {
 1022                                    project_id: *project_id,
 1023                                })
 1024                            })
 1025                        })?
 1026                        .transpose()?;
 1027                        Ok(())
 1028                    }
 1029                }
 1030            })
 1031            .detach();
 1032
 1033        language_server
 1034            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1035                let this = lsp_store.clone();
 1036                move |(), cx| {
 1037                    let this = this.clone();
 1038                    let mut cx = cx.clone();
 1039                    async move {
 1040                        this.update(&mut cx, |lsp_store, _| {
 1041                            lsp_store.pull_workspace_diagnostics(server_id);
 1042                            lsp_store
 1043                                .downstream_client
 1044                                .as_ref()
 1045                                .map(|(client, project_id)| {
 1046                                    client.send(proto::PullWorkspaceDiagnostics {
 1047                                        project_id: *project_id,
 1048                                        server_id: server_id.to_proto(),
 1049                                    })
 1050                                })
 1051                        })?
 1052                        .transpose()?;
 1053                        Ok(())
 1054                    }
 1055                }
 1056            })
 1057            .detach();
 1058
 1059        language_server
 1060            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1061                let this = lsp_store.clone();
 1062                let name = name.to_string();
 1063                let adapter = adapter.clone();
 1064                move |params, cx| {
 1065                    let this = this.clone();
 1066                    let name = name.to_string();
 1067                    let adapter = adapter.clone();
 1068                    let mut cx = cx.clone();
 1069                    async move {
 1070                        let actions = params.actions.unwrap_or_default();
 1071                        let message = params.message.clone();
 1072                        let (tx, rx) = smol::channel::bounded(1);
 1073                        let request = LanguageServerPromptRequest {
 1074                            level: match params.typ {
 1075                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1076                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1077                                _ => PromptLevel::Info,
 1078                            },
 1079                            message: params.message,
 1080                            actions,
 1081                            response_channel: tx,
 1082                            lsp_name: name.clone(),
 1083                        };
 1084
 1085                        let did_update = this
 1086                            .update(&mut cx, |_, cx| {
 1087                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1088                            })
 1089                            .is_ok();
 1090                        if did_update {
 1091                            let response = rx.recv().await.ok();
 1092                            if let Some(ref selected_action) = response {
 1093                                let context = language::PromptResponseContext {
 1094                                    message,
 1095                                    selected_action: selected_action.clone(),
 1096                                };
 1097                                adapter.process_prompt_response(&context, &mut cx)
 1098                            }
 1099
 1100                            Ok(response)
 1101                        } else {
 1102                            Ok(None)
 1103                        }
 1104                    }
 1105                }
 1106            })
 1107            .detach();
 1108        language_server
 1109            .on_notification::<lsp::notification::ShowMessage, _>({
 1110                let this = lsp_store.clone();
 1111                let name = name.to_string();
 1112                move |params, cx| {
 1113                    let this = this.clone();
 1114                    let name = name.to_string();
 1115                    let mut cx = cx.clone();
 1116
 1117                    let (tx, _) = smol::channel::bounded(1);
 1118                    let request = LanguageServerPromptRequest {
 1119                        level: match params.typ {
 1120                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1121                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1122                            _ => PromptLevel::Info,
 1123                        },
 1124                        message: params.message,
 1125                        actions: vec![],
 1126                        response_channel: tx,
 1127                        lsp_name: name,
 1128                    };
 1129
 1130                    let _ = this.update(&mut cx, |_, cx| {
 1131                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1132                    });
 1133                }
 1134            })
 1135            .detach();
 1136
 1137        let disk_based_diagnostics_progress_token =
 1138            adapter.disk_based_diagnostics_progress_token.clone();
 1139
 1140        language_server
 1141            .on_notification::<lsp::notification::Progress, _>({
 1142                let this = lsp_store.clone();
 1143                move |params, cx| {
 1144                    if let Some(this) = this.upgrade() {
 1145                        this.update(cx, |this, cx| {
 1146                            this.on_lsp_progress(
 1147                                params,
 1148                                server_id,
 1149                                disk_based_diagnostics_progress_token.clone(),
 1150                                cx,
 1151                            );
 1152                        })
 1153                        .ok();
 1154                    }
 1155                }
 1156            })
 1157            .detach();
 1158
 1159        language_server
 1160            .on_notification::<lsp::notification::LogMessage, _>({
 1161                let this = lsp_store.clone();
 1162                move |params, cx| {
 1163                    if let Some(this) = this.upgrade() {
 1164                        this.update(cx, |_, cx| {
 1165                            cx.emit(LspStoreEvent::LanguageServerLog(
 1166                                server_id,
 1167                                LanguageServerLogType::Log(params.typ),
 1168                                params.message,
 1169                            ));
 1170                        })
 1171                        .ok();
 1172                    }
 1173                }
 1174            })
 1175            .detach();
 1176
 1177        language_server
 1178            .on_notification::<lsp::notification::LogTrace, _>({
 1179                let this = lsp_store.clone();
 1180                move |params, cx| {
 1181                    let mut cx = cx.clone();
 1182                    if let Some(this) = this.upgrade() {
 1183                        this.update(&mut cx, |_, cx| {
 1184                            cx.emit(LspStoreEvent::LanguageServerLog(
 1185                                server_id,
 1186                                LanguageServerLogType::Trace {
 1187                                    verbose_info: params.verbose,
 1188                                },
 1189                                params.message,
 1190                            ));
 1191                        })
 1192                        .ok();
 1193                    }
 1194                }
 1195            })
 1196            .detach();
 1197
 1198        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1199        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1200        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1201        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1202    }
 1203
 1204    fn shutdown_language_servers_on_quit(
 1205        &mut self,
 1206        _: &mut Context<LspStore>,
 1207    ) -> impl Future<Output = ()> + use<> {
 1208        let shutdown_futures = self
 1209            .language_servers
 1210            .drain()
 1211            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1212            .collect::<Vec<_>>();
 1213
 1214        async move {
 1215            join_all(shutdown_futures).await;
 1216        }
 1217    }
 1218
 1219    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1220        match server_state {
 1221            LanguageServerState::Running { server, .. } => {
 1222                if let Some(shutdown) = server.shutdown() {
 1223                    shutdown.await;
 1224                }
 1225            }
 1226            LanguageServerState::Starting { startup, .. } => {
 1227                if let Some(server) = startup.await
 1228                    && let Some(shutdown) = server.shutdown()
 1229                {
 1230                    shutdown.await;
 1231                }
 1232            }
 1233        }
 1234        Ok(())
 1235    }
 1236
 1237    fn language_servers_for_worktree(
 1238        &self,
 1239        worktree_id: WorktreeId,
 1240    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1241        self.language_server_ids
 1242            .iter()
 1243            .filter_map(move |(seed, state)| {
 1244                if seed.worktree_id != worktree_id {
 1245                    return None;
 1246                }
 1247
 1248                if let Some(LanguageServerState::Running { server, .. }) =
 1249                    self.language_servers.get(&state.id)
 1250                {
 1251                    Some(server)
 1252                } else {
 1253                    None
 1254                }
 1255            })
 1256    }
 1257
 1258    fn language_server_ids_for_project_path(
 1259        &self,
 1260        project_path: ProjectPath,
 1261        language: &Language,
 1262        cx: &mut App,
 1263    ) -> Vec<LanguageServerId> {
 1264        let Some(worktree) = self
 1265            .worktree_store
 1266            .read(cx)
 1267            .worktree_for_id(project_path.worktree_id, cx)
 1268        else {
 1269            return Vec::new();
 1270        };
 1271        let delegate: Arc<dyn ManifestDelegate> =
 1272            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1273
 1274        self.lsp_tree
 1275            .get(
 1276                project_path,
 1277                language.name(),
 1278                language.manifest(),
 1279                &delegate,
 1280                cx,
 1281            )
 1282            .collect::<Vec<_>>()
 1283    }
 1284
 1285    fn language_server_ids_for_buffer(
 1286        &self,
 1287        buffer: &Buffer,
 1288        cx: &mut App,
 1289    ) -> Vec<LanguageServerId> {
 1290        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1291            let worktree_id = file.worktree_id(cx);
 1292
 1293            let path: Arc<RelPath> = file
 1294                .path()
 1295                .parent()
 1296                .map(Arc::from)
 1297                .unwrap_or_else(|| file.path().clone());
 1298            let worktree_path = ProjectPath { worktree_id, path };
 1299            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1300        } else {
 1301            Vec::new()
 1302        }
 1303    }
 1304
 1305    fn language_servers_for_buffer<'a>(
 1306        &'a self,
 1307        buffer: &'a Buffer,
 1308        cx: &'a mut App,
 1309    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1310        self.language_server_ids_for_buffer(buffer, cx)
 1311            .into_iter()
 1312            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1313                LanguageServerState::Running {
 1314                    adapter, server, ..
 1315                } => Some((adapter, server)),
 1316                _ => None,
 1317            })
 1318    }
 1319
 1320    async fn execute_code_action_kind_locally(
 1321        lsp_store: WeakEntity<LspStore>,
 1322        mut buffers: Vec<Entity<Buffer>>,
 1323        kind: CodeActionKind,
 1324        push_to_history: bool,
 1325        cx: &mut AsyncApp,
 1326    ) -> anyhow::Result<ProjectTransaction> {
 1327        // Do not allow multiple concurrent code actions requests for the
 1328        // same buffer.
 1329        lsp_store.update(cx, |this, cx| {
 1330            let this = this.as_local_mut().unwrap();
 1331            buffers.retain(|buffer| {
 1332                this.buffers_being_formatted
 1333                    .insert(buffer.read(cx).remote_id())
 1334            });
 1335        })?;
 1336        let _cleanup = defer({
 1337            let this = lsp_store.clone();
 1338            let mut cx = cx.clone();
 1339            let buffers = &buffers;
 1340            move || {
 1341                this.update(&mut cx, |this, cx| {
 1342                    let this = this.as_local_mut().unwrap();
 1343                    for buffer in buffers {
 1344                        this.buffers_being_formatted
 1345                            .remove(&buffer.read(cx).remote_id());
 1346                    }
 1347                })
 1348                .ok();
 1349            }
 1350        });
 1351        let mut project_transaction = ProjectTransaction::default();
 1352
 1353        for buffer in &buffers {
 1354            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1355                buffer.update(cx, |buffer, cx| {
 1356                    lsp_store
 1357                        .as_local()
 1358                        .unwrap()
 1359                        .language_servers_for_buffer(buffer, cx)
 1360                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1361                        .collect::<Vec<_>>()
 1362                })
 1363            })?;
 1364            for (_, language_server) in adapters_and_servers.iter() {
 1365                let actions = Self::get_server_code_actions_from_action_kinds(
 1366                    &lsp_store,
 1367                    language_server.server_id(),
 1368                    vec![kind.clone()],
 1369                    buffer,
 1370                    cx,
 1371                )
 1372                .await?;
 1373                Self::execute_code_actions_on_server(
 1374                    &lsp_store,
 1375                    language_server,
 1376                    actions,
 1377                    push_to_history,
 1378                    &mut project_transaction,
 1379                    cx,
 1380                )
 1381                .await?;
 1382            }
 1383        }
 1384        Ok(project_transaction)
 1385    }
 1386
 1387    async fn format_locally(
 1388        lsp_store: WeakEntity<LspStore>,
 1389        mut buffers: Vec<FormattableBuffer>,
 1390        push_to_history: bool,
 1391        trigger: FormatTrigger,
 1392        logger: zlog::Logger,
 1393        cx: &mut AsyncApp,
 1394    ) -> anyhow::Result<ProjectTransaction> {
 1395        // Do not allow multiple concurrent formatting requests for the
 1396        // same buffer.
 1397        lsp_store.update(cx, |this, cx| {
 1398            let this = this.as_local_mut().unwrap();
 1399            buffers.retain(|buffer| {
 1400                this.buffers_being_formatted
 1401                    .insert(buffer.handle.read(cx).remote_id())
 1402            });
 1403        })?;
 1404
 1405        let _cleanup = defer({
 1406            let this = lsp_store.clone();
 1407            let mut cx = cx.clone();
 1408            let buffers = &buffers;
 1409            move || {
 1410                this.update(&mut cx, |this, cx| {
 1411                    let this = this.as_local_mut().unwrap();
 1412                    for buffer in buffers {
 1413                        this.buffers_being_formatted
 1414                            .remove(&buffer.handle.read(cx).remote_id());
 1415                    }
 1416                })
 1417                .ok();
 1418            }
 1419        });
 1420
 1421        let mut project_transaction = ProjectTransaction::default();
 1422
 1423        for buffer in &buffers {
 1424            zlog::debug!(
 1425                logger =>
 1426                "formatting buffer '{:?}'",
 1427                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1428            );
 1429            // Create an empty transaction to hold all of the formatting edits.
 1430            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1431                // ensure no transactions created while formatting are
 1432                // grouped with the previous transaction in the history
 1433                // based on the transaction group interval
 1434                buffer.finalize_last_transaction();
 1435                buffer
 1436                    .start_transaction()
 1437                    .context("transaction already open")?;
 1438                buffer.end_transaction(cx);
 1439                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1440                buffer.finalize_last_transaction();
 1441                anyhow::Ok(transaction_id)
 1442            })??;
 1443
 1444            let result = Self::format_buffer_locally(
 1445                lsp_store.clone(),
 1446                buffer,
 1447                formatting_transaction_id,
 1448                trigger,
 1449                logger,
 1450                cx,
 1451            )
 1452            .await;
 1453
 1454            buffer.handle.update(cx, |buffer, cx| {
 1455                let Some(formatting_transaction) =
 1456                    buffer.get_transaction(formatting_transaction_id).cloned()
 1457                else {
 1458                    zlog::warn!(logger => "no formatting transaction");
 1459                    return;
 1460                };
 1461                if formatting_transaction.edit_ids.is_empty() {
 1462                    zlog::debug!(logger => "no changes made while formatting");
 1463                    buffer.forget_transaction(formatting_transaction_id);
 1464                    return;
 1465                }
 1466                if !push_to_history {
 1467                    zlog::trace!(logger => "forgetting format transaction");
 1468                    buffer.forget_transaction(formatting_transaction.id);
 1469                }
 1470                project_transaction
 1471                    .0
 1472                    .insert(cx.entity(), formatting_transaction);
 1473            })?;
 1474
 1475            result?;
 1476        }
 1477
 1478        Ok(project_transaction)
 1479    }
 1480
 1481    async fn format_buffer_locally(
 1482        lsp_store: WeakEntity<LspStore>,
 1483        buffer: &FormattableBuffer,
 1484        formatting_transaction_id: clock::Lamport,
 1485        trigger: FormatTrigger,
 1486        logger: zlog::Logger,
 1487        cx: &mut AsyncApp,
 1488    ) -> Result<()> {
 1489        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1490            buffer.handle.update(cx, |buffer, cx| {
 1491                let adapters_and_servers = lsp_store
 1492                    .as_local()
 1493                    .unwrap()
 1494                    .language_servers_for_buffer(buffer, cx)
 1495                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1496                    .collect::<Vec<_>>();
 1497                let settings =
 1498                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1499                        .into_owned();
 1500                (adapters_and_servers, settings)
 1501            })
 1502        })?;
 1503
 1504        /// Apply edits to the buffer that will become part of the formatting transaction.
 1505        /// Fails if the buffer has been edited since the start of that transaction.
 1506        fn extend_formatting_transaction(
 1507            buffer: &FormattableBuffer,
 1508            formatting_transaction_id: text::TransactionId,
 1509            cx: &mut AsyncApp,
 1510            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1511        ) -> anyhow::Result<()> {
 1512            buffer.handle.update(cx, |buffer, cx| {
 1513                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1514                if last_transaction_id != Some(formatting_transaction_id) {
 1515                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1516                }
 1517                buffer.start_transaction();
 1518                operation(buffer, cx);
 1519                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1520                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1521                }
 1522                Ok(())
 1523            })?
 1524        }
 1525
 1526        // handle whitespace formatting
 1527        if settings.remove_trailing_whitespace_on_save {
 1528            zlog::trace!(logger => "removing trailing whitespace");
 1529            let diff = buffer
 1530                .handle
 1531                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1532                .await;
 1533            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1534                buffer.apply_diff(diff, cx);
 1535            })?;
 1536        }
 1537
 1538        if settings.ensure_final_newline_on_save {
 1539            zlog::trace!(logger => "ensuring final newline");
 1540            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1541                buffer.ensure_final_newline(cx);
 1542            })?;
 1543        }
 1544
 1545        // Formatter for `code_actions_on_format` that runs before
 1546        // the rest of the formatters
 1547        let mut code_actions_on_format_formatters = None;
 1548        let should_run_code_actions_on_format = !matches!(
 1549            (trigger, &settings.format_on_save),
 1550            (FormatTrigger::Save, &FormatOnSave::Off)
 1551        );
 1552        if should_run_code_actions_on_format {
 1553            let have_code_actions_to_run_on_format = settings
 1554                .code_actions_on_format
 1555                .values()
 1556                .any(|enabled| *enabled);
 1557            if have_code_actions_to_run_on_format {
 1558                zlog::trace!(logger => "going to run code actions on format");
 1559                code_actions_on_format_formatters = Some(
 1560                    settings
 1561                        .code_actions_on_format
 1562                        .iter()
 1563                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1564                        .cloned()
 1565                        .map(Formatter::CodeAction)
 1566                        .collect::<Vec<_>>(),
 1567                );
 1568            }
 1569        }
 1570
 1571        let formatters = match (trigger, &settings.format_on_save) {
 1572            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1573            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1574                settings.formatter.as_ref()
 1575            }
 1576        };
 1577
 1578        let formatters = code_actions_on_format_formatters
 1579            .iter()
 1580            .flatten()
 1581            .chain(formatters);
 1582
 1583        for formatter in formatters {
 1584            let formatter = if formatter == &Formatter::Auto {
 1585                if settings.prettier.allowed {
 1586                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1587                    &Formatter::Prettier
 1588                } else {
 1589                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1590                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1591                }
 1592            } else {
 1593                formatter
 1594            };
 1595            match formatter {
 1596                Formatter::Auto => unreachable!("Auto resolved above"),
 1597                Formatter::Prettier => {
 1598                    let logger = zlog::scoped!(logger => "prettier");
 1599                    zlog::trace!(logger => "formatting");
 1600                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1601
 1602                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1603                        lsp_store.prettier_store().unwrap().downgrade()
 1604                    })?;
 1605                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1606                        .await
 1607                        .transpose()?;
 1608                    let Some(diff) = diff else {
 1609                        zlog::trace!(logger => "No changes");
 1610                        continue;
 1611                    };
 1612
 1613                    extend_formatting_transaction(
 1614                        buffer,
 1615                        formatting_transaction_id,
 1616                        cx,
 1617                        |buffer, cx| {
 1618                            buffer.apply_diff(diff, cx);
 1619                        },
 1620                    )?;
 1621                }
 1622                Formatter::External { command, arguments } => {
 1623                    let logger = zlog::scoped!(logger => "command");
 1624                    zlog::trace!(logger => "formatting");
 1625                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1626
 1627                    let diff = Self::format_via_external_command(
 1628                        buffer,
 1629                        command.as_ref(),
 1630                        arguments.as_deref(),
 1631                        cx,
 1632                    )
 1633                    .await
 1634                    .with_context(|| {
 1635                        format!("Failed to format buffer via external command: {}", command)
 1636                    })?;
 1637                    let Some(diff) = diff else {
 1638                        zlog::trace!(logger => "No changes");
 1639                        continue;
 1640                    };
 1641
 1642                    extend_formatting_transaction(
 1643                        buffer,
 1644                        formatting_transaction_id,
 1645                        cx,
 1646                        |buffer, cx| {
 1647                            buffer.apply_diff(diff, cx);
 1648                        },
 1649                    )?;
 1650                }
 1651                Formatter::LanguageServer(specifier) => {
 1652                    let logger = zlog::scoped!(logger => "language-server");
 1653                    zlog::trace!(logger => "formatting");
 1654                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1655
 1656                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1657                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1658                        continue;
 1659                    };
 1660
 1661                    let language_server = match specifier {
 1662                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1663                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1664                                if adapter.name.0.as_ref() == name {
 1665                                    Some(server.clone())
 1666                                } else {
 1667                                    None
 1668                                }
 1669                            })
 1670                        }
 1671                        settings::LanguageServerFormatterSpecifier::Current => {
 1672                            adapters_and_servers.first().map(|e| e.1.clone())
 1673                        }
 1674                    };
 1675
 1676                    let Some(language_server) = language_server else {
 1677                        log::debug!(
 1678                            "No language server found to format buffer '{:?}'. Skipping",
 1679                            buffer_path_abs.as_path().to_string_lossy()
 1680                        );
 1681                        continue;
 1682                    };
 1683
 1684                    zlog::trace!(
 1685                        logger =>
 1686                        "Formatting buffer '{:?}' using language server '{:?}'",
 1687                        buffer_path_abs.as_path().to_string_lossy(),
 1688                        language_server.name()
 1689                    );
 1690
 1691                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1692                        zlog::trace!(logger => "formatting ranges");
 1693                        Self::format_ranges_via_lsp(
 1694                            &lsp_store,
 1695                            &buffer.handle,
 1696                            ranges,
 1697                            buffer_path_abs,
 1698                            &language_server,
 1699                            &settings,
 1700                            cx,
 1701                        )
 1702                        .await
 1703                        .context("Failed to format ranges via language server")?
 1704                    } else {
 1705                        zlog::trace!(logger => "formatting full");
 1706                        Self::format_via_lsp(
 1707                            &lsp_store,
 1708                            &buffer.handle,
 1709                            buffer_path_abs,
 1710                            &language_server,
 1711                            &settings,
 1712                            cx,
 1713                        )
 1714                        .await
 1715                        .context("failed to format via language server")?
 1716                    };
 1717
 1718                    if edits.is_empty() {
 1719                        zlog::trace!(logger => "No changes");
 1720                        continue;
 1721                    }
 1722                    extend_formatting_transaction(
 1723                        buffer,
 1724                        formatting_transaction_id,
 1725                        cx,
 1726                        |buffer, cx| {
 1727                            buffer.edit(edits, None, cx);
 1728                        },
 1729                    )?;
 1730                }
 1731                Formatter::CodeAction(code_action_name) => {
 1732                    let logger = zlog::scoped!(logger => "code-actions");
 1733                    zlog::trace!(logger => "formatting");
 1734                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1735
 1736                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1737                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1738                        continue;
 1739                    };
 1740
 1741                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1742                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1743
 1744                    let mut actions_and_servers = Vec::new();
 1745
 1746                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1747                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1748                            &lsp_store,
 1749                            language_server.server_id(),
 1750                            vec![code_action_kind.clone()],
 1751                            &buffer.handle,
 1752                            cx,
 1753                        )
 1754                        .await
 1755                        .with_context(|| {
 1756                            format!(
 1757                                "Failed to resolve code action {:?} with language server {}",
 1758                                code_action_kind,
 1759                                language_server.name()
 1760                            )
 1761                        });
 1762                        let Ok(actions) = actions_result else {
 1763                            // note: it may be better to set result to the error and break formatters here
 1764                            // but for now we try to execute the actions that we can resolve and skip the rest
 1765                            zlog::error!(
 1766                                logger =>
 1767                                "Failed to resolve code action {:?} with language server {}",
 1768                                code_action_kind,
 1769                                language_server.name()
 1770                            );
 1771                            continue;
 1772                        };
 1773                        for action in actions {
 1774                            actions_and_servers.push((action, index));
 1775                        }
 1776                    }
 1777
 1778                    if actions_and_servers.is_empty() {
 1779                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1780                        continue;
 1781                    }
 1782
 1783                    'actions: for (mut action, server_index) in actions_and_servers {
 1784                        let server = &adapters_and_servers[server_index].1;
 1785
 1786                        let describe_code_action = |action: &CodeAction| {
 1787                            format!(
 1788                                "code action '{}' with title \"{}\" on server {}",
 1789                                action
 1790                                    .lsp_action
 1791                                    .action_kind()
 1792                                    .unwrap_or("unknown".into())
 1793                                    .as_str(),
 1794                                action.lsp_action.title(),
 1795                                server.name(),
 1796                            )
 1797                        };
 1798
 1799                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1800
 1801                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1802                            zlog::error!(
 1803                                logger =>
 1804                                "Failed to resolve {}. Error: {}",
 1805                                describe_code_action(&action),
 1806                                err
 1807                            );
 1808                            continue;
 1809                        }
 1810
 1811                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1812                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1813                            // but filters out and logs warnings for code actions that require unreasonably
 1814                            // difficult handling on our part, such as:
 1815                            // - applying edits that call commands
 1816                            //   which can result in arbitrary workspace edits being sent from the server that
 1817                            //   have no way of being tied back to the command that initiated them (i.e. we
 1818                            //   can't know which edits are part of the format request, or if the server is done sending
 1819                            //   actions in response to the command)
 1820                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1821                            //   as we then would need to handle such changes correctly in the local history as well
 1822                            //   as the remote history through the ProjectTransaction
 1823                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1824                            // Supporting these actions is not impossible, but not supported as of yet.
 1825                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1826                                zlog::trace!(
 1827                                    logger =>
 1828                                    "No changes for code action. Skipping {}",
 1829                                    describe_code_action(&action),
 1830                                );
 1831                                continue;
 1832                            }
 1833
 1834                            let mut operations = Vec::new();
 1835                            if let Some(document_changes) = edit.document_changes {
 1836                                match document_changes {
 1837                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1838                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1839                                    ),
 1840                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1841                                }
 1842                            } else if let Some(changes) = edit.changes {
 1843                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1844                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1845                                        text_document:
 1846                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1847                                                uri,
 1848                                                version: None,
 1849                                            },
 1850                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1851                                    })
 1852                                }));
 1853                            }
 1854
 1855                            let mut edits = Vec::with_capacity(operations.len());
 1856
 1857                            if operations.is_empty() {
 1858                                zlog::trace!(
 1859                                    logger =>
 1860                                    "No changes for code action. Skipping {}",
 1861                                    describe_code_action(&action),
 1862                                );
 1863                                continue;
 1864                            }
 1865                            for operation in operations {
 1866                                let op = match operation {
 1867                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1868                                    lsp::DocumentChangeOperation::Op(_) => {
 1869                                        zlog::warn!(
 1870                                            logger =>
 1871                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1872                                            describe_code_action(&action),
 1873                                        );
 1874                                        continue 'actions;
 1875                                    }
 1876                                };
 1877                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1878                                    zlog::warn!(
 1879                                        logger =>
 1880                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1881                                        &op.text_document.uri,
 1882                                        describe_code_action(&action),
 1883                                    );
 1884                                    continue 'actions;
 1885                                };
 1886                                if &file_path != buffer_path_abs {
 1887                                    zlog::warn!(
 1888                                        logger =>
 1889                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1890                                        file_path,
 1891                                        buffer_path_abs,
 1892                                        describe_code_action(&action),
 1893                                    );
 1894                                    continue 'actions;
 1895                                }
 1896
 1897                                let mut lsp_edits = Vec::new();
 1898                                for edit in op.edits {
 1899                                    match edit {
 1900                                        Edit::Plain(edit) => {
 1901                                            if !lsp_edits.contains(&edit) {
 1902                                                lsp_edits.push(edit);
 1903                                            }
 1904                                        }
 1905                                        Edit::Annotated(edit) => {
 1906                                            if !lsp_edits.contains(&edit.text_edit) {
 1907                                                lsp_edits.push(edit.text_edit);
 1908                                            }
 1909                                        }
 1910                                        Edit::Snippet(_) => {
 1911                                            zlog::warn!(
 1912                                                logger =>
 1913                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1914                                                describe_code_action(&action),
 1915                                            );
 1916                                            continue 'actions;
 1917                                        }
 1918                                    }
 1919                                }
 1920                                let edits_result = lsp_store
 1921                                    .update(cx, |lsp_store, cx| {
 1922                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1923                                            &buffer.handle,
 1924                                            lsp_edits,
 1925                                            server.server_id(),
 1926                                            op.text_document.version,
 1927                                            cx,
 1928                                        )
 1929                                    })?
 1930                                    .await;
 1931                                let Ok(resolved_edits) = edits_result else {
 1932                                    zlog::warn!(
 1933                                        logger =>
 1934                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1935                                        buffer_path_abs.as_path(),
 1936                                        describe_code_action(&action),
 1937                                    );
 1938                                    continue 'actions;
 1939                                };
 1940                                edits.extend(resolved_edits);
 1941                            }
 1942
 1943                            if edits.is_empty() {
 1944                                zlog::warn!(logger => "No edits resolved from LSP");
 1945                                continue;
 1946                            }
 1947
 1948                            extend_formatting_transaction(
 1949                                buffer,
 1950                                formatting_transaction_id,
 1951                                cx,
 1952                                |buffer, cx| {
 1953                                    zlog::info!(
 1954                                        "Applying edits {edits:?}. Content: {:?}",
 1955                                        buffer.text()
 1956                                    );
 1957                                    buffer.edit(edits, None, cx);
 1958                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1959                                },
 1960                            )?;
 1961                        }
 1962
 1963                        if let Some(command) = action.lsp_action.command() {
 1964                            zlog::warn!(
 1965                                logger =>
 1966                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1967                                &command.command,
 1968                            );
 1969
 1970                            // bail early if command is invalid
 1971                            let server_capabilities = server.capabilities();
 1972                            let available_commands = server_capabilities
 1973                                .execute_command_provider
 1974                                .as_ref()
 1975                                .map(|options| options.commands.as_slice())
 1976                                .unwrap_or_default();
 1977                            if !available_commands.contains(&command.command) {
 1978                                zlog::warn!(
 1979                                    logger =>
 1980                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1981                                    command.command,
 1982                                    server.name(),
 1983                                );
 1984                                continue;
 1985                            }
 1986
 1987                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1988                            extend_formatting_transaction(
 1989                                buffer,
 1990                                formatting_transaction_id,
 1991                                cx,
 1992                                |_, _| {},
 1993                            )?;
 1994                            zlog::info!(logger => "Executing command {}", &command.command);
 1995
 1996                            lsp_store.update(cx, |this, _| {
 1997                                this.as_local_mut()
 1998                                    .unwrap()
 1999                                    .last_workspace_edits_by_language_server
 2000                                    .remove(&server.server_id());
 2001                            })?;
 2002
 2003                            let execute_command_result = server
 2004                                .request::<lsp::request::ExecuteCommand>(
 2005                                    lsp::ExecuteCommandParams {
 2006                                        command: command.command.clone(),
 2007                                        arguments: command.arguments.clone().unwrap_or_default(),
 2008                                        ..Default::default()
 2009                                    },
 2010                                )
 2011                                .await
 2012                                .into_response();
 2013
 2014                            if execute_command_result.is_err() {
 2015                                zlog::error!(
 2016                                    logger =>
 2017                                    "Failed to execute command '{}' as part of {}",
 2018                                    &command.command,
 2019                                    describe_code_action(&action),
 2020                                );
 2021                                continue 'actions;
 2022                            }
 2023
 2024                            let mut project_transaction_command =
 2025                                lsp_store.update(cx, |this, _| {
 2026                                    this.as_local_mut()
 2027                                        .unwrap()
 2028                                        .last_workspace_edits_by_language_server
 2029                                        .remove(&server.server_id())
 2030                                        .unwrap_or_default()
 2031                                })?;
 2032
 2033                            if let Some(transaction) =
 2034                                project_transaction_command.0.remove(&buffer.handle)
 2035                            {
 2036                                zlog::trace!(
 2037                                    logger =>
 2038                                    "Successfully captured {} edits that resulted from command {}",
 2039                                    transaction.edit_ids.len(),
 2040                                    &command.command,
 2041                                );
 2042                                let transaction_id_project_transaction = transaction.id;
 2043                                buffer.handle.update(cx, |buffer, _| {
 2044                                    // it may have been removed from history if push_to_history was
 2045                                    // false in deserialize_workspace_edit. If so push it so we
 2046                                    // can merge it with the format transaction
 2047                                    // and pop the combined transaction off the history stack
 2048                                    // later if push_to_history is false
 2049                                    if buffer.get_transaction(transaction.id).is_none() {
 2050                                        buffer.push_transaction(transaction, Instant::now());
 2051                                    }
 2052                                    buffer.merge_transactions(
 2053                                        transaction_id_project_transaction,
 2054                                        formatting_transaction_id,
 2055                                    );
 2056                                })?;
 2057                            }
 2058
 2059                            if !project_transaction_command.0.is_empty() {
 2060                                let mut extra_buffers = String::new();
 2061                                for buffer in project_transaction_command.0.keys() {
 2062                                    buffer
 2063                                        .read_with(cx, |b, cx| {
 2064                                            if let Some(path) = b.project_path(cx) {
 2065                                                if !extra_buffers.is_empty() {
 2066                                                    extra_buffers.push_str(", ");
 2067                                                }
 2068                                                extra_buffers.push_str(path.path.as_unix_str());
 2069                                            }
 2070                                        })
 2071                                        .ok();
 2072                                }
 2073                                zlog::warn!(
 2074                                    logger =>
 2075                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2076                                    &command.command,
 2077                                    extra_buffers,
 2078                                );
 2079                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2080                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2081                                // add it so it's included, and merge it into the format transaction when its created later
 2082                            }
 2083                        }
 2084                    }
 2085                }
 2086            }
 2087        }
 2088
 2089        Ok(())
 2090    }
 2091
 2092    pub async fn format_ranges_via_lsp(
 2093        this: &WeakEntity<LspStore>,
 2094        buffer_handle: &Entity<Buffer>,
 2095        ranges: &[Range<Anchor>],
 2096        abs_path: &Path,
 2097        language_server: &Arc<LanguageServer>,
 2098        settings: &LanguageSettings,
 2099        cx: &mut AsyncApp,
 2100    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2101        let capabilities = &language_server.capabilities();
 2102        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2103        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2104            anyhow::bail!(
 2105                "{} language server does not support range formatting",
 2106                language_server.name()
 2107            );
 2108        }
 2109
 2110        let uri = file_path_to_lsp_url(abs_path)?;
 2111        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2112
 2113        let lsp_edits = {
 2114            let mut lsp_ranges = Vec::new();
 2115            this.update(cx, |_this, cx| {
 2116                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2117                // not have been sent to the language server. This seems like a fairly systemic
 2118                // issue, though, the resolution probably is not specific to formatting.
 2119                //
 2120                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2121                // LSP.
 2122                let snapshot = buffer_handle.read(cx).snapshot();
 2123                for range in ranges {
 2124                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2125                }
 2126                anyhow::Ok(())
 2127            })??;
 2128
 2129            let mut edits = None;
 2130            for range in lsp_ranges {
 2131                if let Some(mut edit) = language_server
 2132                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2133                        text_document: text_document.clone(),
 2134                        range,
 2135                        options: lsp_command::lsp_formatting_options(settings),
 2136                        work_done_progress_params: Default::default(),
 2137                    })
 2138                    .await
 2139                    .into_response()?
 2140                {
 2141                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2142                }
 2143            }
 2144            edits
 2145        };
 2146
 2147        if let Some(lsp_edits) = lsp_edits {
 2148            this.update(cx, |this, cx| {
 2149                this.as_local_mut().unwrap().edits_from_lsp(
 2150                    buffer_handle,
 2151                    lsp_edits,
 2152                    language_server.server_id(),
 2153                    None,
 2154                    cx,
 2155                )
 2156            })?
 2157            .await
 2158        } else {
 2159            Ok(Vec::with_capacity(0))
 2160        }
 2161    }
 2162
 2163    async fn format_via_lsp(
 2164        this: &WeakEntity<LspStore>,
 2165        buffer: &Entity<Buffer>,
 2166        abs_path: &Path,
 2167        language_server: &Arc<LanguageServer>,
 2168        settings: &LanguageSettings,
 2169        cx: &mut AsyncApp,
 2170    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2171        let logger = zlog::scoped!("lsp_format");
 2172        zlog::debug!(logger => "Formatting via LSP");
 2173
 2174        let uri = file_path_to_lsp_url(abs_path)?;
 2175        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2176        let capabilities = &language_server.capabilities();
 2177
 2178        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2179        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2180
 2181        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2182            let _timer = zlog::time!(logger => "format-full");
 2183            language_server
 2184                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2185                    text_document,
 2186                    options: lsp_command::lsp_formatting_options(settings),
 2187                    work_done_progress_params: Default::default(),
 2188                })
 2189                .await
 2190                .into_response()?
 2191        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2192            let _timer = zlog::time!(logger => "format-range");
 2193            let buffer_start = lsp::Position::new(0, 0);
 2194            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2195            language_server
 2196                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2197                    text_document: text_document.clone(),
 2198                    range: lsp::Range::new(buffer_start, buffer_end),
 2199                    options: lsp_command::lsp_formatting_options(settings),
 2200                    work_done_progress_params: Default::default(),
 2201                })
 2202                .await
 2203                .into_response()?
 2204        } else {
 2205            None
 2206        };
 2207
 2208        if let Some(lsp_edits) = lsp_edits {
 2209            this.update(cx, |this, cx| {
 2210                this.as_local_mut().unwrap().edits_from_lsp(
 2211                    buffer,
 2212                    lsp_edits,
 2213                    language_server.server_id(),
 2214                    None,
 2215                    cx,
 2216                )
 2217            })?
 2218            .await
 2219        } else {
 2220            Ok(Vec::with_capacity(0))
 2221        }
 2222    }
 2223
 2224    async fn format_via_external_command(
 2225        buffer: &FormattableBuffer,
 2226        command: &str,
 2227        arguments: Option<&[String]>,
 2228        cx: &mut AsyncApp,
 2229    ) -> Result<Option<Diff>> {
 2230        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2231            let file = File::from_dyn(buffer.file())?;
 2232            let worktree = file.worktree.read(cx);
 2233            let mut worktree_path = worktree.abs_path().to_path_buf();
 2234            if worktree.root_entry()?.is_file() {
 2235                worktree_path.pop();
 2236            }
 2237            Some(worktree_path)
 2238        })?;
 2239
 2240        let mut child = util::command::new_smol_command(command);
 2241
 2242        if let Some(buffer_env) = buffer.env.as_ref() {
 2243            child.envs(buffer_env);
 2244        }
 2245
 2246        if let Some(working_dir_path) = working_dir_path {
 2247            child.current_dir(working_dir_path);
 2248        }
 2249
 2250        if let Some(arguments) = arguments {
 2251            child.args(arguments.iter().map(|arg| {
 2252                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2253                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2254                } else {
 2255                    arg.replace("{buffer_path}", "Untitled")
 2256                }
 2257            }));
 2258        }
 2259
 2260        let mut child = child
 2261            .stdin(smol::process::Stdio::piped())
 2262            .stdout(smol::process::Stdio::piped())
 2263            .stderr(smol::process::Stdio::piped())
 2264            .spawn()?;
 2265
 2266        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2267        let text = buffer
 2268            .handle
 2269            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2270        for chunk in text.chunks() {
 2271            stdin.write_all(chunk.as_bytes()).await?;
 2272        }
 2273        stdin.flush().await?;
 2274
 2275        let output = child.output().await?;
 2276        anyhow::ensure!(
 2277            output.status.success(),
 2278            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2279            output.status.code(),
 2280            String::from_utf8_lossy(&output.stdout),
 2281            String::from_utf8_lossy(&output.stderr),
 2282        );
 2283
 2284        let stdout = String::from_utf8(output.stdout)?;
 2285        Ok(Some(
 2286            buffer
 2287                .handle
 2288                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2289                .await,
 2290        ))
 2291    }
 2292
 2293    async fn try_resolve_code_action(
 2294        lang_server: &LanguageServer,
 2295        action: &mut CodeAction,
 2296    ) -> anyhow::Result<()> {
 2297        match &mut action.lsp_action {
 2298            LspAction::Action(lsp_action) => {
 2299                if !action.resolved
 2300                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2301                    && lsp_action.data.is_some()
 2302                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2303                {
 2304                    **lsp_action = lang_server
 2305                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2306                        .await
 2307                        .into_response()?;
 2308                }
 2309            }
 2310            LspAction::CodeLens(lens) => {
 2311                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2312                    *lens = lang_server
 2313                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2314                        .await
 2315                        .into_response()?;
 2316                }
 2317            }
 2318            LspAction::Command(_) => {}
 2319        }
 2320
 2321        action.resolved = true;
 2322        anyhow::Ok(())
 2323    }
 2324
 2325    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2326        let buffer = buffer_handle.read(cx);
 2327
 2328        let file = buffer.file().cloned();
 2329
 2330        let Some(file) = File::from_dyn(file.as_ref()) else {
 2331            return;
 2332        };
 2333        if !file.is_local() {
 2334            return;
 2335        }
 2336        let path = ProjectPath::from_file(file, cx);
 2337        let worktree_id = file.worktree_id(cx);
 2338        let language = buffer.language().cloned();
 2339
 2340        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2341            for (server_id, diagnostics) in
 2342                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2343            {
 2344                self.update_buffer_diagnostics(
 2345                    buffer_handle,
 2346                    server_id,
 2347                    None,
 2348                    None,
 2349                    None,
 2350                    Vec::new(),
 2351                    diagnostics,
 2352                    cx,
 2353                )
 2354                .log_err();
 2355            }
 2356        }
 2357        let Some(language) = language else {
 2358            return;
 2359        };
 2360        let Some(snapshot) = self
 2361            .worktree_store
 2362            .read(cx)
 2363            .worktree_for_id(worktree_id, cx)
 2364            .map(|worktree| worktree.read(cx).snapshot())
 2365        else {
 2366            return;
 2367        };
 2368        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2369
 2370        for server_id in
 2371            self.lsp_tree
 2372                .get(path, language.name(), language.manifest(), &delegate, cx)
 2373        {
 2374            let server = self
 2375                .language_servers
 2376                .get(&server_id)
 2377                .and_then(|server_state| {
 2378                    if let LanguageServerState::Running { server, .. } = server_state {
 2379                        Some(server.clone())
 2380                    } else {
 2381                        None
 2382                    }
 2383                });
 2384            let server = match server {
 2385                Some(server) => server,
 2386                None => continue,
 2387            };
 2388
 2389            buffer_handle.update(cx, |buffer, cx| {
 2390                buffer.set_completion_triggers(
 2391                    server.server_id(),
 2392                    server
 2393                        .capabilities()
 2394                        .completion_provider
 2395                        .as_ref()
 2396                        .and_then(|provider| {
 2397                            provider
 2398                                .trigger_characters
 2399                                .as_ref()
 2400                                .map(|characters| characters.iter().cloned().collect())
 2401                        })
 2402                        .unwrap_or_default(),
 2403                    cx,
 2404                );
 2405            });
 2406        }
 2407    }
 2408
 2409    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2410        buffer.update(cx, |buffer, cx| {
 2411            let Some(language) = buffer.language() else {
 2412                return;
 2413            };
 2414            let path = ProjectPath {
 2415                worktree_id: old_file.worktree_id(cx),
 2416                path: old_file.path.clone(),
 2417            };
 2418            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2419                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2420                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2421            }
 2422        });
 2423    }
 2424
 2425    fn update_buffer_diagnostics(
 2426        &mut self,
 2427        buffer: &Entity<Buffer>,
 2428        server_id: LanguageServerId,
 2429        registration_id: Option<Option<SharedString>>,
 2430        result_id: Option<SharedString>,
 2431        version: Option<i32>,
 2432        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2433        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2434        cx: &mut Context<LspStore>,
 2435    ) -> Result<()> {
 2436        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2437            Ordering::Equal
 2438                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2439                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2440                .then_with(|| a.severity.cmp(&b.severity))
 2441                .then_with(|| a.message.cmp(&b.message))
 2442        }
 2443
 2444        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2445        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2446        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2447
 2448        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2449            Ordering::Equal
 2450                .then_with(|| a.range.start.cmp(&b.range.start))
 2451                .then_with(|| b.range.end.cmp(&a.range.end))
 2452                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2453        });
 2454
 2455        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2456
 2457        let edits_since_save = std::cell::LazyCell::new(|| {
 2458            let saved_version = buffer.read(cx).saved_version();
 2459            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2460        });
 2461
 2462        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2463
 2464        for (new_diagnostic, entry) in diagnostics {
 2465            let start;
 2466            let end;
 2467            if new_diagnostic && entry.diagnostic.is_disk_based {
 2468                // Some diagnostics are based on files on disk instead of buffers'
 2469                // current contents. Adjust these diagnostics' ranges to reflect
 2470                // any unsaved edits.
 2471                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2472                // and were properly adjusted on reuse.
 2473                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2474                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2475            } else {
 2476                start = entry.range.start;
 2477                end = entry.range.end;
 2478            }
 2479
 2480            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2481                ..snapshot.clip_point_utf16(end, Bias::Right);
 2482
 2483            // Expand empty ranges by one codepoint
 2484            if range.start == range.end {
 2485                // This will be go to the next boundary when being clipped
 2486                range.end.column += 1;
 2487                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2488                if range.start == range.end && range.end.column > 0 {
 2489                    range.start.column -= 1;
 2490                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2491                }
 2492            }
 2493
 2494            sanitized_diagnostics.push(DiagnosticEntry {
 2495                range,
 2496                diagnostic: entry.diagnostic,
 2497            });
 2498        }
 2499        drop(edits_since_save);
 2500
 2501        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2502        buffer.update(cx, |buffer, cx| {
 2503            if let Some(registration_id) = registration_id {
 2504                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2505                    self.buffer_pull_diagnostics_result_ids
 2506                        .entry(server_id)
 2507                        .or_default()
 2508                        .entry(registration_id)
 2509                        .or_default()
 2510                        .insert(abs_path, result_id);
 2511                }
 2512            }
 2513
 2514            buffer.update_diagnostics(server_id, set, cx)
 2515        });
 2516
 2517        Ok(())
 2518    }
 2519
 2520    fn register_language_server_for_invisible_worktree(
 2521        &mut self,
 2522        worktree: &Entity<Worktree>,
 2523        language_server_id: LanguageServerId,
 2524        cx: &mut App,
 2525    ) {
 2526        let worktree = worktree.read(cx);
 2527        let worktree_id = worktree.id();
 2528        debug_assert!(!worktree.is_visible());
 2529        let Some(mut origin_seed) = self
 2530            .language_server_ids
 2531            .iter()
 2532            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2533        else {
 2534            return;
 2535        };
 2536        origin_seed.worktree_id = worktree_id;
 2537        self.language_server_ids
 2538            .entry(origin_seed)
 2539            .or_insert_with(|| UnifiedLanguageServer {
 2540                id: language_server_id,
 2541                project_roots: Default::default(),
 2542            });
 2543    }
 2544
 2545    fn register_buffer_with_language_servers(
 2546        &mut self,
 2547        buffer_handle: &Entity<Buffer>,
 2548        only_register_servers: HashSet<LanguageServerSelector>,
 2549        cx: &mut Context<LspStore>,
 2550    ) {
 2551        let buffer = buffer_handle.read(cx);
 2552        let buffer_id = buffer.remote_id();
 2553
 2554        let Some(file) = File::from_dyn(buffer.file()) else {
 2555            return;
 2556        };
 2557        if !file.is_local() {
 2558            return;
 2559        }
 2560
 2561        let abs_path = file.abs_path(cx);
 2562        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2563            return;
 2564        };
 2565        let initial_snapshot = buffer.text_snapshot();
 2566        let worktree_id = file.worktree_id(cx);
 2567
 2568        let Some(language) = buffer.language().cloned() else {
 2569            return;
 2570        };
 2571        let path: Arc<RelPath> = file
 2572            .path()
 2573            .parent()
 2574            .map(Arc::from)
 2575            .unwrap_or_else(|| file.path().clone());
 2576        let Some(worktree) = self
 2577            .worktree_store
 2578            .read(cx)
 2579            .worktree_for_id(worktree_id, cx)
 2580        else {
 2581            return;
 2582        };
 2583        let language_name = language.name();
 2584        let (reused, delegate, servers) = self
 2585            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2586            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2587            .unwrap_or_else(|| {
 2588                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2589                let delegate: Arc<dyn ManifestDelegate> =
 2590                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2591
 2592                let servers = self
 2593                    .lsp_tree
 2594                    .walk(
 2595                        ProjectPath { worktree_id, path },
 2596                        language.name(),
 2597                        language.manifest(),
 2598                        &delegate,
 2599                        cx,
 2600                    )
 2601                    .collect::<Vec<_>>();
 2602                (false, lsp_delegate, servers)
 2603            });
 2604        let servers_and_adapters = servers
 2605            .into_iter()
 2606            .filter_map(|server_node| {
 2607                if reused && server_node.server_id().is_none() {
 2608                    return None;
 2609                }
 2610                if !only_register_servers.is_empty() {
 2611                    if let Some(server_id) = server_node.server_id()
 2612                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2613                    {
 2614                        return None;
 2615                    }
 2616                    if let Some(name) = server_node.name()
 2617                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2618                    {
 2619                        return None;
 2620                    }
 2621                }
 2622
 2623                let server_id = server_node.server_id_or_init(|disposition| {
 2624                    let path = &disposition.path;
 2625
 2626                    {
 2627                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2628
 2629                        let server_id = self.get_or_insert_language_server(
 2630                            &worktree,
 2631                            delegate.clone(),
 2632                            disposition,
 2633                            &language_name,
 2634                            cx,
 2635                        );
 2636
 2637                        if let Some(state) = self.language_servers.get(&server_id)
 2638                            && let Ok(uri) = uri
 2639                        {
 2640                            state.add_workspace_folder(uri);
 2641                        };
 2642                        server_id
 2643                    }
 2644                })?;
 2645                let server_state = self.language_servers.get(&server_id)?;
 2646                if let LanguageServerState::Running {
 2647                    server, adapter, ..
 2648                } = server_state
 2649                {
 2650                    Some((server.clone(), adapter.clone()))
 2651                } else {
 2652                    None
 2653                }
 2654            })
 2655            .collect::<Vec<_>>();
 2656        for (server, adapter) in servers_and_adapters {
 2657            buffer_handle.update(cx, |buffer, cx| {
 2658                buffer.set_completion_triggers(
 2659                    server.server_id(),
 2660                    server
 2661                        .capabilities()
 2662                        .completion_provider
 2663                        .as_ref()
 2664                        .and_then(|provider| {
 2665                            provider
 2666                                .trigger_characters
 2667                                .as_ref()
 2668                                .map(|characters| characters.iter().cloned().collect())
 2669                        })
 2670                        .unwrap_or_default(),
 2671                    cx,
 2672                );
 2673            });
 2674
 2675            let snapshot = LspBufferSnapshot {
 2676                version: 0,
 2677                snapshot: initial_snapshot.clone(),
 2678            };
 2679
 2680            let mut registered = false;
 2681            self.buffer_snapshots
 2682                .entry(buffer_id)
 2683                .or_default()
 2684                .entry(server.server_id())
 2685                .or_insert_with(|| {
 2686                    registered = true;
 2687                    server.register_buffer(
 2688                        uri.clone(),
 2689                        adapter.language_id(&language.name()),
 2690                        0,
 2691                        initial_snapshot.text(),
 2692                    );
 2693
 2694                    vec![snapshot]
 2695                });
 2696
 2697            self.buffers_opened_in_servers
 2698                .entry(buffer_id)
 2699                .or_default()
 2700                .insert(server.server_id());
 2701            if registered {
 2702                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2703                    language_server_id: server.server_id(),
 2704                    name: None,
 2705                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2706                        proto::RegisteredForBuffer {
 2707                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2708                            buffer_id: buffer_id.to_proto(),
 2709                        },
 2710                    ),
 2711                });
 2712            }
 2713        }
 2714    }
 2715
 2716    fn reuse_existing_language_server<'lang_name>(
 2717        &self,
 2718        server_tree: &LanguageServerTree,
 2719        worktree: &Entity<Worktree>,
 2720        language_name: &'lang_name LanguageName,
 2721        cx: &mut App,
 2722    ) -> Option<(
 2723        Arc<LocalLspAdapterDelegate>,
 2724        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2725    )> {
 2726        if worktree.read(cx).is_visible() {
 2727            return None;
 2728        }
 2729
 2730        let worktree_store = self.worktree_store.read(cx);
 2731        let servers = server_tree
 2732            .instances
 2733            .iter()
 2734            .filter(|(worktree_id, _)| {
 2735                worktree_store
 2736                    .worktree_for_id(**worktree_id, cx)
 2737                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2738            })
 2739            .flat_map(|(worktree_id, servers)| {
 2740                servers
 2741                    .roots
 2742                    .iter()
 2743                    .flat_map(|(_, language_servers)| language_servers)
 2744                    .map(move |(_, (server_node, server_languages))| {
 2745                        (worktree_id, server_node, server_languages)
 2746                    })
 2747                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2748                    .map(|(worktree_id, server_node, _)| {
 2749                        (
 2750                            *worktree_id,
 2751                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2752                        )
 2753                    })
 2754            })
 2755            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2756                acc.entry(worktree_id)
 2757                    .or_insert_with(Vec::new)
 2758                    .push(server_node);
 2759                acc
 2760            })
 2761            .into_values()
 2762            .max_by_key(|servers| servers.len())?;
 2763
 2764        let worktree_id = worktree.read(cx).id();
 2765        let apply = move |tree: &mut LanguageServerTree| {
 2766            for server_node in &servers {
 2767                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2768            }
 2769            servers
 2770        };
 2771
 2772        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2773        Some((delegate, apply))
 2774    }
 2775
 2776    pub(crate) fn unregister_old_buffer_from_language_servers(
 2777        &mut self,
 2778        buffer: &Entity<Buffer>,
 2779        old_file: &File,
 2780        cx: &mut App,
 2781    ) {
 2782        let old_path = match old_file.as_local() {
 2783            Some(local) => local.abs_path(cx),
 2784            None => return,
 2785        };
 2786
 2787        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2788            debug_panic!("{old_path:?} is not parseable as an URI");
 2789            return;
 2790        };
 2791        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2792    }
 2793
 2794    pub(crate) fn unregister_buffer_from_language_servers(
 2795        &mut self,
 2796        buffer: &Entity<Buffer>,
 2797        file_url: &lsp::Uri,
 2798        cx: &mut App,
 2799    ) {
 2800        buffer.update(cx, |buffer, cx| {
 2801            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2802
 2803            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2804                if snapshots
 2805                    .as_mut()
 2806                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2807                {
 2808                    language_server.unregister_buffer(file_url.clone());
 2809                }
 2810            }
 2811        });
 2812    }
 2813
 2814    fn buffer_snapshot_for_lsp_version(
 2815        &mut self,
 2816        buffer: &Entity<Buffer>,
 2817        server_id: LanguageServerId,
 2818        version: Option<i32>,
 2819        cx: &App,
 2820    ) -> Result<TextBufferSnapshot> {
 2821        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2822
 2823        if let Some(version) = version {
 2824            let buffer_id = buffer.read(cx).remote_id();
 2825            let snapshots = if let Some(snapshots) = self
 2826                .buffer_snapshots
 2827                .get_mut(&buffer_id)
 2828                .and_then(|m| m.get_mut(&server_id))
 2829            {
 2830                snapshots
 2831            } else if version == 0 {
 2832                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2833                // We detect this case and treat it as if the version was `None`.
 2834                return Ok(buffer.read(cx).text_snapshot());
 2835            } else {
 2836                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2837            };
 2838
 2839            let found_snapshot = snapshots
 2840                    .binary_search_by_key(&version, |e| e.version)
 2841                    .map(|ix| snapshots[ix].snapshot.clone())
 2842                    .map_err(|_| {
 2843                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2844                    })?;
 2845
 2846            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2847            Ok(found_snapshot)
 2848        } else {
 2849            Ok((buffer.read(cx)).text_snapshot())
 2850        }
 2851    }
 2852
 2853    async fn get_server_code_actions_from_action_kinds(
 2854        lsp_store: &WeakEntity<LspStore>,
 2855        language_server_id: LanguageServerId,
 2856        code_action_kinds: Vec<lsp::CodeActionKind>,
 2857        buffer: &Entity<Buffer>,
 2858        cx: &mut AsyncApp,
 2859    ) -> Result<Vec<CodeAction>> {
 2860        let actions = lsp_store
 2861            .update(cx, move |this, cx| {
 2862                let request = GetCodeActions {
 2863                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2864                    kinds: Some(code_action_kinds),
 2865                };
 2866                let server = LanguageServerToQuery::Other(language_server_id);
 2867                this.request_lsp(buffer.clone(), server, request, cx)
 2868            })?
 2869            .await?;
 2870        Ok(actions)
 2871    }
 2872
 2873    pub async fn execute_code_actions_on_server(
 2874        lsp_store: &WeakEntity<LspStore>,
 2875        language_server: &Arc<LanguageServer>,
 2876
 2877        actions: Vec<CodeAction>,
 2878        push_to_history: bool,
 2879        project_transaction: &mut ProjectTransaction,
 2880        cx: &mut AsyncApp,
 2881    ) -> anyhow::Result<()> {
 2882        for mut action in actions {
 2883            Self::try_resolve_code_action(language_server, &mut action)
 2884                .await
 2885                .context("resolving a formatting code action")?;
 2886
 2887            if let Some(edit) = action.lsp_action.edit() {
 2888                if edit.changes.is_none() && edit.document_changes.is_none() {
 2889                    continue;
 2890                }
 2891
 2892                let new = Self::deserialize_workspace_edit(
 2893                    lsp_store.upgrade().context("project dropped")?,
 2894                    edit.clone(),
 2895                    push_to_history,
 2896                    language_server.clone(),
 2897                    cx,
 2898                )
 2899                .await?;
 2900                project_transaction.0.extend(new.0);
 2901            }
 2902
 2903            if let Some(command) = action.lsp_action.command() {
 2904                let server_capabilities = language_server.capabilities();
 2905                let available_commands = server_capabilities
 2906                    .execute_command_provider
 2907                    .as_ref()
 2908                    .map(|options| options.commands.as_slice())
 2909                    .unwrap_or_default();
 2910                if available_commands.contains(&command.command) {
 2911                    lsp_store.update(cx, |lsp_store, _| {
 2912                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2913                            mode.last_workspace_edits_by_language_server
 2914                                .remove(&language_server.server_id());
 2915                        }
 2916                    })?;
 2917
 2918                    language_server
 2919                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2920                            command: command.command.clone(),
 2921                            arguments: command.arguments.clone().unwrap_or_default(),
 2922                            ..Default::default()
 2923                        })
 2924                        .await
 2925                        .into_response()
 2926                        .context("execute command")?;
 2927
 2928                    lsp_store.update(cx, |this, _| {
 2929                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2930                            project_transaction.0.extend(
 2931                                mode.last_workspace_edits_by_language_server
 2932                                    .remove(&language_server.server_id())
 2933                                    .unwrap_or_default()
 2934                                    .0,
 2935                            )
 2936                        }
 2937                    })?;
 2938                } else {
 2939                    log::warn!(
 2940                        "Cannot execute a command {} not listed in the language server capabilities",
 2941                        command.command
 2942                    )
 2943                }
 2944            }
 2945        }
 2946        Ok(())
 2947    }
 2948
 2949    pub async fn deserialize_text_edits(
 2950        this: Entity<LspStore>,
 2951        buffer_to_edit: Entity<Buffer>,
 2952        edits: Vec<lsp::TextEdit>,
 2953        push_to_history: bool,
 2954        _: Arc<CachedLspAdapter>,
 2955        language_server: Arc<LanguageServer>,
 2956        cx: &mut AsyncApp,
 2957    ) -> Result<Option<Transaction>> {
 2958        let edits = this
 2959            .update(cx, |this, cx| {
 2960                this.as_local_mut().unwrap().edits_from_lsp(
 2961                    &buffer_to_edit,
 2962                    edits,
 2963                    language_server.server_id(),
 2964                    None,
 2965                    cx,
 2966                )
 2967            })?
 2968            .await?;
 2969
 2970        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2971            buffer.finalize_last_transaction();
 2972            buffer.start_transaction();
 2973            for (range, text) in edits {
 2974                buffer.edit([(range, text)], None, cx);
 2975            }
 2976
 2977            if buffer.end_transaction(cx).is_some() {
 2978                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2979                if !push_to_history {
 2980                    buffer.forget_transaction(transaction.id);
 2981                }
 2982                Some(transaction)
 2983            } else {
 2984                None
 2985            }
 2986        })?;
 2987
 2988        Ok(transaction)
 2989    }
 2990
 2991    #[allow(clippy::type_complexity)]
 2992    pub(crate) fn edits_from_lsp(
 2993        &mut self,
 2994        buffer: &Entity<Buffer>,
 2995        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2996        server_id: LanguageServerId,
 2997        version: Option<i32>,
 2998        cx: &mut Context<LspStore>,
 2999    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3000        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3001        cx.background_spawn(async move {
 3002            let snapshot = snapshot?;
 3003            let mut lsp_edits = lsp_edits
 3004                .into_iter()
 3005                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3006                .collect::<Vec<_>>();
 3007
 3008            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3009
 3010            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3011            let mut edits = Vec::new();
 3012            while let Some((range, mut new_text)) = lsp_edits.next() {
 3013                // Clip invalid ranges provided by the language server.
 3014                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3015                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3016
 3017                // Combine any LSP edits that are adjacent.
 3018                //
 3019                // Also, combine LSP edits that are separated from each other by only
 3020                // a newline. This is important because for some code actions,
 3021                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3022                // are separated by unchanged newline characters.
 3023                //
 3024                // In order for the diffing logic below to work properly, any edits that
 3025                // cancel each other out must be combined into one.
 3026                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3027                    if next_range.start.0 > range.end {
 3028                        if next_range.start.0.row > range.end.row + 1
 3029                            || next_range.start.0.column > 0
 3030                            || snapshot.clip_point_utf16(
 3031                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3032                                Bias::Left,
 3033                            ) > range.end
 3034                        {
 3035                            break;
 3036                        }
 3037                        new_text.push('\n');
 3038                    }
 3039                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3040                    new_text.push_str(next_text);
 3041                    lsp_edits.next();
 3042                }
 3043
 3044                // For multiline edits, perform a diff of the old and new text so that
 3045                // we can identify the changes more precisely, preserving the locations
 3046                // of any anchors positioned in the unchanged regions.
 3047                if range.end.row > range.start.row {
 3048                    let offset = range.start.to_offset(&snapshot);
 3049                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3050                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3051                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3052                        (
 3053                            snapshot.anchor_after(offset + range.start)
 3054                                ..snapshot.anchor_before(offset + range.end),
 3055                            replacement,
 3056                        )
 3057                    }));
 3058                } else if range.end == range.start {
 3059                    let anchor = snapshot.anchor_after(range.start);
 3060                    edits.push((anchor..anchor, new_text.into()));
 3061                } else {
 3062                    let edit_start = snapshot.anchor_after(range.start);
 3063                    let edit_end = snapshot.anchor_before(range.end);
 3064                    edits.push((edit_start..edit_end, new_text.into()));
 3065                }
 3066            }
 3067
 3068            Ok(edits)
 3069        })
 3070    }
 3071
 3072    pub(crate) async fn deserialize_workspace_edit(
 3073        this: Entity<LspStore>,
 3074        edit: lsp::WorkspaceEdit,
 3075        push_to_history: bool,
 3076        language_server: Arc<LanguageServer>,
 3077        cx: &mut AsyncApp,
 3078    ) -> Result<ProjectTransaction> {
 3079        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3080
 3081        let mut operations = Vec::new();
 3082        if let Some(document_changes) = edit.document_changes {
 3083            match document_changes {
 3084                lsp::DocumentChanges::Edits(edits) => {
 3085                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3086                }
 3087                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3088            }
 3089        } else if let Some(changes) = edit.changes {
 3090            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3091                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3092                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3093                        uri,
 3094                        version: None,
 3095                    },
 3096                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3097                })
 3098            }));
 3099        }
 3100
 3101        let mut project_transaction = ProjectTransaction::default();
 3102        for operation in operations {
 3103            match operation {
 3104                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3105                    let abs_path = op
 3106                        .uri
 3107                        .to_file_path()
 3108                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3109
 3110                    if let Some(parent_path) = abs_path.parent() {
 3111                        fs.create_dir(parent_path).await?;
 3112                    }
 3113                    if abs_path.ends_with("/") {
 3114                        fs.create_dir(&abs_path).await?;
 3115                    } else {
 3116                        fs.create_file(
 3117                            &abs_path,
 3118                            op.options
 3119                                .map(|options| fs::CreateOptions {
 3120                                    overwrite: options.overwrite.unwrap_or(false),
 3121                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3122                                })
 3123                                .unwrap_or_default(),
 3124                        )
 3125                        .await?;
 3126                    }
 3127                }
 3128
 3129                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3130                    let source_abs_path = op
 3131                        .old_uri
 3132                        .to_file_path()
 3133                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3134                    let target_abs_path = op
 3135                        .new_uri
 3136                        .to_file_path()
 3137                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3138
 3139                    let options = fs::RenameOptions {
 3140                        overwrite: op
 3141                            .options
 3142                            .as_ref()
 3143                            .and_then(|options| options.overwrite)
 3144                            .unwrap_or(false),
 3145                        ignore_if_exists: op
 3146                            .options
 3147                            .as_ref()
 3148                            .and_then(|options| options.ignore_if_exists)
 3149                            .unwrap_or(false),
 3150                        create_parents: true,
 3151                    };
 3152
 3153                    fs.rename(&source_abs_path, &target_abs_path, options)
 3154                        .await?;
 3155                }
 3156
 3157                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3158                    let abs_path = op
 3159                        .uri
 3160                        .to_file_path()
 3161                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3162                    let options = op
 3163                        .options
 3164                        .map(|options| fs::RemoveOptions {
 3165                            recursive: options.recursive.unwrap_or(false),
 3166                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3167                        })
 3168                        .unwrap_or_default();
 3169                    if abs_path.ends_with("/") {
 3170                        fs.remove_dir(&abs_path, options).await?;
 3171                    } else {
 3172                        fs.remove_file(&abs_path, options).await?;
 3173                    }
 3174                }
 3175
 3176                lsp::DocumentChangeOperation::Edit(op) => {
 3177                    let buffer_to_edit = this
 3178                        .update(cx, |this, cx| {
 3179                            this.open_local_buffer_via_lsp(
 3180                                op.text_document.uri.clone(),
 3181                                language_server.server_id(),
 3182                                cx,
 3183                            )
 3184                        })?
 3185                        .await?;
 3186
 3187                    let edits = this
 3188                        .update(cx, |this, cx| {
 3189                            let path = buffer_to_edit.read(cx).project_path(cx);
 3190                            let active_entry = this.active_entry;
 3191                            let is_active_entry = path.is_some_and(|project_path| {
 3192                                this.worktree_store
 3193                                    .read(cx)
 3194                                    .entry_for_path(&project_path, cx)
 3195                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3196                            });
 3197                            let local = this.as_local_mut().unwrap();
 3198
 3199                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3200                            for edit in op.edits {
 3201                                match edit {
 3202                                    Edit::Plain(edit) => {
 3203                                        if !edits.contains(&edit) {
 3204                                            edits.push(edit)
 3205                                        }
 3206                                    }
 3207                                    Edit::Annotated(edit) => {
 3208                                        if !edits.contains(&edit.text_edit) {
 3209                                            edits.push(edit.text_edit)
 3210                                        }
 3211                                    }
 3212                                    Edit::Snippet(edit) => {
 3213                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3214                                        else {
 3215                                            continue;
 3216                                        };
 3217
 3218                                        if is_active_entry {
 3219                                            snippet_edits.push((edit.range, snippet));
 3220                                        } else {
 3221                                            // Since this buffer is not focused, apply a normal edit.
 3222                                            let new_edit = TextEdit {
 3223                                                range: edit.range,
 3224                                                new_text: snippet.text,
 3225                                            };
 3226                                            if !edits.contains(&new_edit) {
 3227                                                edits.push(new_edit);
 3228                                            }
 3229                                        }
 3230                                    }
 3231                                }
 3232                            }
 3233                            if !snippet_edits.is_empty() {
 3234                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3235                                let version = if let Some(buffer_version) = op.text_document.version
 3236                                {
 3237                                    local
 3238                                        .buffer_snapshot_for_lsp_version(
 3239                                            &buffer_to_edit,
 3240                                            language_server.server_id(),
 3241                                            Some(buffer_version),
 3242                                            cx,
 3243                                        )
 3244                                        .ok()
 3245                                        .map(|snapshot| snapshot.version)
 3246                                } else {
 3247                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3248                                };
 3249
 3250                                let most_recent_edit =
 3251                                    version.and_then(|version| version.most_recent());
 3252                                // Check if the edit that triggered that edit has been made by this participant.
 3253
 3254                                if let Some(most_recent_edit) = most_recent_edit {
 3255                                    cx.emit(LspStoreEvent::SnippetEdit {
 3256                                        buffer_id,
 3257                                        edits: snippet_edits,
 3258                                        most_recent_edit,
 3259                                    });
 3260                                }
 3261                            }
 3262
 3263                            local.edits_from_lsp(
 3264                                &buffer_to_edit,
 3265                                edits,
 3266                                language_server.server_id(),
 3267                                op.text_document.version,
 3268                                cx,
 3269                            )
 3270                        })?
 3271                        .await?;
 3272
 3273                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3274                        buffer.finalize_last_transaction();
 3275                        buffer.start_transaction();
 3276                        for (range, text) in edits {
 3277                            buffer.edit([(range, text)], None, cx);
 3278                        }
 3279
 3280                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3281                            if push_to_history {
 3282                                buffer.finalize_last_transaction();
 3283                                buffer.get_transaction(transaction_id).cloned()
 3284                            } else {
 3285                                buffer.forget_transaction(transaction_id)
 3286                            }
 3287                        })
 3288                    })?;
 3289                    if let Some(transaction) = transaction {
 3290                        project_transaction.0.insert(buffer_to_edit, transaction);
 3291                    }
 3292                }
 3293            }
 3294        }
 3295
 3296        Ok(project_transaction)
 3297    }
 3298
 3299    async fn on_lsp_workspace_edit(
 3300        this: WeakEntity<LspStore>,
 3301        params: lsp::ApplyWorkspaceEditParams,
 3302        server_id: LanguageServerId,
 3303        cx: &mut AsyncApp,
 3304    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3305        let this = this.upgrade().context("project project closed")?;
 3306        let language_server = this
 3307            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3308            .context("language server not found")?;
 3309        let transaction = Self::deserialize_workspace_edit(
 3310            this.clone(),
 3311            params.edit,
 3312            true,
 3313            language_server.clone(),
 3314            cx,
 3315        )
 3316        .await
 3317        .log_err();
 3318        this.update(cx, |this, cx| {
 3319            if let Some(transaction) = transaction {
 3320                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3321
 3322                this.as_local_mut()
 3323                    .unwrap()
 3324                    .last_workspace_edits_by_language_server
 3325                    .insert(server_id, transaction);
 3326            }
 3327        })?;
 3328        Ok(lsp::ApplyWorkspaceEditResponse {
 3329            applied: true,
 3330            failed_change: None,
 3331            failure_reason: None,
 3332        })
 3333    }
 3334
 3335    fn remove_worktree(
 3336        &mut self,
 3337        id_to_remove: WorktreeId,
 3338        cx: &mut Context<LspStore>,
 3339    ) -> Vec<LanguageServerId> {
 3340        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3341        self.diagnostics.remove(&id_to_remove);
 3342        self.prettier_store.update(cx, |prettier_store, cx| {
 3343            prettier_store.remove_worktree(id_to_remove, cx);
 3344        });
 3345
 3346        let mut servers_to_remove = BTreeSet::default();
 3347        let mut servers_to_preserve = HashSet::default();
 3348        for (seed, state) in &self.language_server_ids {
 3349            if seed.worktree_id == id_to_remove {
 3350                servers_to_remove.insert(state.id);
 3351            } else {
 3352                servers_to_preserve.insert(state.id);
 3353            }
 3354        }
 3355        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3356        self.language_server_ids
 3357            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3358        for server_id_to_remove in &servers_to_remove {
 3359            self.language_server_watched_paths
 3360                .remove(server_id_to_remove);
 3361            self.language_server_paths_watched_for_rename
 3362                .remove(server_id_to_remove);
 3363            self.last_workspace_edits_by_language_server
 3364                .remove(server_id_to_remove);
 3365            self.language_servers.remove(server_id_to_remove);
 3366            self.buffer_pull_diagnostics_result_ids
 3367                .remove(server_id_to_remove);
 3368            self.workspace_pull_diagnostics_result_ids
 3369                .remove(server_id_to_remove);
 3370            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3371                buffer_servers.remove(server_id_to_remove);
 3372            }
 3373            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3374        }
 3375        servers_to_remove.into_iter().collect()
 3376    }
 3377
 3378    fn rebuild_watched_paths_inner<'a>(
 3379        &'a self,
 3380        language_server_id: LanguageServerId,
 3381        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3382        cx: &mut Context<LspStore>,
 3383    ) -> LanguageServerWatchedPathsBuilder {
 3384        let worktrees = self
 3385            .worktree_store
 3386            .read(cx)
 3387            .worktrees()
 3388            .filter_map(|worktree| {
 3389                self.language_servers_for_worktree(worktree.read(cx).id())
 3390                    .find(|server| server.server_id() == language_server_id)
 3391                    .map(|_| worktree)
 3392            })
 3393            .collect::<Vec<_>>();
 3394
 3395        let mut worktree_globs = HashMap::default();
 3396        let mut abs_globs = HashMap::default();
 3397        log::trace!(
 3398            "Processing new watcher paths for language server with id {}",
 3399            language_server_id
 3400        );
 3401
 3402        for watcher in watchers {
 3403            if let Some((worktree, literal_prefix, pattern)) =
 3404                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3405            {
 3406                worktree.update(cx, |worktree, _| {
 3407                    if let Some((tree, glob)) =
 3408                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3409                    {
 3410                        tree.add_path_prefix_to_scan(literal_prefix);
 3411                        worktree_globs
 3412                            .entry(tree.id())
 3413                            .or_insert_with(GlobSetBuilder::new)
 3414                            .add(glob);
 3415                    }
 3416                });
 3417            } else {
 3418                let (path, pattern) = match &watcher.glob_pattern {
 3419                    lsp::GlobPattern::String(s) => {
 3420                        let watcher_path = SanitizedPath::new(s);
 3421                        let path = glob_literal_prefix(watcher_path.as_path());
 3422                        let pattern = watcher_path
 3423                            .as_path()
 3424                            .strip_prefix(&path)
 3425                            .map(|p| p.to_string_lossy().into_owned())
 3426                            .unwrap_or_else(|e| {
 3427                                debug_panic!(
 3428                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3429                                    s,
 3430                                    path.display(),
 3431                                    e
 3432                                );
 3433                                watcher_path.as_path().to_string_lossy().into_owned()
 3434                            });
 3435                        (path, pattern)
 3436                    }
 3437                    lsp::GlobPattern::Relative(rp) => {
 3438                        let Ok(mut base_uri) = match &rp.base_uri {
 3439                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3440                            lsp::OneOf::Right(base_uri) => base_uri,
 3441                        }
 3442                        .to_file_path() else {
 3443                            continue;
 3444                        };
 3445
 3446                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3447                        let pattern = Path::new(&rp.pattern)
 3448                            .strip_prefix(&path)
 3449                            .map(|p| p.to_string_lossy().into_owned())
 3450                            .unwrap_or_else(|e| {
 3451                                debug_panic!(
 3452                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3453                                    rp.pattern,
 3454                                    path.display(),
 3455                                    e
 3456                                );
 3457                                rp.pattern.clone()
 3458                            });
 3459                        base_uri.push(path);
 3460                        (base_uri, pattern)
 3461                    }
 3462                };
 3463
 3464                if let Some(glob) = Glob::new(&pattern).log_err() {
 3465                    if !path
 3466                        .components()
 3467                        .any(|c| matches!(c, path::Component::Normal(_)))
 3468                    {
 3469                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3470                        // rather than adding a new watcher for `/`.
 3471                        for worktree in &worktrees {
 3472                            worktree_globs
 3473                                .entry(worktree.read(cx).id())
 3474                                .or_insert_with(GlobSetBuilder::new)
 3475                                .add(glob.clone());
 3476                        }
 3477                    } else {
 3478                        abs_globs
 3479                            .entry(path.into())
 3480                            .or_insert_with(GlobSetBuilder::new)
 3481                            .add(glob);
 3482                    }
 3483                }
 3484            }
 3485        }
 3486
 3487        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3488        for (worktree_id, builder) in worktree_globs {
 3489            if let Ok(globset) = builder.build() {
 3490                watch_builder.watch_worktree(worktree_id, globset);
 3491            }
 3492        }
 3493        for (abs_path, builder) in abs_globs {
 3494            if let Ok(globset) = builder.build() {
 3495                watch_builder.watch_abs_path(abs_path, globset);
 3496            }
 3497        }
 3498        watch_builder
 3499    }
 3500
 3501    fn worktree_and_path_for_file_watcher(
 3502        worktrees: &[Entity<Worktree>],
 3503        watcher: &FileSystemWatcher,
 3504        cx: &App,
 3505    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3506        worktrees.iter().find_map(|worktree| {
 3507            let tree = worktree.read(cx);
 3508            let worktree_root_path = tree.abs_path();
 3509            let path_style = tree.path_style();
 3510            match &watcher.glob_pattern {
 3511                lsp::GlobPattern::String(s) => {
 3512                    let watcher_path = SanitizedPath::new(s);
 3513                    let relative = watcher_path
 3514                        .as_path()
 3515                        .strip_prefix(&worktree_root_path)
 3516                        .ok()?;
 3517                    let literal_prefix = glob_literal_prefix(relative);
 3518                    Some((
 3519                        worktree.clone(),
 3520                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3521                        relative.to_string_lossy().into_owned(),
 3522                    ))
 3523                }
 3524                lsp::GlobPattern::Relative(rp) => {
 3525                    let base_uri = match &rp.base_uri {
 3526                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3527                        lsp::OneOf::Right(base_uri) => base_uri,
 3528                    }
 3529                    .to_file_path()
 3530                    .ok()?;
 3531                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3532                    let mut literal_prefix = relative.to_owned();
 3533                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3534                    Some((
 3535                        worktree.clone(),
 3536                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3537                        rp.pattern.clone(),
 3538                    ))
 3539                }
 3540            }
 3541        })
 3542    }
 3543
 3544    fn rebuild_watched_paths(
 3545        &mut self,
 3546        language_server_id: LanguageServerId,
 3547        cx: &mut Context<LspStore>,
 3548    ) {
 3549        let Some(registrations) = self
 3550            .language_server_dynamic_registrations
 3551            .get(&language_server_id)
 3552        else {
 3553            return;
 3554        };
 3555
 3556        let watch_builder = self.rebuild_watched_paths_inner(
 3557            language_server_id,
 3558            registrations.did_change_watched_files.values().flatten(),
 3559            cx,
 3560        );
 3561        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3562        self.language_server_watched_paths
 3563            .insert(language_server_id, watcher);
 3564
 3565        cx.notify();
 3566    }
 3567
 3568    fn on_lsp_did_change_watched_files(
 3569        &mut self,
 3570        language_server_id: LanguageServerId,
 3571        registration_id: &str,
 3572        params: DidChangeWatchedFilesRegistrationOptions,
 3573        cx: &mut Context<LspStore>,
 3574    ) {
 3575        let registrations = self
 3576            .language_server_dynamic_registrations
 3577            .entry(language_server_id)
 3578            .or_default();
 3579
 3580        registrations
 3581            .did_change_watched_files
 3582            .insert(registration_id.to_string(), params.watchers);
 3583
 3584        self.rebuild_watched_paths(language_server_id, cx);
 3585    }
 3586
 3587    fn on_lsp_unregister_did_change_watched_files(
 3588        &mut self,
 3589        language_server_id: LanguageServerId,
 3590        registration_id: &str,
 3591        cx: &mut Context<LspStore>,
 3592    ) {
 3593        let registrations = self
 3594            .language_server_dynamic_registrations
 3595            .entry(language_server_id)
 3596            .or_default();
 3597
 3598        if registrations
 3599            .did_change_watched_files
 3600            .remove(registration_id)
 3601            .is_some()
 3602        {
 3603            log::info!(
 3604                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3605                language_server_id,
 3606                registration_id
 3607            );
 3608        } else {
 3609            log::warn!(
 3610                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3611                language_server_id,
 3612                registration_id
 3613            );
 3614        }
 3615
 3616        self.rebuild_watched_paths(language_server_id, cx);
 3617    }
 3618
 3619    async fn initialization_options_for_adapter(
 3620        adapter: Arc<dyn LspAdapter>,
 3621        delegate: &Arc<dyn LspAdapterDelegate>,
 3622    ) -> Result<Option<serde_json::Value>> {
 3623        let Some(mut initialization_config) =
 3624            adapter.clone().initialization_options(delegate).await?
 3625        else {
 3626            return Ok(None);
 3627        };
 3628
 3629        for other_adapter in delegate.registered_lsp_adapters() {
 3630            if other_adapter.name() == adapter.name() {
 3631                continue;
 3632            }
 3633            if let Ok(Some(target_config)) = other_adapter
 3634                .clone()
 3635                .additional_initialization_options(adapter.name(), delegate)
 3636                .await
 3637            {
 3638                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3639            }
 3640        }
 3641
 3642        Ok(Some(initialization_config))
 3643    }
 3644
 3645    async fn workspace_configuration_for_adapter(
 3646        adapter: Arc<dyn LspAdapter>,
 3647        delegate: &Arc<dyn LspAdapterDelegate>,
 3648        toolchain: Option<Toolchain>,
 3649        requested_uri: Option<Uri>,
 3650        cx: &mut AsyncApp,
 3651    ) -> Result<serde_json::Value> {
 3652        let mut workspace_config = adapter
 3653            .clone()
 3654            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3655            .await?;
 3656
 3657        for other_adapter in delegate.registered_lsp_adapters() {
 3658            if other_adapter.name() == adapter.name() {
 3659                continue;
 3660            }
 3661            if let Ok(Some(target_config)) = other_adapter
 3662                .clone()
 3663                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3664                .await
 3665            {
 3666                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3667            }
 3668        }
 3669
 3670        Ok(workspace_config)
 3671    }
 3672
 3673    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3674        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3675            Some(server.clone())
 3676        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3677            Some(Arc::clone(server))
 3678        } else {
 3679            None
 3680        }
 3681    }
 3682}
 3683
 3684fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3685    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3686        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3687            language_server_id: server.server_id(),
 3688            name: Some(server.name()),
 3689            message: proto::update_language_server::Variant::MetadataUpdated(
 3690                proto::ServerMetadataUpdated {
 3691                    capabilities: Some(capabilities),
 3692                    binary: Some(proto::LanguageServerBinaryInfo {
 3693                        path: server.binary().path.to_string_lossy().into_owned(),
 3694                        arguments: server
 3695                            .binary()
 3696                            .arguments
 3697                            .iter()
 3698                            .map(|arg| arg.to_string_lossy().into_owned())
 3699                            .collect(),
 3700                    }),
 3701                    configuration: serde_json::to_string(server.configuration()).ok(),
 3702                    workspace_folders: server
 3703                        .workspace_folders()
 3704                        .iter()
 3705                        .map(|uri| uri.to_string())
 3706                        .collect(),
 3707                },
 3708            ),
 3709        });
 3710    }
 3711}
 3712
 3713#[derive(Debug)]
 3714pub struct FormattableBuffer {
 3715    handle: Entity<Buffer>,
 3716    abs_path: Option<PathBuf>,
 3717    env: Option<HashMap<String, String>>,
 3718    ranges: Option<Vec<Range<Anchor>>>,
 3719}
 3720
 3721pub struct RemoteLspStore {
 3722    upstream_client: Option<AnyProtoClient>,
 3723    upstream_project_id: u64,
 3724}
 3725
 3726pub(crate) enum LspStoreMode {
 3727    Local(LocalLspStore),   // ssh host and collab host
 3728    Remote(RemoteLspStore), // collab guest
 3729}
 3730
 3731impl LspStoreMode {
 3732    fn is_local(&self) -> bool {
 3733        matches!(self, LspStoreMode::Local(_))
 3734    }
 3735}
 3736
 3737pub struct LspStore {
 3738    mode: LspStoreMode,
 3739    last_formatting_failure: Option<String>,
 3740    downstream_client: Option<(AnyProtoClient, u64)>,
 3741    nonce: u128,
 3742    buffer_store: Entity<BufferStore>,
 3743    worktree_store: Entity<WorktreeStore>,
 3744    pub languages: Arc<LanguageRegistry>,
 3745    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3746    active_entry: Option<ProjectEntryId>,
 3747    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3748    _maintain_buffer_languages: Task<()>,
 3749    diagnostic_summaries:
 3750        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3751    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3752    lsp_data: HashMap<BufferId, BufferLspData>,
 3753    next_hint_id: Arc<AtomicUsize>,
 3754}
 3755
 3756#[derive(Debug)]
 3757pub struct BufferLspData {
 3758    buffer_version: Global,
 3759    document_colors: Option<DocumentColorData>,
 3760    code_lens: Option<CodeLensData>,
 3761    inlay_hints: BufferInlayHints,
 3762    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3763    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3764}
 3765
 3766#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3767struct LspKey {
 3768    request_type: TypeId,
 3769    server_queried: Option<LanguageServerId>,
 3770}
 3771
 3772impl BufferLspData {
 3773    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3774        Self {
 3775            buffer_version: buffer.read(cx).version(),
 3776            document_colors: None,
 3777            code_lens: None,
 3778            inlay_hints: BufferInlayHints::new(buffer, cx),
 3779            lsp_requests: HashMap::default(),
 3780            chunk_lsp_requests: HashMap::default(),
 3781        }
 3782    }
 3783
 3784    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3785        if let Some(document_colors) = &mut self.document_colors {
 3786            document_colors.colors.remove(&for_server);
 3787            document_colors.cache_version += 1;
 3788        }
 3789
 3790        if let Some(code_lens) = &mut self.code_lens {
 3791            code_lens.lens.remove(&for_server);
 3792        }
 3793
 3794        self.inlay_hints.remove_server_data(for_server);
 3795    }
 3796
 3797    #[cfg(any(test, feature = "test-support"))]
 3798    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3799        &self.inlay_hints
 3800    }
 3801}
 3802
 3803#[derive(Debug, Default, Clone)]
 3804pub struct DocumentColors {
 3805    pub colors: HashSet<DocumentColor>,
 3806    pub cache_version: Option<usize>,
 3807}
 3808
 3809type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3810type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3811
 3812#[derive(Debug, Default)]
 3813struct DocumentColorData {
 3814    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3815    cache_version: usize,
 3816    colors_update: Option<(Global, DocumentColorTask)>,
 3817}
 3818
 3819#[derive(Debug, Default)]
 3820struct CodeLensData {
 3821    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3822    update: Option<(Global, CodeLensTask)>,
 3823}
 3824
 3825#[derive(Debug)]
 3826pub enum LspStoreEvent {
 3827    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3828    LanguageServerRemoved(LanguageServerId),
 3829    LanguageServerUpdate {
 3830        language_server_id: LanguageServerId,
 3831        name: Option<LanguageServerName>,
 3832        message: proto::update_language_server::Variant,
 3833    },
 3834    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3835    LanguageServerPrompt(LanguageServerPromptRequest),
 3836    LanguageDetected {
 3837        buffer: Entity<Buffer>,
 3838        new_language: Option<Arc<Language>>,
 3839    },
 3840    Notification(String),
 3841    RefreshInlayHints {
 3842        server_id: LanguageServerId,
 3843        request_id: Option<usize>,
 3844    },
 3845    RefreshCodeLens,
 3846    DiagnosticsUpdated {
 3847        server_id: LanguageServerId,
 3848        paths: Vec<ProjectPath>,
 3849    },
 3850    DiskBasedDiagnosticsStarted {
 3851        language_server_id: LanguageServerId,
 3852    },
 3853    DiskBasedDiagnosticsFinished {
 3854        language_server_id: LanguageServerId,
 3855    },
 3856    SnippetEdit {
 3857        buffer_id: BufferId,
 3858        edits: Vec<(lsp::Range, Snippet)>,
 3859        most_recent_edit: clock::Lamport,
 3860    },
 3861    WorkspaceEditApplied(ProjectTransaction),
 3862}
 3863
 3864#[derive(Clone, Debug, Serialize)]
 3865pub struct LanguageServerStatus {
 3866    pub name: LanguageServerName,
 3867    pub server_version: Option<SharedString>,
 3868    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3869    pub has_pending_diagnostic_updates: bool,
 3870    pub progress_tokens: HashSet<ProgressToken>,
 3871    pub worktree: Option<WorktreeId>,
 3872    pub binary: Option<LanguageServerBinary>,
 3873    pub configuration: Option<Value>,
 3874    pub workspace_folders: BTreeSet<Uri>,
 3875}
 3876
 3877#[derive(Clone, Debug)]
 3878struct CoreSymbol {
 3879    pub language_server_name: LanguageServerName,
 3880    pub source_worktree_id: WorktreeId,
 3881    pub source_language_server_id: LanguageServerId,
 3882    pub path: SymbolLocation,
 3883    pub name: String,
 3884    pub kind: lsp::SymbolKind,
 3885    pub range: Range<Unclipped<PointUtf16>>,
 3886}
 3887
 3888#[derive(Clone, Debug, PartialEq, Eq)]
 3889pub enum SymbolLocation {
 3890    InProject(ProjectPath),
 3891    OutsideProject {
 3892        abs_path: Arc<Path>,
 3893        signature: [u8; 32],
 3894    },
 3895}
 3896
 3897impl SymbolLocation {
 3898    fn file_name(&self) -> Option<&str> {
 3899        match self {
 3900            Self::InProject(path) => path.path.file_name(),
 3901            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3902        }
 3903    }
 3904}
 3905
 3906impl LspStore {
 3907    pub fn init(client: &AnyProtoClient) {
 3908        client.add_entity_request_handler(Self::handle_lsp_query);
 3909        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3910        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3911        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3912        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3913        client.add_entity_message_handler(Self::handle_start_language_server);
 3914        client.add_entity_message_handler(Self::handle_update_language_server);
 3915        client.add_entity_message_handler(Self::handle_language_server_log);
 3916        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3917        client.add_entity_request_handler(Self::handle_format_buffers);
 3918        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3919        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3920        client.add_entity_request_handler(Self::handle_apply_code_action);
 3921        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3922        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3923        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3924        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3925        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3926        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3927        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3928        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3929        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3930        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3931        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3932        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3933        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3934        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3935        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3936        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3937        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3938
 3939        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3940        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3941        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3942        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3943        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3944        client.add_entity_request_handler(
 3945            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3946        );
 3947        client.add_entity_request_handler(
 3948            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3949        );
 3950        client.add_entity_request_handler(
 3951            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3952        );
 3953    }
 3954
 3955    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3956        match &self.mode {
 3957            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3958            _ => None,
 3959        }
 3960    }
 3961
 3962    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3963        match &self.mode {
 3964            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3965            _ => None,
 3966        }
 3967    }
 3968
 3969    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3970        match &mut self.mode {
 3971            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3972            _ => None,
 3973        }
 3974    }
 3975
 3976    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3977        match &self.mode {
 3978            LspStoreMode::Remote(RemoteLspStore {
 3979                upstream_client: Some(upstream_client),
 3980                upstream_project_id,
 3981                ..
 3982            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3983
 3984            LspStoreMode::Remote(RemoteLspStore {
 3985                upstream_client: None,
 3986                ..
 3987            }) => None,
 3988            LspStoreMode::Local(_) => None,
 3989        }
 3990    }
 3991
 3992    pub fn new_local(
 3993        buffer_store: Entity<BufferStore>,
 3994        worktree_store: Entity<WorktreeStore>,
 3995        prettier_store: Entity<PrettierStore>,
 3996        toolchain_store: Entity<LocalToolchainStore>,
 3997        environment: Entity<ProjectEnvironment>,
 3998        manifest_tree: Entity<ManifestTree>,
 3999        languages: Arc<LanguageRegistry>,
 4000        http_client: Arc<dyn HttpClient>,
 4001        fs: Arc<dyn Fs>,
 4002        cx: &mut Context<Self>,
 4003    ) -> Self {
 4004        let yarn = YarnPathStore::new(fs.clone(), cx);
 4005        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4006            .detach();
 4007        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4008            .detach();
 4009        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4010            .detach();
 4011        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4012            .detach();
 4013        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4014            .detach();
 4015        subscribe_to_binary_statuses(&languages, cx).detach();
 4016
 4017        let _maintain_workspace_config = {
 4018            let (sender, receiver) = watch::channel();
 4019            (Self::maintain_workspace_config(receiver, cx), sender)
 4020        };
 4021
 4022        Self {
 4023            mode: LspStoreMode::Local(LocalLspStore {
 4024                weak: cx.weak_entity(),
 4025                worktree_store: worktree_store.clone(),
 4026
 4027                supplementary_language_servers: Default::default(),
 4028                languages: languages.clone(),
 4029                language_server_ids: Default::default(),
 4030                language_servers: Default::default(),
 4031                last_workspace_edits_by_language_server: Default::default(),
 4032                language_server_watched_paths: Default::default(),
 4033                language_server_paths_watched_for_rename: Default::default(),
 4034                language_server_dynamic_registrations: Default::default(),
 4035                buffers_being_formatted: Default::default(),
 4036                buffer_snapshots: Default::default(),
 4037                prettier_store,
 4038                environment,
 4039                http_client,
 4040                fs,
 4041                yarn,
 4042                next_diagnostic_group_id: Default::default(),
 4043                diagnostics: Default::default(),
 4044                _subscription: cx.on_app_quit(|this, cx| {
 4045                    this.as_local_mut()
 4046                        .unwrap()
 4047                        .shutdown_language_servers_on_quit(cx)
 4048                }),
 4049                lsp_tree: LanguageServerTree::new(
 4050                    manifest_tree,
 4051                    languages.clone(),
 4052                    toolchain_store.clone(),
 4053                ),
 4054                toolchain_store,
 4055                registered_buffers: HashMap::default(),
 4056                buffers_opened_in_servers: HashMap::default(),
 4057                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4058                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4059                restricted_worktrees_tasks: HashMap::default(),
 4060                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4061                    .manifest_file_names(),
 4062            }),
 4063            last_formatting_failure: None,
 4064            downstream_client: None,
 4065            buffer_store,
 4066            worktree_store,
 4067            languages: languages.clone(),
 4068            language_server_statuses: Default::default(),
 4069            nonce: StdRng::from_os_rng().random(),
 4070            diagnostic_summaries: HashMap::default(),
 4071            lsp_server_capabilities: HashMap::default(),
 4072            lsp_data: HashMap::default(),
 4073            next_hint_id: Arc::default(),
 4074            active_entry: None,
 4075            _maintain_workspace_config,
 4076            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4077        }
 4078    }
 4079
 4080    fn send_lsp_proto_request<R: LspCommand>(
 4081        &self,
 4082        buffer: Entity<Buffer>,
 4083        client: AnyProtoClient,
 4084        upstream_project_id: u64,
 4085        request: R,
 4086        cx: &mut Context<LspStore>,
 4087    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4088        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4089            return Task::ready(Ok(R::Response::default()));
 4090        }
 4091        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4092        cx.spawn(async move |this, cx| {
 4093            let response = client.request(message).await?;
 4094            let this = this.upgrade().context("project dropped")?;
 4095            request
 4096                .response_from_proto(response, this, buffer, cx.clone())
 4097                .await
 4098        })
 4099    }
 4100
 4101    pub(super) fn new_remote(
 4102        buffer_store: Entity<BufferStore>,
 4103        worktree_store: Entity<WorktreeStore>,
 4104        languages: Arc<LanguageRegistry>,
 4105        upstream_client: AnyProtoClient,
 4106        project_id: u64,
 4107        cx: &mut Context<Self>,
 4108    ) -> Self {
 4109        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4110            .detach();
 4111        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4112            .detach();
 4113        subscribe_to_binary_statuses(&languages, cx).detach();
 4114        let _maintain_workspace_config = {
 4115            let (sender, receiver) = watch::channel();
 4116            (Self::maintain_workspace_config(receiver, cx), sender)
 4117        };
 4118        Self {
 4119            mode: LspStoreMode::Remote(RemoteLspStore {
 4120                upstream_client: Some(upstream_client),
 4121                upstream_project_id: project_id,
 4122            }),
 4123            downstream_client: None,
 4124            last_formatting_failure: None,
 4125            buffer_store,
 4126            worktree_store,
 4127            languages: languages.clone(),
 4128            language_server_statuses: Default::default(),
 4129            nonce: StdRng::from_os_rng().random(),
 4130            diagnostic_summaries: HashMap::default(),
 4131            lsp_server_capabilities: HashMap::default(),
 4132            next_hint_id: Arc::default(),
 4133            lsp_data: HashMap::default(),
 4134            active_entry: None,
 4135
 4136            _maintain_workspace_config,
 4137            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4138        }
 4139    }
 4140
 4141    fn on_buffer_store_event(
 4142        &mut self,
 4143        _: Entity<BufferStore>,
 4144        event: &BufferStoreEvent,
 4145        cx: &mut Context<Self>,
 4146    ) {
 4147        match event {
 4148            BufferStoreEvent::BufferAdded(buffer) => {
 4149                self.on_buffer_added(buffer, cx).log_err();
 4150            }
 4151            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4152                let buffer_id = buffer.read(cx).remote_id();
 4153                if let Some(local) = self.as_local_mut()
 4154                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4155                {
 4156                    local.reset_buffer(buffer, old_file, cx);
 4157
 4158                    if local.registered_buffers.contains_key(&buffer_id) {
 4159                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4160                    }
 4161                }
 4162
 4163                self.detect_language_for_buffer(buffer, cx);
 4164                if let Some(local) = self.as_local_mut() {
 4165                    local.initialize_buffer(buffer, cx);
 4166                    if local.registered_buffers.contains_key(&buffer_id) {
 4167                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4168                    }
 4169                }
 4170            }
 4171            _ => {}
 4172        }
 4173    }
 4174
 4175    fn on_worktree_store_event(
 4176        &mut self,
 4177        _: Entity<WorktreeStore>,
 4178        event: &WorktreeStoreEvent,
 4179        cx: &mut Context<Self>,
 4180    ) {
 4181        match event {
 4182            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4183                if !worktree.read(cx).is_local() {
 4184                    return;
 4185                }
 4186                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4187                    worktree::Event::UpdatedEntries(changes) => {
 4188                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4189                    }
 4190                    worktree::Event::UpdatedGitRepositories(_)
 4191                    | worktree::Event::DeletedEntry(_) => {}
 4192                })
 4193                .detach()
 4194            }
 4195            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4196            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4197                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4198            }
 4199            WorktreeStoreEvent::WorktreeReleased(..)
 4200            | WorktreeStoreEvent::WorktreeOrderChanged
 4201            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4202            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4203            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4204        }
 4205    }
 4206
 4207    fn on_prettier_store_event(
 4208        &mut self,
 4209        _: Entity<PrettierStore>,
 4210        event: &PrettierStoreEvent,
 4211        cx: &mut Context<Self>,
 4212    ) {
 4213        match event {
 4214            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4215                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4216            }
 4217            PrettierStoreEvent::LanguageServerAdded {
 4218                new_server_id,
 4219                name,
 4220                prettier_server,
 4221            } => {
 4222                self.register_supplementary_language_server(
 4223                    *new_server_id,
 4224                    name.clone(),
 4225                    prettier_server.clone(),
 4226                    cx,
 4227                );
 4228            }
 4229        }
 4230    }
 4231
 4232    fn on_toolchain_store_event(
 4233        &mut self,
 4234        _: Entity<LocalToolchainStore>,
 4235        event: &ToolchainStoreEvent,
 4236        _: &mut Context<Self>,
 4237    ) {
 4238        if let ToolchainStoreEvent::ToolchainActivated = event {
 4239            self.request_workspace_config_refresh()
 4240        }
 4241    }
 4242
 4243    fn request_workspace_config_refresh(&mut self) {
 4244        *self._maintain_workspace_config.1.borrow_mut() = ();
 4245    }
 4246
 4247    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4248        self.as_local().map(|local| local.prettier_store.clone())
 4249    }
 4250
 4251    fn on_buffer_event(
 4252        &mut self,
 4253        buffer: Entity<Buffer>,
 4254        event: &language::BufferEvent,
 4255        cx: &mut Context<Self>,
 4256    ) {
 4257        match event {
 4258            language::BufferEvent::Edited => {
 4259                self.on_buffer_edited(buffer, cx);
 4260            }
 4261
 4262            language::BufferEvent::Saved => {
 4263                self.on_buffer_saved(buffer, cx);
 4264            }
 4265
 4266            _ => {}
 4267        }
 4268    }
 4269
 4270    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4271        buffer
 4272            .read(cx)
 4273            .set_language_registry(self.languages.clone());
 4274
 4275        cx.subscribe(buffer, |this, buffer, event, cx| {
 4276            this.on_buffer_event(buffer, event, cx);
 4277        })
 4278        .detach();
 4279
 4280        self.detect_language_for_buffer(buffer, cx);
 4281        if let Some(local) = self.as_local_mut() {
 4282            local.initialize_buffer(buffer, cx);
 4283        }
 4284
 4285        Ok(())
 4286    }
 4287
 4288    pub(crate) fn register_buffer_with_language_servers(
 4289        &mut self,
 4290        buffer: &Entity<Buffer>,
 4291        only_register_servers: HashSet<LanguageServerSelector>,
 4292        ignore_refcounts: bool,
 4293        cx: &mut Context<Self>,
 4294    ) -> OpenLspBufferHandle {
 4295        let buffer_id = buffer.read(cx).remote_id();
 4296        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4297        if let Some(local) = self.as_local_mut() {
 4298            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4299            if !ignore_refcounts {
 4300                *refcount += 1;
 4301            }
 4302
 4303            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4304            // 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
 4305            // 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
 4306            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4307            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4308                return handle;
 4309            };
 4310            if !file.is_local() {
 4311                return handle;
 4312            }
 4313
 4314            if ignore_refcounts || *refcount == 1 {
 4315                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4316            }
 4317            if !ignore_refcounts {
 4318                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4319                    let refcount = {
 4320                        let local = lsp_store.as_local_mut().unwrap();
 4321                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4322                            debug_panic!("bad refcounting");
 4323                            return;
 4324                        };
 4325
 4326                        *refcount -= 1;
 4327                        *refcount
 4328                    };
 4329                    if refcount == 0 {
 4330                        lsp_store.lsp_data.remove(&buffer_id);
 4331                        let local = lsp_store.as_local_mut().unwrap();
 4332                        local.registered_buffers.remove(&buffer_id);
 4333
 4334                        local.buffers_opened_in_servers.remove(&buffer_id);
 4335                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4336                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4337
 4338                            let buffer_abs_path = file.abs_path(cx);
 4339                            for (_, buffer_pull_diagnostics_result_ids) in
 4340                                &mut local.buffer_pull_diagnostics_result_ids
 4341                            {
 4342                                buffer_pull_diagnostics_result_ids.retain(
 4343                                    |_, buffer_result_ids| {
 4344                                        buffer_result_ids.remove(&buffer_abs_path);
 4345                                        !buffer_result_ids.is_empty()
 4346                                    },
 4347                                );
 4348                            }
 4349
 4350                            let diagnostic_updates = local
 4351                                .language_servers
 4352                                .keys()
 4353                                .cloned()
 4354                                .map(|server_id| DocumentDiagnosticsUpdate {
 4355                                    diagnostics: DocumentDiagnostics {
 4356                                        document_abs_path: buffer_abs_path.clone(),
 4357                                        version: None,
 4358                                        diagnostics: Vec::new(),
 4359                                    },
 4360                                    result_id: None,
 4361                                    registration_id: None,
 4362                                    server_id: server_id,
 4363                                    disk_based_sources: Cow::Borrowed(&[]),
 4364                                })
 4365                                .collect::<Vec<_>>();
 4366
 4367                            lsp_store
 4368                                .merge_diagnostic_entries(
 4369                                    diagnostic_updates,
 4370                                    |_, diagnostic, _| {
 4371                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4372                                    },
 4373                                    cx,
 4374                                )
 4375                                .context("Clearing diagnostics for the closed buffer")
 4376                                .log_err();
 4377                        }
 4378                    }
 4379                })
 4380                .detach();
 4381            }
 4382        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4383            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4384            cx.background_spawn(async move {
 4385                upstream_client
 4386                    .request(proto::RegisterBufferWithLanguageServers {
 4387                        project_id: upstream_project_id,
 4388                        buffer_id,
 4389                        only_servers: only_register_servers
 4390                            .into_iter()
 4391                            .map(|selector| {
 4392                                let selector = match selector {
 4393                                    LanguageServerSelector::Id(language_server_id) => {
 4394                                        proto::language_server_selector::Selector::ServerId(
 4395                                            language_server_id.to_proto(),
 4396                                        )
 4397                                    }
 4398                                    LanguageServerSelector::Name(language_server_name) => {
 4399                                        proto::language_server_selector::Selector::Name(
 4400                                            language_server_name.to_string(),
 4401                                        )
 4402                                    }
 4403                                };
 4404                                proto::LanguageServerSelector {
 4405                                    selector: Some(selector),
 4406                                }
 4407                            })
 4408                            .collect(),
 4409                    })
 4410                    .await
 4411            })
 4412            .detach();
 4413        } else {
 4414            // Our remote connection got closed
 4415        }
 4416        handle
 4417    }
 4418
 4419    fn maintain_buffer_languages(
 4420        languages: Arc<LanguageRegistry>,
 4421        cx: &mut Context<Self>,
 4422    ) -> Task<()> {
 4423        let mut subscription = languages.subscribe();
 4424        let mut prev_reload_count = languages.reload_count();
 4425        cx.spawn(async move |this, cx| {
 4426            while let Some(()) = subscription.next().await {
 4427                if let Some(this) = this.upgrade() {
 4428                    // If the language registry has been reloaded, then remove and
 4429                    // re-assign the languages on all open buffers.
 4430                    let reload_count = languages.reload_count();
 4431                    if reload_count > prev_reload_count {
 4432                        prev_reload_count = reload_count;
 4433                        this.update(cx, |this, cx| {
 4434                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4435                                for buffer in buffer_store.buffers() {
 4436                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4437                                    {
 4438                                        buffer.update(cx, |buffer, cx| {
 4439                                            buffer.set_language_async(None, cx)
 4440                                        });
 4441                                        if let Some(local) = this.as_local_mut() {
 4442                                            local.reset_buffer(&buffer, &f, cx);
 4443
 4444                                            if local
 4445                                                .registered_buffers
 4446                                                .contains_key(&buffer.read(cx).remote_id())
 4447                                                && let Some(file_url) =
 4448                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4449                                            {
 4450                                                local.unregister_buffer_from_language_servers(
 4451                                                    &buffer, &file_url, cx,
 4452                                                );
 4453                                            }
 4454                                        }
 4455                                    }
 4456                                }
 4457                            });
 4458                        })
 4459                        .ok();
 4460                    }
 4461
 4462                    this.update(cx, |this, cx| {
 4463                        let mut plain_text_buffers = Vec::new();
 4464                        let mut buffers_with_unknown_injections = Vec::new();
 4465                        for handle in this.buffer_store.read(cx).buffers() {
 4466                            let buffer = handle.read(cx);
 4467                            if buffer.language().is_none()
 4468                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4469                            {
 4470                                plain_text_buffers.push(handle);
 4471                            } else if buffer.contains_unknown_injections() {
 4472                                buffers_with_unknown_injections.push(handle);
 4473                            }
 4474                        }
 4475
 4476                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4477                        // and reused later in the invisible worktrees.
 4478                        plain_text_buffers.sort_by_key(|buffer| {
 4479                            Reverse(
 4480                                File::from_dyn(buffer.read(cx).file())
 4481                                    .map(|file| file.worktree.read(cx).is_visible()),
 4482                            )
 4483                        });
 4484
 4485                        for buffer in plain_text_buffers {
 4486                            this.detect_language_for_buffer(&buffer, cx);
 4487                            if let Some(local) = this.as_local_mut() {
 4488                                local.initialize_buffer(&buffer, cx);
 4489                                if local
 4490                                    .registered_buffers
 4491                                    .contains_key(&buffer.read(cx).remote_id())
 4492                                {
 4493                                    local.register_buffer_with_language_servers(
 4494                                        &buffer,
 4495                                        HashSet::default(),
 4496                                        cx,
 4497                                    );
 4498                                }
 4499                            }
 4500                        }
 4501
 4502                        for buffer in buffers_with_unknown_injections {
 4503                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4504                        }
 4505                    })
 4506                    .ok();
 4507                }
 4508            }
 4509        })
 4510    }
 4511
 4512    fn detect_language_for_buffer(
 4513        &mut self,
 4514        buffer_handle: &Entity<Buffer>,
 4515        cx: &mut Context<Self>,
 4516    ) -> Option<language::AvailableLanguage> {
 4517        // If the buffer has a language, set it and start the language server if we haven't already.
 4518        let buffer = buffer_handle.read(cx);
 4519        let file = buffer.file()?;
 4520
 4521        let content = buffer.as_rope();
 4522        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4523        if let Some(available_language) = &available_language {
 4524            if let Some(Ok(Ok(new_language))) = self
 4525                .languages
 4526                .load_language(available_language)
 4527                .now_or_never()
 4528            {
 4529                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4530            }
 4531        } else {
 4532            cx.emit(LspStoreEvent::LanguageDetected {
 4533                buffer: buffer_handle.clone(),
 4534                new_language: None,
 4535            });
 4536        }
 4537
 4538        available_language
 4539    }
 4540
 4541    pub(crate) fn set_language_for_buffer(
 4542        &mut self,
 4543        buffer_entity: &Entity<Buffer>,
 4544        new_language: Arc<Language>,
 4545        cx: &mut Context<Self>,
 4546    ) {
 4547        let buffer = buffer_entity.read(cx);
 4548        let buffer_file = buffer.file().cloned();
 4549        let buffer_id = buffer.remote_id();
 4550        if let Some(local_store) = self.as_local_mut()
 4551            && local_store.registered_buffers.contains_key(&buffer_id)
 4552            && let Some(abs_path) =
 4553                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4554            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4555        {
 4556            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4557        }
 4558        buffer_entity.update(cx, |buffer, cx| {
 4559            if buffer
 4560                .language()
 4561                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4562            {
 4563                buffer.set_language_async(Some(new_language.clone()), cx);
 4564            }
 4565        });
 4566
 4567        let settings =
 4568            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4569        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4570
 4571        let worktree_id = if let Some(file) = buffer_file {
 4572            let worktree = file.worktree.clone();
 4573
 4574            if let Some(local) = self.as_local_mut()
 4575                && local.registered_buffers.contains_key(&buffer_id)
 4576            {
 4577                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4578            }
 4579            Some(worktree.read(cx).id())
 4580        } else {
 4581            None
 4582        };
 4583
 4584        if settings.prettier.allowed
 4585            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4586        {
 4587            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4588            if let Some(prettier_store) = prettier_store {
 4589                prettier_store.update(cx, |prettier_store, cx| {
 4590                    prettier_store.install_default_prettier(
 4591                        worktree_id,
 4592                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4593                        cx,
 4594                    )
 4595                })
 4596            }
 4597        }
 4598
 4599        cx.emit(LspStoreEvent::LanguageDetected {
 4600            buffer: buffer_entity.clone(),
 4601            new_language: Some(new_language),
 4602        })
 4603    }
 4604
 4605    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4606        self.buffer_store.clone()
 4607    }
 4608
 4609    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4610        self.active_entry = active_entry;
 4611    }
 4612
 4613    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4614        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4615            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4616        {
 4617            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4618                summaries
 4619                    .iter()
 4620                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4621            });
 4622            if let Some(summary) = summaries.next() {
 4623                client
 4624                    .send(proto::UpdateDiagnosticSummary {
 4625                        project_id: downstream_project_id,
 4626                        worktree_id: worktree.id().to_proto(),
 4627                        summary: Some(summary),
 4628                        more_summaries: summaries.collect(),
 4629                    })
 4630                    .log_err();
 4631            }
 4632        }
 4633    }
 4634
 4635    fn is_capable_for_proto_request<R>(
 4636        &self,
 4637        buffer: &Entity<Buffer>,
 4638        request: &R,
 4639        cx: &App,
 4640    ) -> bool
 4641    where
 4642        R: LspCommand,
 4643    {
 4644        self.check_if_capable_for_proto_request(
 4645            buffer,
 4646            |capabilities| {
 4647                request.check_capabilities(AdapterServerCapabilities {
 4648                    server_capabilities: capabilities.clone(),
 4649                    code_action_kinds: None,
 4650                })
 4651            },
 4652            cx,
 4653        )
 4654    }
 4655
 4656    fn check_if_capable_for_proto_request<F>(
 4657        &self,
 4658        buffer: &Entity<Buffer>,
 4659        check: F,
 4660        cx: &App,
 4661    ) -> bool
 4662    where
 4663        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4664    {
 4665        let Some(language) = buffer.read(cx).language().cloned() else {
 4666            return false;
 4667        };
 4668        let relevant_language_servers = self
 4669            .languages
 4670            .lsp_adapters(&language.name())
 4671            .into_iter()
 4672            .map(|lsp_adapter| lsp_adapter.name())
 4673            .collect::<HashSet<_>>();
 4674        self.language_server_statuses
 4675            .iter()
 4676            .filter_map(|(server_id, server_status)| {
 4677                relevant_language_servers
 4678                    .contains(&server_status.name)
 4679                    .then_some(server_id)
 4680            })
 4681            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4682            .any(check)
 4683    }
 4684
 4685    fn all_capable_for_proto_request<F>(
 4686        &self,
 4687        buffer: &Entity<Buffer>,
 4688        mut check: F,
 4689        cx: &App,
 4690    ) -> Vec<lsp::LanguageServerId>
 4691    where
 4692        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4693    {
 4694        let Some(language) = buffer.read(cx).language().cloned() else {
 4695            return Vec::default();
 4696        };
 4697        let relevant_language_servers = self
 4698            .languages
 4699            .lsp_adapters(&language.name())
 4700            .into_iter()
 4701            .map(|lsp_adapter| lsp_adapter.name())
 4702            .collect::<HashSet<_>>();
 4703        self.language_server_statuses
 4704            .iter()
 4705            .filter_map(|(server_id, server_status)| {
 4706                relevant_language_servers
 4707                    .contains(&server_status.name)
 4708                    .then_some((server_id, &server_status.name))
 4709            })
 4710            .filter_map(|(server_id, server_name)| {
 4711                self.lsp_server_capabilities
 4712                    .get(server_id)
 4713                    .map(|c| (server_id, server_name, c))
 4714            })
 4715            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4716            .map(|(server_id, _, _)| *server_id)
 4717            .collect()
 4718    }
 4719
 4720    pub fn request_lsp<R>(
 4721        &mut self,
 4722        buffer: Entity<Buffer>,
 4723        server: LanguageServerToQuery,
 4724        request: R,
 4725        cx: &mut Context<Self>,
 4726    ) -> Task<Result<R::Response>>
 4727    where
 4728        R: LspCommand,
 4729        <R::LspRequest as lsp::request::Request>::Result: Send,
 4730        <R::LspRequest as lsp::request::Request>::Params: Send,
 4731    {
 4732        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4733            return self.send_lsp_proto_request(
 4734                buffer,
 4735                upstream_client,
 4736                upstream_project_id,
 4737                request,
 4738                cx,
 4739            );
 4740        }
 4741
 4742        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4743            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4744                local
 4745                    .language_servers_for_buffer(buffer, cx)
 4746                    .find(|(_, server)| {
 4747                        request.check_capabilities(server.adapter_server_capabilities())
 4748                    })
 4749                    .map(|(_, server)| server.clone())
 4750            }),
 4751            LanguageServerToQuery::Other(id) => self
 4752                .language_server_for_local_buffer(buffer, id, cx)
 4753                .and_then(|(_, server)| {
 4754                    request
 4755                        .check_capabilities(server.adapter_server_capabilities())
 4756                        .then(|| Arc::clone(server))
 4757                }),
 4758        }) else {
 4759            return Task::ready(Ok(Default::default()));
 4760        };
 4761
 4762        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4763
 4764        let Some(file) = file else {
 4765            return Task::ready(Ok(Default::default()));
 4766        };
 4767
 4768        let lsp_params = match request.to_lsp_params_or_response(
 4769            &file.abs_path(cx),
 4770            buffer.read(cx),
 4771            &language_server,
 4772            cx,
 4773        ) {
 4774            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4775            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4776            Err(err) => {
 4777                let message = format!(
 4778                    "{} via {} failed: {}",
 4779                    request.display_name(),
 4780                    language_server.name(),
 4781                    err
 4782                );
 4783                // rust-analyzer likes to error with this when its still loading up
 4784                if !message.ends_with("content modified") {
 4785                    log::warn!("{message}");
 4786                }
 4787                return Task::ready(Err(anyhow!(message)));
 4788            }
 4789        };
 4790
 4791        let status = request.status();
 4792        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4793            return Task::ready(Ok(Default::default()));
 4794        }
 4795        cx.spawn(async move |this, cx| {
 4796            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4797
 4798            let id = lsp_request.id();
 4799            let _cleanup = if status.is_some() {
 4800                cx.update(|cx| {
 4801                    this.update(cx, |this, cx| {
 4802                        this.on_lsp_work_start(
 4803                            language_server.server_id(),
 4804                            ProgressToken::Number(id),
 4805                            LanguageServerProgress {
 4806                                is_disk_based_diagnostics_progress: false,
 4807                                is_cancellable: false,
 4808                                title: None,
 4809                                message: status.clone(),
 4810                                percentage: None,
 4811                                last_update_at: cx.background_executor().now(),
 4812                            },
 4813                            cx,
 4814                        );
 4815                    })
 4816                })
 4817                .log_err();
 4818
 4819                Some(defer(|| {
 4820                    cx.update(|cx| {
 4821                        this.update(cx, |this, cx| {
 4822                            this.on_lsp_work_end(
 4823                                language_server.server_id(),
 4824                                ProgressToken::Number(id),
 4825                                cx,
 4826                            );
 4827                        })
 4828                    })
 4829                    .log_err();
 4830                }))
 4831            } else {
 4832                None
 4833            };
 4834
 4835            let result = lsp_request.await.into_response();
 4836
 4837            let response = result.map_err(|err| {
 4838                let message = format!(
 4839                    "{} via {} failed: {}",
 4840                    request.display_name(),
 4841                    language_server.name(),
 4842                    err
 4843                );
 4844                // rust-analyzer likes to error with this when its still loading up
 4845                if !message.ends_with("content modified") {
 4846                    log::warn!("{message}");
 4847                }
 4848                anyhow::anyhow!(message)
 4849            })?;
 4850
 4851            request
 4852                .response_from_lsp(
 4853                    response,
 4854                    this.upgrade().context("no app context")?,
 4855                    buffer,
 4856                    language_server.server_id(),
 4857                    cx.clone(),
 4858                )
 4859                .await
 4860        })
 4861    }
 4862
 4863    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4864        let mut language_formatters_to_check = Vec::new();
 4865        for buffer in self.buffer_store.read(cx).buffers() {
 4866            let buffer = buffer.read(cx);
 4867            let buffer_file = File::from_dyn(buffer.file());
 4868            let buffer_language = buffer.language();
 4869            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4870            if buffer_language.is_some() {
 4871                language_formatters_to_check.push((
 4872                    buffer_file.map(|f| f.worktree_id(cx)),
 4873                    settings.into_owned(),
 4874                ));
 4875            }
 4876        }
 4877
 4878        self.request_workspace_config_refresh();
 4879
 4880        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4881            prettier_store.update(cx, |prettier_store, cx| {
 4882                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4883            })
 4884        }
 4885
 4886        cx.notify();
 4887    }
 4888
 4889    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4890        let buffer_store = self.buffer_store.clone();
 4891        let Some(local) = self.as_local_mut() else {
 4892            return;
 4893        };
 4894        let mut adapters = BTreeMap::default();
 4895        let get_adapter = {
 4896            let languages = local.languages.clone();
 4897            let environment = local.environment.clone();
 4898            let weak = local.weak.clone();
 4899            let worktree_store = local.worktree_store.clone();
 4900            let http_client = local.http_client.clone();
 4901            let fs = local.fs.clone();
 4902            move |worktree_id, cx: &mut App| {
 4903                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4904                Some(LocalLspAdapterDelegate::new(
 4905                    languages.clone(),
 4906                    &environment,
 4907                    weak.clone(),
 4908                    &worktree,
 4909                    http_client.clone(),
 4910                    fs.clone(),
 4911                    cx,
 4912                ))
 4913            }
 4914        };
 4915
 4916        let mut messages_to_report = Vec::new();
 4917        let (new_tree, to_stop) = {
 4918            let mut rebase = local.lsp_tree.rebase();
 4919            let buffers = buffer_store
 4920                .read(cx)
 4921                .buffers()
 4922                .filter_map(|buffer| {
 4923                    let raw_buffer = buffer.read(cx);
 4924                    if !local
 4925                        .registered_buffers
 4926                        .contains_key(&raw_buffer.remote_id())
 4927                    {
 4928                        return None;
 4929                    }
 4930                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4931                    let language = raw_buffer.language().cloned()?;
 4932                    Some((file, language, raw_buffer.remote_id()))
 4933                })
 4934                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4935            for (file, language, buffer_id) in buffers {
 4936                let worktree_id = file.worktree_id(cx);
 4937                let Some(worktree) = local
 4938                    .worktree_store
 4939                    .read(cx)
 4940                    .worktree_for_id(worktree_id, cx)
 4941                else {
 4942                    continue;
 4943                };
 4944
 4945                if let Some((_, apply)) = local.reuse_existing_language_server(
 4946                    rebase.server_tree(),
 4947                    &worktree,
 4948                    &language.name(),
 4949                    cx,
 4950                ) {
 4951                    (apply)(rebase.server_tree());
 4952                } else if let Some(lsp_delegate) = adapters
 4953                    .entry(worktree_id)
 4954                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4955                    .clone()
 4956                {
 4957                    let delegate =
 4958                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4959                    let path = file
 4960                        .path()
 4961                        .parent()
 4962                        .map(Arc::from)
 4963                        .unwrap_or_else(|| file.path().clone());
 4964                    let worktree_path = ProjectPath { worktree_id, path };
 4965                    let abs_path = file.abs_path(cx);
 4966                    let nodes = rebase
 4967                        .walk(
 4968                            worktree_path,
 4969                            language.name(),
 4970                            language.manifest(),
 4971                            delegate.clone(),
 4972                            cx,
 4973                        )
 4974                        .collect::<Vec<_>>();
 4975                    for node in nodes {
 4976                        let server_id = node.server_id_or_init(|disposition| {
 4977                            let path = &disposition.path;
 4978                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4979                            let key = LanguageServerSeed {
 4980                                worktree_id,
 4981                                name: disposition.server_name.clone(),
 4982                                settings: disposition.settings.clone(),
 4983                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4984                                    path.worktree_id,
 4985                                    &path.path,
 4986                                    language.name(),
 4987                                ),
 4988                            };
 4989                            local.language_server_ids.remove(&key);
 4990
 4991                            let server_id = local.get_or_insert_language_server(
 4992                                &worktree,
 4993                                lsp_delegate.clone(),
 4994                                disposition,
 4995                                &language.name(),
 4996                                cx,
 4997                            );
 4998                            if let Some(state) = local.language_servers.get(&server_id)
 4999                                && let Ok(uri) = uri
 5000                            {
 5001                                state.add_workspace_folder(uri);
 5002                            };
 5003                            server_id
 5004                        });
 5005
 5006                        if let Some(language_server_id) = server_id {
 5007                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5008                                language_server_id,
 5009                                name: node.name(),
 5010                                message:
 5011                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5012                                        proto::RegisteredForBuffer {
 5013                                            buffer_abs_path: abs_path
 5014                                                .to_string_lossy()
 5015                                                .into_owned(),
 5016                                            buffer_id: buffer_id.to_proto(),
 5017                                        },
 5018                                    ),
 5019                            });
 5020                        }
 5021                    }
 5022                } else {
 5023                    continue;
 5024                }
 5025            }
 5026            rebase.finish()
 5027        };
 5028        for message in messages_to_report {
 5029            cx.emit(message);
 5030        }
 5031        local.lsp_tree = new_tree;
 5032        for (id, _) in to_stop {
 5033            self.stop_local_language_server(id, cx).detach();
 5034        }
 5035    }
 5036
 5037    pub fn apply_code_action(
 5038        &self,
 5039        buffer_handle: Entity<Buffer>,
 5040        mut action: CodeAction,
 5041        push_to_history: bool,
 5042        cx: &mut Context<Self>,
 5043    ) -> Task<Result<ProjectTransaction>> {
 5044        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5045            let request = proto::ApplyCodeAction {
 5046                project_id,
 5047                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5048                action: Some(Self::serialize_code_action(&action)),
 5049            };
 5050            let buffer_store = self.buffer_store();
 5051            cx.spawn(async move |_, cx| {
 5052                let response = upstream_client
 5053                    .request(request)
 5054                    .await?
 5055                    .transaction
 5056                    .context("missing transaction")?;
 5057
 5058                buffer_store
 5059                    .update(cx, |buffer_store, cx| {
 5060                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5061                    })?
 5062                    .await
 5063            })
 5064        } else if self.mode.is_local() {
 5065            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5066                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5067                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5068            }) else {
 5069                return Task::ready(Ok(ProjectTransaction::default()));
 5070            };
 5071            cx.spawn(async move |this,  cx| {
 5072                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5073                    .await
 5074                    .context("resolving a code action")?;
 5075                if let Some(edit) = action.lsp_action.edit()
 5076                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5077                        return LocalLspStore::deserialize_workspace_edit(
 5078                            this.upgrade().context("no app present")?,
 5079                            edit.clone(),
 5080                            push_to_history,
 5081
 5082                            lang_server.clone(),
 5083                            cx,
 5084                        )
 5085                        .await;
 5086                    }
 5087
 5088                if let Some(command) = action.lsp_action.command() {
 5089                    let server_capabilities = lang_server.capabilities();
 5090                    let available_commands = server_capabilities
 5091                        .execute_command_provider
 5092                        .as_ref()
 5093                        .map(|options| options.commands.as_slice())
 5094                        .unwrap_or_default();
 5095                    if available_commands.contains(&command.command) {
 5096                        this.update(cx, |this, _| {
 5097                            this.as_local_mut()
 5098                                .unwrap()
 5099                                .last_workspace_edits_by_language_server
 5100                                .remove(&lang_server.server_id());
 5101                        })?;
 5102
 5103                        let _result = lang_server
 5104                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5105                                command: command.command.clone(),
 5106                                arguments: command.arguments.clone().unwrap_or_default(),
 5107                                ..lsp::ExecuteCommandParams::default()
 5108                            })
 5109                            .await.into_response()
 5110                            .context("execute command")?;
 5111
 5112                        return this.update(cx, |this, _| {
 5113                            this.as_local_mut()
 5114                                .unwrap()
 5115                                .last_workspace_edits_by_language_server
 5116                                .remove(&lang_server.server_id())
 5117                                .unwrap_or_default()
 5118                        });
 5119                    } else {
 5120                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5121                    }
 5122                }
 5123
 5124                Ok(ProjectTransaction::default())
 5125            })
 5126        } else {
 5127            Task::ready(Err(anyhow!("no upstream client and not local")))
 5128        }
 5129    }
 5130
 5131    pub fn apply_code_action_kind(
 5132        &mut self,
 5133        buffers: HashSet<Entity<Buffer>>,
 5134        kind: CodeActionKind,
 5135        push_to_history: bool,
 5136        cx: &mut Context<Self>,
 5137    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5138        if self.as_local().is_some() {
 5139            cx.spawn(async move |lsp_store, cx| {
 5140                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5141                let result = LocalLspStore::execute_code_action_kind_locally(
 5142                    lsp_store.clone(),
 5143                    buffers,
 5144                    kind,
 5145                    push_to_history,
 5146                    cx,
 5147                )
 5148                .await;
 5149                lsp_store.update(cx, |lsp_store, _| {
 5150                    lsp_store.update_last_formatting_failure(&result);
 5151                })?;
 5152                result
 5153            })
 5154        } else if let Some((client, project_id)) = self.upstream_client() {
 5155            let buffer_store = self.buffer_store();
 5156            cx.spawn(async move |lsp_store, cx| {
 5157                let result = client
 5158                    .request(proto::ApplyCodeActionKind {
 5159                        project_id,
 5160                        kind: kind.as_str().to_owned(),
 5161                        buffer_ids: buffers
 5162                            .iter()
 5163                            .map(|buffer| {
 5164                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5165                            })
 5166                            .collect::<Result<_>>()?,
 5167                    })
 5168                    .await
 5169                    .and_then(|result| result.transaction.context("missing transaction"));
 5170                lsp_store.update(cx, |lsp_store, _| {
 5171                    lsp_store.update_last_formatting_failure(&result);
 5172                })?;
 5173
 5174                let transaction_response = result?;
 5175                buffer_store
 5176                    .update(cx, |buffer_store, cx| {
 5177                        buffer_store.deserialize_project_transaction(
 5178                            transaction_response,
 5179                            push_to_history,
 5180                            cx,
 5181                        )
 5182                    })?
 5183                    .await
 5184            })
 5185        } else {
 5186            Task::ready(Ok(ProjectTransaction::default()))
 5187        }
 5188    }
 5189
 5190    pub fn resolved_hint(
 5191        &mut self,
 5192        buffer_id: BufferId,
 5193        id: InlayId,
 5194        cx: &mut Context<Self>,
 5195    ) -> Option<ResolvedHint> {
 5196        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5197
 5198        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5199        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5200        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5201        let (server_id, resolve_data) = match &hint.resolve_state {
 5202            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5203            ResolveState::Resolving => {
 5204                return Some(ResolvedHint::Resolving(
 5205                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5206                ));
 5207            }
 5208            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5209        };
 5210
 5211        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5212        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5213        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5214            id,
 5215            cx.spawn(async move |lsp_store, cx| {
 5216                let resolved_hint = resolve_task.await;
 5217                lsp_store
 5218                    .update(cx, |lsp_store, _| {
 5219                        if let Some(old_inlay_hint) = lsp_store
 5220                            .lsp_data
 5221                            .get_mut(&buffer_id)
 5222                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5223                        {
 5224                            match resolved_hint {
 5225                                Ok(resolved_hint) => {
 5226                                    *old_inlay_hint = resolved_hint;
 5227                                }
 5228                                Err(e) => {
 5229                                    old_inlay_hint.resolve_state =
 5230                                        ResolveState::CanResolve(server_id, resolve_data);
 5231                                    log::error!("Inlay hint resolve failed: {e:#}");
 5232                                }
 5233                            }
 5234                        }
 5235                    })
 5236                    .ok();
 5237            })
 5238            .shared(),
 5239        );
 5240        debug_assert!(
 5241            previous_task.is_none(),
 5242            "Did not change hint's resolve state after spawning its resolve"
 5243        );
 5244        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5245        None
 5246    }
 5247
 5248    fn resolve_inlay_hint(
 5249        &self,
 5250        mut hint: InlayHint,
 5251        buffer: Entity<Buffer>,
 5252        server_id: LanguageServerId,
 5253        cx: &mut Context<Self>,
 5254    ) -> Task<anyhow::Result<InlayHint>> {
 5255        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5256            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5257            {
 5258                hint.resolve_state = ResolveState::Resolved;
 5259                return Task::ready(Ok(hint));
 5260            }
 5261            let request = proto::ResolveInlayHint {
 5262                project_id,
 5263                buffer_id: buffer.read(cx).remote_id().into(),
 5264                language_server_id: server_id.0 as u64,
 5265                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5266            };
 5267            cx.background_spawn(async move {
 5268                let response = upstream_client
 5269                    .request(request)
 5270                    .await
 5271                    .context("inlay hints proto request")?;
 5272                match response.hint {
 5273                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5274                        .context("inlay hints proto resolve response conversion"),
 5275                    None => Ok(hint),
 5276                }
 5277            })
 5278        } else {
 5279            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5280                self.language_server_for_local_buffer(buffer, server_id, cx)
 5281                    .map(|(_, server)| server.clone())
 5282            }) else {
 5283                return Task::ready(Ok(hint));
 5284            };
 5285            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5286                return Task::ready(Ok(hint));
 5287            }
 5288            let buffer_snapshot = buffer.read(cx).snapshot();
 5289            cx.spawn(async move |_, cx| {
 5290                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5291                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5292                );
 5293                let resolved_hint = resolve_task
 5294                    .await
 5295                    .into_response()
 5296                    .context("inlay hint resolve LSP request")?;
 5297                let resolved_hint = InlayHints::lsp_to_project_hint(
 5298                    resolved_hint,
 5299                    &buffer,
 5300                    server_id,
 5301                    ResolveState::Resolved,
 5302                    false,
 5303                    cx,
 5304                )
 5305                .await?;
 5306                Ok(resolved_hint)
 5307            })
 5308        }
 5309    }
 5310
 5311    pub fn resolve_color_presentation(
 5312        &mut self,
 5313        mut color: DocumentColor,
 5314        buffer: Entity<Buffer>,
 5315        server_id: LanguageServerId,
 5316        cx: &mut Context<Self>,
 5317    ) -> Task<Result<DocumentColor>> {
 5318        if color.resolved {
 5319            return Task::ready(Ok(color));
 5320        }
 5321
 5322        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5323            let start = color.lsp_range.start;
 5324            let end = color.lsp_range.end;
 5325            let request = proto::GetColorPresentation {
 5326                project_id,
 5327                server_id: server_id.to_proto(),
 5328                buffer_id: buffer.read(cx).remote_id().into(),
 5329                color: Some(proto::ColorInformation {
 5330                    red: color.color.red,
 5331                    green: color.color.green,
 5332                    blue: color.color.blue,
 5333                    alpha: color.color.alpha,
 5334                    lsp_range_start: Some(proto::PointUtf16 {
 5335                        row: start.line,
 5336                        column: start.character,
 5337                    }),
 5338                    lsp_range_end: Some(proto::PointUtf16 {
 5339                        row: end.line,
 5340                        column: end.character,
 5341                    }),
 5342                }),
 5343            };
 5344            cx.background_spawn(async move {
 5345                let response = upstream_client
 5346                    .request(request)
 5347                    .await
 5348                    .context("color presentation proto request")?;
 5349                color.resolved = true;
 5350                color.color_presentations = response
 5351                    .presentations
 5352                    .into_iter()
 5353                    .map(|presentation| ColorPresentation {
 5354                        label: SharedString::from(presentation.label),
 5355                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5356                        additional_text_edits: presentation
 5357                            .additional_text_edits
 5358                            .into_iter()
 5359                            .filter_map(deserialize_lsp_edit)
 5360                            .collect(),
 5361                    })
 5362                    .collect();
 5363                Ok(color)
 5364            })
 5365        } else {
 5366            let path = match buffer
 5367                .update(cx, |buffer, cx| {
 5368                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5369                })
 5370                .context("buffer with the missing path")
 5371            {
 5372                Ok(path) => path,
 5373                Err(e) => return Task::ready(Err(e)),
 5374            };
 5375            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5376                self.language_server_for_local_buffer(buffer, server_id, cx)
 5377                    .map(|(_, server)| server.clone())
 5378            }) else {
 5379                return Task::ready(Ok(color));
 5380            };
 5381            cx.background_spawn(async move {
 5382                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5383                    lsp::ColorPresentationParams {
 5384                        text_document: make_text_document_identifier(&path)?,
 5385                        color: color.color,
 5386                        range: color.lsp_range,
 5387                        work_done_progress_params: Default::default(),
 5388                        partial_result_params: Default::default(),
 5389                    },
 5390                );
 5391                color.color_presentations = resolve_task
 5392                    .await
 5393                    .into_response()
 5394                    .context("color presentation resolve LSP request")?
 5395                    .into_iter()
 5396                    .map(|presentation| ColorPresentation {
 5397                        label: SharedString::from(presentation.label),
 5398                        text_edit: presentation.text_edit,
 5399                        additional_text_edits: presentation
 5400                            .additional_text_edits
 5401                            .unwrap_or_default(),
 5402                    })
 5403                    .collect();
 5404                color.resolved = true;
 5405                Ok(color)
 5406            })
 5407        }
 5408    }
 5409
 5410    pub(crate) fn linked_edits(
 5411        &mut self,
 5412        buffer: &Entity<Buffer>,
 5413        position: Anchor,
 5414        cx: &mut Context<Self>,
 5415    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5416        let snapshot = buffer.read(cx).snapshot();
 5417        let scope = snapshot.language_scope_at(position);
 5418        let Some(server_id) = self
 5419            .as_local()
 5420            .and_then(|local| {
 5421                buffer.update(cx, |buffer, cx| {
 5422                    local
 5423                        .language_servers_for_buffer(buffer, cx)
 5424                        .filter(|(_, server)| {
 5425                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5426                        })
 5427                        .filter(|(adapter, _)| {
 5428                            scope
 5429                                .as_ref()
 5430                                .map(|scope| scope.language_allowed(&adapter.name))
 5431                                .unwrap_or(true)
 5432                        })
 5433                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5434                        .next()
 5435                })
 5436            })
 5437            .or_else(|| {
 5438                self.upstream_client()
 5439                    .is_some()
 5440                    .then_some(LanguageServerToQuery::FirstCapable)
 5441            })
 5442            .filter(|_| {
 5443                maybe!({
 5444                    let language = buffer.read(cx).language_at(position)?;
 5445                    Some(
 5446                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5447                            .linked_edits,
 5448                    )
 5449                }) == Some(true)
 5450            })
 5451        else {
 5452            return Task::ready(Ok(Vec::new()));
 5453        };
 5454
 5455        self.request_lsp(
 5456            buffer.clone(),
 5457            server_id,
 5458            LinkedEditingRange { position },
 5459            cx,
 5460        )
 5461    }
 5462
 5463    fn apply_on_type_formatting(
 5464        &mut self,
 5465        buffer: Entity<Buffer>,
 5466        position: Anchor,
 5467        trigger: String,
 5468        cx: &mut Context<Self>,
 5469    ) -> Task<Result<Option<Transaction>>> {
 5470        if let Some((client, project_id)) = self.upstream_client() {
 5471            if !self.check_if_capable_for_proto_request(
 5472                &buffer,
 5473                |capabilities| {
 5474                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5475                },
 5476                cx,
 5477            ) {
 5478                return Task::ready(Ok(None));
 5479            }
 5480            let request = proto::OnTypeFormatting {
 5481                project_id,
 5482                buffer_id: buffer.read(cx).remote_id().into(),
 5483                position: Some(serialize_anchor(&position)),
 5484                trigger,
 5485                version: serialize_version(&buffer.read(cx).version()),
 5486            };
 5487            cx.background_spawn(async move {
 5488                client
 5489                    .request(request)
 5490                    .await?
 5491                    .transaction
 5492                    .map(language::proto::deserialize_transaction)
 5493                    .transpose()
 5494            })
 5495        } else if let Some(local) = self.as_local_mut() {
 5496            let buffer_id = buffer.read(cx).remote_id();
 5497            local.buffers_being_formatted.insert(buffer_id);
 5498            cx.spawn(async move |this, cx| {
 5499                let _cleanup = defer({
 5500                    let this = this.clone();
 5501                    let mut cx = cx.clone();
 5502                    move || {
 5503                        this.update(&mut cx, |this, _| {
 5504                            if let Some(local) = this.as_local_mut() {
 5505                                local.buffers_being_formatted.remove(&buffer_id);
 5506                            }
 5507                        })
 5508                        .ok();
 5509                    }
 5510                });
 5511
 5512                buffer
 5513                    .update(cx, |buffer, _| {
 5514                        buffer.wait_for_edits(Some(position.timestamp))
 5515                    })?
 5516                    .await?;
 5517                this.update(cx, |this, cx| {
 5518                    let position = position.to_point_utf16(buffer.read(cx));
 5519                    this.on_type_format(buffer, position, trigger, false, cx)
 5520                })?
 5521                .await
 5522            })
 5523        } else {
 5524            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5525        }
 5526    }
 5527
 5528    pub fn on_type_format<T: ToPointUtf16>(
 5529        &mut self,
 5530        buffer: Entity<Buffer>,
 5531        position: T,
 5532        trigger: String,
 5533        push_to_history: bool,
 5534        cx: &mut Context<Self>,
 5535    ) -> Task<Result<Option<Transaction>>> {
 5536        let position = position.to_point_utf16(buffer.read(cx));
 5537        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5538    }
 5539
 5540    fn on_type_format_impl(
 5541        &mut self,
 5542        buffer: Entity<Buffer>,
 5543        position: PointUtf16,
 5544        trigger: String,
 5545        push_to_history: bool,
 5546        cx: &mut Context<Self>,
 5547    ) -> Task<Result<Option<Transaction>>> {
 5548        let options = buffer.update(cx, |buffer, cx| {
 5549            lsp_command::lsp_formatting_options(
 5550                language_settings(
 5551                    buffer.language_at(position).map(|l| l.name()),
 5552                    buffer.file(),
 5553                    cx,
 5554                )
 5555                .as_ref(),
 5556            )
 5557        });
 5558
 5559        cx.spawn(async move |this, cx| {
 5560            if let Some(waiter) =
 5561                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5562            {
 5563                waiter.await?;
 5564            }
 5565            cx.update(|cx| {
 5566                this.update(cx, |this, cx| {
 5567                    this.request_lsp(
 5568                        buffer.clone(),
 5569                        LanguageServerToQuery::FirstCapable,
 5570                        OnTypeFormatting {
 5571                            position,
 5572                            trigger,
 5573                            options,
 5574                            push_to_history,
 5575                        },
 5576                        cx,
 5577                    )
 5578                })
 5579            })??
 5580            .await
 5581        })
 5582    }
 5583
 5584    pub fn definitions(
 5585        &mut self,
 5586        buffer: &Entity<Buffer>,
 5587        position: PointUtf16,
 5588        cx: &mut Context<Self>,
 5589    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5590        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5591            let request = GetDefinitions { position };
 5592            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5593                return Task::ready(Ok(None));
 5594            }
 5595            let request_task = upstream_client.request_lsp(
 5596                project_id,
 5597                None,
 5598                LSP_REQUEST_TIMEOUT,
 5599                cx.background_executor().clone(),
 5600                request.to_proto(project_id, buffer.read(cx)),
 5601            );
 5602            let buffer = buffer.clone();
 5603            cx.spawn(async move |weak_lsp_store, cx| {
 5604                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5605                    return Ok(None);
 5606                };
 5607                let Some(responses) = request_task.await? else {
 5608                    return Ok(None);
 5609                };
 5610                let actions = join_all(responses.payload.into_iter().map(|response| {
 5611                    GetDefinitions { position }.response_from_proto(
 5612                        response.response,
 5613                        lsp_store.clone(),
 5614                        buffer.clone(),
 5615                        cx.clone(),
 5616                    )
 5617                }))
 5618                .await;
 5619
 5620                Ok(Some(
 5621                    actions
 5622                        .into_iter()
 5623                        .collect::<Result<Vec<Vec<_>>>>()?
 5624                        .into_iter()
 5625                        .flatten()
 5626                        .dedup()
 5627                        .collect(),
 5628                ))
 5629            })
 5630        } else {
 5631            let definitions_task = self.request_multiple_lsp_locally(
 5632                buffer,
 5633                Some(position),
 5634                GetDefinitions { position },
 5635                cx,
 5636            );
 5637            cx.background_spawn(async move {
 5638                Ok(Some(
 5639                    definitions_task
 5640                        .await
 5641                        .into_iter()
 5642                        .flat_map(|(_, definitions)| definitions)
 5643                        .dedup()
 5644                        .collect(),
 5645                ))
 5646            })
 5647        }
 5648    }
 5649
 5650    pub fn declarations(
 5651        &mut self,
 5652        buffer: &Entity<Buffer>,
 5653        position: PointUtf16,
 5654        cx: &mut Context<Self>,
 5655    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5656        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5657            let request = GetDeclarations { position };
 5658            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5659                return Task::ready(Ok(None));
 5660            }
 5661            let request_task = upstream_client.request_lsp(
 5662                project_id,
 5663                None,
 5664                LSP_REQUEST_TIMEOUT,
 5665                cx.background_executor().clone(),
 5666                request.to_proto(project_id, buffer.read(cx)),
 5667            );
 5668            let buffer = buffer.clone();
 5669            cx.spawn(async move |weak_lsp_store, cx| {
 5670                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5671                    return Ok(None);
 5672                };
 5673                let Some(responses) = request_task.await? else {
 5674                    return Ok(None);
 5675                };
 5676                let actions = join_all(responses.payload.into_iter().map(|response| {
 5677                    GetDeclarations { position }.response_from_proto(
 5678                        response.response,
 5679                        lsp_store.clone(),
 5680                        buffer.clone(),
 5681                        cx.clone(),
 5682                    )
 5683                }))
 5684                .await;
 5685
 5686                Ok(Some(
 5687                    actions
 5688                        .into_iter()
 5689                        .collect::<Result<Vec<Vec<_>>>>()?
 5690                        .into_iter()
 5691                        .flatten()
 5692                        .dedup()
 5693                        .collect(),
 5694                ))
 5695            })
 5696        } else {
 5697            let declarations_task = self.request_multiple_lsp_locally(
 5698                buffer,
 5699                Some(position),
 5700                GetDeclarations { position },
 5701                cx,
 5702            );
 5703            cx.background_spawn(async move {
 5704                Ok(Some(
 5705                    declarations_task
 5706                        .await
 5707                        .into_iter()
 5708                        .flat_map(|(_, declarations)| declarations)
 5709                        .dedup()
 5710                        .collect(),
 5711                ))
 5712            })
 5713        }
 5714    }
 5715
 5716    pub fn type_definitions(
 5717        &mut self,
 5718        buffer: &Entity<Buffer>,
 5719        position: PointUtf16,
 5720        cx: &mut Context<Self>,
 5721    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5722        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5723            let request = GetTypeDefinitions { position };
 5724            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5725                return Task::ready(Ok(None));
 5726            }
 5727            let request_task = upstream_client.request_lsp(
 5728                project_id,
 5729                None,
 5730                LSP_REQUEST_TIMEOUT,
 5731                cx.background_executor().clone(),
 5732                request.to_proto(project_id, buffer.read(cx)),
 5733            );
 5734            let buffer = buffer.clone();
 5735            cx.spawn(async move |weak_lsp_store, cx| {
 5736                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5737                    return Ok(None);
 5738                };
 5739                let Some(responses) = request_task.await? else {
 5740                    return Ok(None);
 5741                };
 5742                let actions = join_all(responses.payload.into_iter().map(|response| {
 5743                    GetTypeDefinitions { position }.response_from_proto(
 5744                        response.response,
 5745                        lsp_store.clone(),
 5746                        buffer.clone(),
 5747                        cx.clone(),
 5748                    )
 5749                }))
 5750                .await;
 5751
 5752                Ok(Some(
 5753                    actions
 5754                        .into_iter()
 5755                        .collect::<Result<Vec<Vec<_>>>>()?
 5756                        .into_iter()
 5757                        .flatten()
 5758                        .dedup()
 5759                        .collect(),
 5760                ))
 5761            })
 5762        } else {
 5763            let type_definitions_task = self.request_multiple_lsp_locally(
 5764                buffer,
 5765                Some(position),
 5766                GetTypeDefinitions { position },
 5767                cx,
 5768            );
 5769            cx.background_spawn(async move {
 5770                Ok(Some(
 5771                    type_definitions_task
 5772                        .await
 5773                        .into_iter()
 5774                        .flat_map(|(_, type_definitions)| type_definitions)
 5775                        .dedup()
 5776                        .collect(),
 5777                ))
 5778            })
 5779        }
 5780    }
 5781
 5782    pub fn implementations(
 5783        &mut self,
 5784        buffer: &Entity<Buffer>,
 5785        position: PointUtf16,
 5786        cx: &mut Context<Self>,
 5787    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5788        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5789            let request = GetImplementations { position };
 5790            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5791                return Task::ready(Ok(None));
 5792            }
 5793            let request_task = upstream_client.request_lsp(
 5794                project_id,
 5795                None,
 5796                LSP_REQUEST_TIMEOUT,
 5797                cx.background_executor().clone(),
 5798                request.to_proto(project_id, buffer.read(cx)),
 5799            );
 5800            let buffer = buffer.clone();
 5801            cx.spawn(async move |weak_lsp_store, cx| {
 5802                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5803                    return Ok(None);
 5804                };
 5805                let Some(responses) = request_task.await? else {
 5806                    return Ok(None);
 5807                };
 5808                let actions = join_all(responses.payload.into_iter().map(|response| {
 5809                    GetImplementations { position }.response_from_proto(
 5810                        response.response,
 5811                        lsp_store.clone(),
 5812                        buffer.clone(),
 5813                        cx.clone(),
 5814                    )
 5815                }))
 5816                .await;
 5817
 5818                Ok(Some(
 5819                    actions
 5820                        .into_iter()
 5821                        .collect::<Result<Vec<Vec<_>>>>()?
 5822                        .into_iter()
 5823                        .flatten()
 5824                        .dedup()
 5825                        .collect(),
 5826                ))
 5827            })
 5828        } else {
 5829            let implementations_task = self.request_multiple_lsp_locally(
 5830                buffer,
 5831                Some(position),
 5832                GetImplementations { position },
 5833                cx,
 5834            );
 5835            cx.background_spawn(async move {
 5836                Ok(Some(
 5837                    implementations_task
 5838                        .await
 5839                        .into_iter()
 5840                        .flat_map(|(_, implementations)| implementations)
 5841                        .dedup()
 5842                        .collect(),
 5843                ))
 5844            })
 5845        }
 5846    }
 5847
 5848    pub fn references(
 5849        &mut self,
 5850        buffer: &Entity<Buffer>,
 5851        position: PointUtf16,
 5852        cx: &mut Context<Self>,
 5853    ) -> Task<Result<Option<Vec<Location>>>> {
 5854        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5855            let request = GetReferences { position };
 5856            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5857                return Task::ready(Ok(None));
 5858            }
 5859
 5860            let request_task = upstream_client.request_lsp(
 5861                project_id,
 5862                None,
 5863                LSP_REQUEST_TIMEOUT,
 5864                cx.background_executor().clone(),
 5865                request.to_proto(project_id, buffer.read(cx)),
 5866            );
 5867            let buffer = buffer.clone();
 5868            cx.spawn(async move |weak_lsp_store, cx| {
 5869                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5870                    return Ok(None);
 5871                };
 5872                let Some(responses) = request_task.await? else {
 5873                    return Ok(None);
 5874                };
 5875
 5876                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5877                    GetReferences { position }.response_from_proto(
 5878                        lsp_response.response,
 5879                        lsp_store.clone(),
 5880                        buffer.clone(),
 5881                        cx.clone(),
 5882                    )
 5883                }))
 5884                .await
 5885                .into_iter()
 5886                .collect::<Result<Vec<Vec<_>>>>()?
 5887                .into_iter()
 5888                .flatten()
 5889                .dedup()
 5890                .collect();
 5891                Ok(Some(locations))
 5892            })
 5893        } else {
 5894            let references_task = self.request_multiple_lsp_locally(
 5895                buffer,
 5896                Some(position),
 5897                GetReferences { position },
 5898                cx,
 5899            );
 5900            cx.background_spawn(async move {
 5901                Ok(Some(
 5902                    references_task
 5903                        .await
 5904                        .into_iter()
 5905                        .flat_map(|(_, references)| references)
 5906                        .dedup()
 5907                        .collect(),
 5908                ))
 5909            })
 5910        }
 5911    }
 5912
 5913    pub fn code_actions(
 5914        &mut self,
 5915        buffer: &Entity<Buffer>,
 5916        range: Range<Anchor>,
 5917        kinds: Option<Vec<CodeActionKind>>,
 5918        cx: &mut Context<Self>,
 5919    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5920        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5921            let request = GetCodeActions {
 5922                range: range.clone(),
 5923                kinds: kinds.clone(),
 5924            };
 5925            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5926                return Task::ready(Ok(None));
 5927            }
 5928            let request_task = upstream_client.request_lsp(
 5929                project_id,
 5930                None,
 5931                LSP_REQUEST_TIMEOUT,
 5932                cx.background_executor().clone(),
 5933                request.to_proto(project_id, buffer.read(cx)),
 5934            );
 5935            let buffer = buffer.clone();
 5936            cx.spawn(async move |weak_lsp_store, cx| {
 5937                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5938                    return Ok(None);
 5939                };
 5940                let Some(responses) = request_task.await? else {
 5941                    return Ok(None);
 5942                };
 5943                let actions = join_all(responses.payload.into_iter().map(|response| {
 5944                    GetCodeActions {
 5945                        range: range.clone(),
 5946                        kinds: kinds.clone(),
 5947                    }
 5948                    .response_from_proto(
 5949                        response.response,
 5950                        lsp_store.clone(),
 5951                        buffer.clone(),
 5952                        cx.clone(),
 5953                    )
 5954                }))
 5955                .await;
 5956
 5957                Ok(Some(
 5958                    actions
 5959                        .into_iter()
 5960                        .collect::<Result<Vec<Vec<_>>>>()?
 5961                        .into_iter()
 5962                        .flatten()
 5963                        .collect(),
 5964                ))
 5965            })
 5966        } else {
 5967            let all_actions_task = self.request_multiple_lsp_locally(
 5968                buffer,
 5969                Some(range.start),
 5970                GetCodeActions { range, kinds },
 5971                cx,
 5972            );
 5973            cx.background_spawn(async move {
 5974                Ok(Some(
 5975                    all_actions_task
 5976                        .await
 5977                        .into_iter()
 5978                        .flat_map(|(_, actions)| actions)
 5979                        .collect(),
 5980                ))
 5981            })
 5982        }
 5983    }
 5984
 5985    pub fn code_lens_actions(
 5986        &mut self,
 5987        buffer: &Entity<Buffer>,
 5988        cx: &mut Context<Self>,
 5989    ) -> CodeLensTask {
 5990        let version_queried_for = buffer.read(cx).version();
 5991        let buffer_id = buffer.read(cx).remote_id();
 5992        let existing_servers = self.as_local().map(|local| {
 5993            local
 5994                .buffers_opened_in_servers
 5995                .get(&buffer_id)
 5996                .cloned()
 5997                .unwrap_or_default()
 5998        });
 5999
 6000        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6001            if let Some(cached_lens) = &lsp_data.code_lens {
 6002                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6003                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6004                        existing_servers != cached_lens.lens.keys().copied().collect()
 6005                    });
 6006                    if !has_different_servers {
 6007                        return Task::ready(Ok(Some(
 6008                            cached_lens.lens.values().flatten().cloned().collect(),
 6009                        )))
 6010                        .shared();
 6011                    }
 6012                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6013                    if !version_queried_for.changed_since(updating_for) {
 6014                        return running_update.clone();
 6015                    }
 6016                }
 6017            }
 6018        }
 6019
 6020        let lens_lsp_data = self
 6021            .latest_lsp_data(buffer, cx)
 6022            .code_lens
 6023            .get_or_insert_default();
 6024        let buffer = buffer.clone();
 6025        let query_version_queried_for = version_queried_for.clone();
 6026        let new_task = cx
 6027            .spawn(async move |lsp_store, cx| {
 6028                cx.background_executor()
 6029                    .timer(Duration::from_millis(30))
 6030                    .await;
 6031                let fetched_lens = lsp_store
 6032                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6033                    .map_err(Arc::new)?
 6034                    .await
 6035                    .context("fetching code lens")
 6036                    .map_err(Arc::new);
 6037                let fetched_lens = match fetched_lens {
 6038                    Ok(fetched_lens) => fetched_lens,
 6039                    Err(e) => {
 6040                        lsp_store
 6041                            .update(cx, |lsp_store, _| {
 6042                                if let Some(lens_lsp_data) = lsp_store
 6043                                    .lsp_data
 6044                                    .get_mut(&buffer_id)
 6045                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6046                                {
 6047                                    lens_lsp_data.update = None;
 6048                                }
 6049                            })
 6050                            .ok();
 6051                        return Err(e);
 6052                    }
 6053                };
 6054
 6055                lsp_store
 6056                    .update(cx, |lsp_store, _| {
 6057                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6058                        let code_lens = lsp_data.code_lens.as_mut()?;
 6059                        if let Some(fetched_lens) = fetched_lens {
 6060                            if lsp_data.buffer_version == query_version_queried_for {
 6061                                code_lens.lens.extend(fetched_lens);
 6062                            } else if !lsp_data
 6063                                .buffer_version
 6064                                .changed_since(&query_version_queried_for)
 6065                            {
 6066                                lsp_data.buffer_version = query_version_queried_for;
 6067                                code_lens.lens = fetched_lens;
 6068                            }
 6069                        }
 6070                        code_lens.update = None;
 6071                        Some(code_lens.lens.values().flatten().cloned().collect())
 6072                    })
 6073                    .map_err(Arc::new)
 6074            })
 6075            .shared();
 6076        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6077        new_task
 6078    }
 6079
 6080    fn fetch_code_lens(
 6081        &mut self,
 6082        buffer: &Entity<Buffer>,
 6083        cx: &mut Context<Self>,
 6084    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6085        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6086            let request = GetCodeLens;
 6087            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6088                return Task::ready(Ok(None));
 6089            }
 6090            let request_task = upstream_client.request_lsp(
 6091                project_id,
 6092                None,
 6093                LSP_REQUEST_TIMEOUT,
 6094                cx.background_executor().clone(),
 6095                request.to_proto(project_id, buffer.read(cx)),
 6096            );
 6097            let buffer = buffer.clone();
 6098            cx.spawn(async move |weak_lsp_store, cx| {
 6099                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6100                    return Ok(None);
 6101                };
 6102                let Some(responses) = request_task.await? else {
 6103                    return Ok(None);
 6104                };
 6105
 6106                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6107                    let lsp_store = lsp_store.clone();
 6108                    let buffer = buffer.clone();
 6109                    let cx = cx.clone();
 6110                    async move {
 6111                        (
 6112                            LanguageServerId::from_proto(response.server_id),
 6113                            GetCodeLens
 6114                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6115                                .await,
 6116                        )
 6117                    }
 6118                }))
 6119                .await;
 6120
 6121                let mut has_errors = false;
 6122                let code_lens_actions = code_lens_actions
 6123                    .into_iter()
 6124                    .filter_map(|(server_id, code_lens)| match code_lens {
 6125                        Ok(code_lens) => Some((server_id, code_lens)),
 6126                        Err(e) => {
 6127                            has_errors = true;
 6128                            log::error!("{e:#}");
 6129                            None
 6130                        }
 6131                    })
 6132                    .collect::<HashMap<_, _>>();
 6133                anyhow::ensure!(
 6134                    !has_errors || !code_lens_actions.is_empty(),
 6135                    "Failed to fetch code lens"
 6136                );
 6137                Ok(Some(code_lens_actions))
 6138            })
 6139        } else {
 6140            let code_lens_actions_task =
 6141                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6142            cx.background_spawn(async move {
 6143                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6144            })
 6145        }
 6146    }
 6147
 6148    #[inline(never)]
 6149    pub fn completions(
 6150        &self,
 6151        buffer: &Entity<Buffer>,
 6152        position: PointUtf16,
 6153        context: CompletionContext,
 6154        cx: &mut Context<Self>,
 6155    ) -> Task<Result<Vec<CompletionResponse>>> {
 6156        let language_registry = self.languages.clone();
 6157
 6158        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6159            let snapshot = buffer.read(cx).snapshot();
 6160            let offset = position.to_offset(&snapshot);
 6161            let scope = snapshot.language_scope_at(offset);
 6162            let capable_lsps = self.all_capable_for_proto_request(
 6163                buffer,
 6164                |server_name, capabilities| {
 6165                    capabilities.completion_provider.is_some()
 6166                        && scope
 6167                            .as_ref()
 6168                            .map(|scope| scope.language_allowed(server_name))
 6169                            .unwrap_or(true)
 6170                },
 6171                cx,
 6172            );
 6173            if capable_lsps.is_empty() {
 6174                return Task::ready(Ok(Vec::new()));
 6175            }
 6176
 6177            let language = buffer.read(cx).language().cloned();
 6178
 6179            // In the future, we should provide project guests with the names of LSP adapters,
 6180            // so that they can use the correct LSP adapter when computing labels. For now,
 6181            // guests just use the first LSP adapter associated with the buffer's language.
 6182            let lsp_adapter = language.as_ref().and_then(|language| {
 6183                language_registry
 6184                    .lsp_adapters(&language.name())
 6185                    .first()
 6186                    .cloned()
 6187            });
 6188
 6189            let buffer = buffer.clone();
 6190
 6191            cx.spawn(async move |this, cx| {
 6192                let requests = join_all(
 6193                    capable_lsps
 6194                        .into_iter()
 6195                        .map(|id| {
 6196                            let request = GetCompletions {
 6197                                position,
 6198                                context: context.clone(),
 6199                                server_id: Some(id),
 6200                            };
 6201                            let buffer = buffer.clone();
 6202                            let language = language.clone();
 6203                            let lsp_adapter = lsp_adapter.clone();
 6204                            let upstream_client = upstream_client.clone();
 6205                            let response = this
 6206                                .update(cx, |this, cx| {
 6207                                    this.send_lsp_proto_request(
 6208                                        buffer,
 6209                                        upstream_client,
 6210                                        project_id,
 6211                                        request,
 6212                                        cx,
 6213                                    )
 6214                                })
 6215                                .log_err();
 6216                            async move {
 6217                                let response = response?.await.log_err()?;
 6218
 6219                                let completions = populate_labels_for_completions(
 6220                                    response.completions,
 6221                                    language,
 6222                                    lsp_adapter,
 6223                                )
 6224                                .await;
 6225
 6226                                Some(CompletionResponse {
 6227                                    completions,
 6228                                    display_options: CompletionDisplayOptions::default(),
 6229                                    is_incomplete: response.is_incomplete,
 6230                                })
 6231                            }
 6232                        })
 6233                        .collect::<Vec<_>>(),
 6234                );
 6235                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6236            })
 6237        } else if let Some(local) = self.as_local() {
 6238            let snapshot = buffer.read(cx).snapshot();
 6239            let offset = position.to_offset(&snapshot);
 6240            let scope = snapshot.language_scope_at(offset);
 6241            let language = snapshot.language().cloned();
 6242            let completion_settings = language_settings(
 6243                language.as_ref().map(|language| language.name()),
 6244                buffer.read(cx).file(),
 6245                cx,
 6246            )
 6247            .completions
 6248            .clone();
 6249            if !completion_settings.lsp {
 6250                return Task::ready(Ok(Vec::new()));
 6251            }
 6252
 6253            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6254                local
 6255                    .language_servers_for_buffer(buffer, cx)
 6256                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6257                    .filter(|(adapter, _)| {
 6258                        scope
 6259                            .as_ref()
 6260                            .map(|scope| scope.language_allowed(&adapter.name))
 6261                            .unwrap_or(true)
 6262                    })
 6263                    .map(|(_, server)| server.server_id())
 6264                    .collect()
 6265            });
 6266
 6267            let buffer = buffer.clone();
 6268            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6269            let lsp_timeout = if lsp_timeout > 0 {
 6270                Some(Duration::from_millis(lsp_timeout))
 6271            } else {
 6272                None
 6273            };
 6274            cx.spawn(async move |this,  cx| {
 6275                let mut tasks = Vec::with_capacity(server_ids.len());
 6276                this.update(cx, |lsp_store, cx| {
 6277                    for server_id in server_ids {
 6278                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6279                        let lsp_timeout = lsp_timeout
 6280                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6281                        let mut timeout = cx.background_spawn(async move {
 6282                            match lsp_timeout {
 6283                                Some(lsp_timeout) => {
 6284                                    lsp_timeout.await;
 6285                                    true
 6286                                },
 6287                                None => false,
 6288                            }
 6289                        }).fuse();
 6290                        let mut lsp_request = lsp_store.request_lsp(
 6291                            buffer.clone(),
 6292                            LanguageServerToQuery::Other(server_id),
 6293                            GetCompletions {
 6294                                position,
 6295                                context: context.clone(),
 6296                                server_id: Some(server_id),
 6297                            },
 6298                            cx,
 6299                        ).fuse();
 6300                        let new_task = cx.background_spawn(async move {
 6301                            select_biased! {
 6302                                response = lsp_request => anyhow::Ok(Some(response?)),
 6303                                timeout_happened = timeout => {
 6304                                    if timeout_happened {
 6305                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6306                                        Ok(None)
 6307                                    } else {
 6308                                        let completions = lsp_request.await?;
 6309                                        Ok(Some(completions))
 6310                                    }
 6311                                },
 6312                            }
 6313                        });
 6314                        tasks.push((lsp_adapter, new_task));
 6315                    }
 6316                })?;
 6317
 6318                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6319                    let completion_response = task.await.ok()??;
 6320                    let completions = populate_labels_for_completions(
 6321                            completion_response.completions,
 6322                            language.clone(),
 6323                            lsp_adapter,
 6324                        )
 6325                        .await;
 6326                    Some(CompletionResponse {
 6327                        completions,
 6328                        display_options: CompletionDisplayOptions::default(),
 6329                        is_incomplete: completion_response.is_incomplete,
 6330                    })
 6331                });
 6332
 6333                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6334
 6335                Ok(responses.into_iter().flatten().collect())
 6336            })
 6337        } else {
 6338            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6339        }
 6340    }
 6341
 6342    pub fn resolve_completions(
 6343        &self,
 6344        buffer: Entity<Buffer>,
 6345        completion_indices: Vec<usize>,
 6346        completions: Rc<RefCell<Box<[Completion]>>>,
 6347        cx: &mut Context<Self>,
 6348    ) -> Task<Result<bool>> {
 6349        let client = self.upstream_client();
 6350        let buffer_id = buffer.read(cx).remote_id();
 6351        let buffer_snapshot = buffer.read(cx).snapshot();
 6352
 6353        if !self.check_if_capable_for_proto_request(
 6354            &buffer,
 6355            GetCompletions::can_resolve_completions,
 6356            cx,
 6357        ) {
 6358            return Task::ready(Ok(false));
 6359        }
 6360        cx.spawn(async move |lsp_store, cx| {
 6361            let mut did_resolve = false;
 6362            if let Some((client, project_id)) = client {
 6363                for completion_index in completion_indices {
 6364                    let server_id = {
 6365                        let completion = &completions.borrow()[completion_index];
 6366                        completion.source.server_id()
 6367                    };
 6368                    if let Some(server_id) = server_id {
 6369                        if Self::resolve_completion_remote(
 6370                            project_id,
 6371                            server_id,
 6372                            buffer_id,
 6373                            completions.clone(),
 6374                            completion_index,
 6375                            client.clone(),
 6376                        )
 6377                        .await
 6378                        .log_err()
 6379                        .is_some()
 6380                        {
 6381                            did_resolve = true;
 6382                        }
 6383                    } else {
 6384                        resolve_word_completion(
 6385                            &buffer_snapshot,
 6386                            &mut completions.borrow_mut()[completion_index],
 6387                        );
 6388                    }
 6389                }
 6390            } else {
 6391                for completion_index in completion_indices {
 6392                    let server_id = {
 6393                        let completion = &completions.borrow()[completion_index];
 6394                        completion.source.server_id()
 6395                    };
 6396                    if let Some(server_id) = server_id {
 6397                        let server_and_adapter = lsp_store
 6398                            .read_with(cx, |lsp_store, _| {
 6399                                let server = lsp_store.language_server_for_id(server_id)?;
 6400                                let adapter =
 6401                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6402                                Some((server, adapter))
 6403                            })
 6404                            .ok()
 6405                            .flatten();
 6406                        let Some((server, adapter)) = server_and_adapter else {
 6407                            continue;
 6408                        };
 6409
 6410                        let resolved = Self::resolve_completion_local(
 6411                            server,
 6412                            completions.clone(),
 6413                            completion_index,
 6414                        )
 6415                        .await
 6416                        .log_err()
 6417                        .is_some();
 6418                        if resolved {
 6419                            Self::regenerate_completion_labels(
 6420                                adapter,
 6421                                &buffer_snapshot,
 6422                                completions.clone(),
 6423                                completion_index,
 6424                            )
 6425                            .await
 6426                            .log_err();
 6427                            did_resolve = true;
 6428                        }
 6429                    } else {
 6430                        resolve_word_completion(
 6431                            &buffer_snapshot,
 6432                            &mut completions.borrow_mut()[completion_index],
 6433                        );
 6434                    }
 6435                }
 6436            }
 6437
 6438            Ok(did_resolve)
 6439        })
 6440    }
 6441
 6442    async fn resolve_completion_local(
 6443        server: Arc<lsp::LanguageServer>,
 6444        completions: Rc<RefCell<Box<[Completion]>>>,
 6445        completion_index: usize,
 6446    ) -> Result<()> {
 6447        let server_id = server.server_id();
 6448        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6449            return Ok(());
 6450        }
 6451
 6452        let request = {
 6453            let completion = &completions.borrow()[completion_index];
 6454            match &completion.source {
 6455                CompletionSource::Lsp {
 6456                    lsp_completion,
 6457                    resolved,
 6458                    server_id: completion_server_id,
 6459                    ..
 6460                } => {
 6461                    if *resolved {
 6462                        return Ok(());
 6463                    }
 6464                    anyhow::ensure!(
 6465                        server_id == *completion_server_id,
 6466                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6467                    );
 6468                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6469                }
 6470                CompletionSource::BufferWord { .. }
 6471                | CompletionSource::Dap { .. }
 6472                | CompletionSource::Custom => {
 6473                    return Ok(());
 6474                }
 6475            }
 6476        };
 6477        let resolved_completion = request
 6478            .await
 6479            .into_response()
 6480            .context("resolve completion")?;
 6481
 6482        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6483        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6484
 6485        let mut completions = completions.borrow_mut();
 6486        let completion = &mut completions[completion_index];
 6487        if let CompletionSource::Lsp {
 6488            lsp_completion,
 6489            resolved,
 6490            server_id: completion_server_id,
 6491            ..
 6492        } = &mut completion.source
 6493        {
 6494            if *resolved {
 6495                return Ok(());
 6496            }
 6497            anyhow::ensure!(
 6498                server_id == *completion_server_id,
 6499                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6500            );
 6501            **lsp_completion = resolved_completion;
 6502            *resolved = true;
 6503        }
 6504        Ok(())
 6505    }
 6506
 6507    async fn regenerate_completion_labels(
 6508        adapter: Arc<CachedLspAdapter>,
 6509        snapshot: &BufferSnapshot,
 6510        completions: Rc<RefCell<Box<[Completion]>>>,
 6511        completion_index: usize,
 6512    ) -> Result<()> {
 6513        let completion_item = completions.borrow()[completion_index]
 6514            .source
 6515            .lsp_completion(true)
 6516            .map(Cow::into_owned);
 6517        if let Some(lsp_documentation) = completion_item
 6518            .as_ref()
 6519            .and_then(|completion_item| completion_item.documentation.clone())
 6520        {
 6521            let mut completions = completions.borrow_mut();
 6522            let completion = &mut completions[completion_index];
 6523            completion.documentation = Some(lsp_documentation.into());
 6524        } else {
 6525            let mut completions = completions.borrow_mut();
 6526            let completion = &mut completions[completion_index];
 6527            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6528        }
 6529
 6530        let mut new_label = match completion_item {
 6531            Some(completion_item) => {
 6532                // 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
 6533                // So we have to update the label here anyway...
 6534                let language = snapshot.language();
 6535                match language {
 6536                    Some(language) => {
 6537                        adapter
 6538                            .labels_for_completions(
 6539                                std::slice::from_ref(&completion_item),
 6540                                language,
 6541                            )
 6542                            .await?
 6543                    }
 6544                    None => Vec::new(),
 6545                }
 6546                .pop()
 6547                .flatten()
 6548                .unwrap_or_else(|| {
 6549                    CodeLabel::fallback_for_completion(
 6550                        &completion_item,
 6551                        language.map(|language| language.as_ref()),
 6552                    )
 6553                })
 6554            }
 6555            None => CodeLabel::plain(
 6556                completions.borrow()[completion_index].new_text.clone(),
 6557                None,
 6558            ),
 6559        };
 6560        ensure_uniform_list_compatible_label(&mut new_label);
 6561
 6562        let mut completions = completions.borrow_mut();
 6563        let completion = &mut completions[completion_index];
 6564        if completion.label.filter_text() == new_label.filter_text() {
 6565            completion.label = new_label;
 6566        } else {
 6567            log::error!(
 6568                "Resolved completion changed display label from {} to {}. \
 6569                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6570                completion.label.text(),
 6571                new_label.text(),
 6572                completion.label.filter_text(),
 6573                new_label.filter_text()
 6574            );
 6575        }
 6576
 6577        Ok(())
 6578    }
 6579
 6580    async fn resolve_completion_remote(
 6581        project_id: u64,
 6582        server_id: LanguageServerId,
 6583        buffer_id: BufferId,
 6584        completions: Rc<RefCell<Box<[Completion]>>>,
 6585        completion_index: usize,
 6586        client: AnyProtoClient,
 6587    ) -> Result<()> {
 6588        let lsp_completion = {
 6589            let completion = &completions.borrow()[completion_index];
 6590            match &completion.source {
 6591                CompletionSource::Lsp {
 6592                    lsp_completion,
 6593                    resolved,
 6594                    server_id: completion_server_id,
 6595                    ..
 6596                } => {
 6597                    anyhow::ensure!(
 6598                        server_id == *completion_server_id,
 6599                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6600                    );
 6601                    if *resolved {
 6602                        return Ok(());
 6603                    }
 6604                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6605                }
 6606                CompletionSource::Custom
 6607                | CompletionSource::Dap { .. }
 6608                | CompletionSource::BufferWord { .. } => {
 6609                    return Ok(());
 6610                }
 6611            }
 6612        };
 6613        let request = proto::ResolveCompletionDocumentation {
 6614            project_id,
 6615            language_server_id: server_id.0 as u64,
 6616            lsp_completion,
 6617            buffer_id: buffer_id.into(),
 6618        };
 6619
 6620        let response = client
 6621            .request(request)
 6622            .await
 6623            .context("completion documentation resolve proto request")?;
 6624        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6625
 6626        let documentation = if response.documentation.is_empty() {
 6627            CompletionDocumentation::Undocumented
 6628        } else if response.documentation_is_markdown {
 6629            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6630        } else if response.documentation.lines().count() <= 1 {
 6631            CompletionDocumentation::SingleLine(response.documentation.into())
 6632        } else {
 6633            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6634        };
 6635
 6636        let mut completions = completions.borrow_mut();
 6637        let completion = &mut completions[completion_index];
 6638        completion.documentation = Some(documentation);
 6639        if let CompletionSource::Lsp {
 6640            insert_range,
 6641            lsp_completion,
 6642            resolved,
 6643            server_id: completion_server_id,
 6644            lsp_defaults: _,
 6645        } = &mut completion.source
 6646        {
 6647            let completion_insert_range = response
 6648                .old_insert_start
 6649                .and_then(deserialize_anchor)
 6650                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6651            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6652
 6653            if *resolved {
 6654                return Ok(());
 6655            }
 6656            anyhow::ensure!(
 6657                server_id == *completion_server_id,
 6658                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6659            );
 6660            **lsp_completion = resolved_lsp_completion;
 6661            *resolved = true;
 6662        }
 6663
 6664        let replace_range = response
 6665            .old_replace_start
 6666            .and_then(deserialize_anchor)
 6667            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6668        if let Some((old_replace_start, old_replace_end)) = replace_range
 6669            && !response.new_text.is_empty()
 6670        {
 6671            completion.new_text = response.new_text;
 6672            completion.replace_range = old_replace_start..old_replace_end;
 6673        }
 6674
 6675        Ok(())
 6676    }
 6677
 6678    pub fn apply_additional_edits_for_completion(
 6679        &self,
 6680        buffer_handle: Entity<Buffer>,
 6681        completions: Rc<RefCell<Box<[Completion]>>>,
 6682        completion_index: usize,
 6683        push_to_history: bool,
 6684        cx: &mut Context<Self>,
 6685    ) -> Task<Result<Option<Transaction>>> {
 6686        if let Some((client, project_id)) = self.upstream_client() {
 6687            let buffer = buffer_handle.read(cx);
 6688            let buffer_id = buffer.remote_id();
 6689            cx.spawn(async move |_, cx| {
 6690                let request = {
 6691                    let completion = completions.borrow()[completion_index].clone();
 6692                    proto::ApplyCompletionAdditionalEdits {
 6693                        project_id,
 6694                        buffer_id: buffer_id.into(),
 6695                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6696                            replace_range: completion.replace_range,
 6697                            new_text: completion.new_text,
 6698                            source: completion.source,
 6699                        })),
 6700                    }
 6701                };
 6702
 6703                if let Some(transaction) = client.request(request).await?.transaction {
 6704                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6705                    buffer_handle
 6706                        .update(cx, |buffer, _| {
 6707                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6708                        })?
 6709                        .await?;
 6710                    if push_to_history {
 6711                        buffer_handle.update(cx, |buffer, _| {
 6712                            buffer.push_transaction(transaction.clone(), Instant::now());
 6713                            buffer.finalize_last_transaction();
 6714                        })?;
 6715                    }
 6716                    Ok(Some(transaction))
 6717                } else {
 6718                    Ok(None)
 6719                }
 6720            })
 6721        } else {
 6722            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6723                let completion = &completions.borrow()[completion_index];
 6724                let server_id = completion.source.server_id()?;
 6725                Some(
 6726                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6727                        .1
 6728                        .clone(),
 6729                )
 6730            }) else {
 6731                return Task::ready(Ok(None));
 6732            };
 6733
 6734            cx.spawn(async move |this, cx| {
 6735                Self::resolve_completion_local(
 6736                    server.clone(),
 6737                    completions.clone(),
 6738                    completion_index,
 6739                )
 6740                .await
 6741                .context("resolving completion")?;
 6742                let completion = completions.borrow()[completion_index].clone();
 6743                let additional_text_edits = completion
 6744                    .source
 6745                    .lsp_completion(true)
 6746                    .as_ref()
 6747                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6748                if let Some(edits) = additional_text_edits {
 6749                    let edits = this
 6750                        .update(cx, |this, cx| {
 6751                            this.as_local_mut().unwrap().edits_from_lsp(
 6752                                &buffer_handle,
 6753                                edits,
 6754                                server.server_id(),
 6755                                None,
 6756                                cx,
 6757                            )
 6758                        })?
 6759                        .await?;
 6760
 6761                    buffer_handle.update(cx, |buffer, cx| {
 6762                        buffer.finalize_last_transaction();
 6763                        buffer.start_transaction();
 6764
 6765                        for (range, text) in edits {
 6766                            let primary = &completion.replace_range;
 6767
 6768                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6769                            // and the primary completion is just an insertion (empty range), then this is likely
 6770                            // an auto-import scenario and should not be considered overlapping
 6771                            // https://github.com/zed-industries/zed/issues/26136
 6772                            let is_file_start_auto_import = {
 6773                                let snapshot = buffer.snapshot();
 6774                                let primary_start_point = primary.start.to_point(&snapshot);
 6775                                let range_start_point = range.start.to_point(&snapshot);
 6776
 6777                                let result = primary_start_point.row == 0
 6778                                    && primary_start_point.column == 0
 6779                                    && range_start_point.row == 0
 6780                                    && range_start_point.column == 0;
 6781
 6782                                result
 6783                            };
 6784
 6785                            let has_overlap = if is_file_start_auto_import {
 6786                                false
 6787                            } else {
 6788                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6789                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6790                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6791                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6792                                let result = start_within || end_within;
 6793                                result
 6794                            };
 6795
 6796                            //Skip additional edits which overlap with the primary completion edit
 6797                            //https://github.com/zed-industries/zed/pull/1871
 6798                            if !has_overlap {
 6799                                buffer.edit([(range, text)], None, cx);
 6800                            }
 6801                        }
 6802
 6803                        let transaction = if buffer.end_transaction(cx).is_some() {
 6804                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6805                            if !push_to_history {
 6806                                buffer.forget_transaction(transaction.id);
 6807                            }
 6808                            Some(transaction)
 6809                        } else {
 6810                            None
 6811                        };
 6812                        Ok(transaction)
 6813                    })?
 6814                } else {
 6815                    Ok(None)
 6816                }
 6817            })
 6818        }
 6819    }
 6820
 6821    pub fn pull_diagnostics(
 6822        &mut self,
 6823        buffer: Entity<Buffer>,
 6824        cx: &mut Context<Self>,
 6825    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6826        let buffer_id = buffer.read(cx).remote_id();
 6827
 6828        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6829            let mut suitable_capabilities = None;
 6830            // Are we capable for proto request?
 6831            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6832                &buffer,
 6833                |capabilities| {
 6834                    if let Some(caps) = &capabilities.diagnostic_provider {
 6835                        suitable_capabilities = Some(caps.clone());
 6836                        true
 6837                    } else {
 6838                        false
 6839                    }
 6840                },
 6841                cx,
 6842            );
 6843            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6844            let Some(dynamic_caps) = suitable_capabilities else {
 6845                return Task::ready(Ok(None));
 6846            };
 6847            assert!(any_server_has_diagnostics_provider);
 6848
 6849            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6850            let request = GetDocumentDiagnostics {
 6851                previous_result_id: None,
 6852                identifier,
 6853                registration_id: None,
 6854            };
 6855            let request_task = client.request_lsp(
 6856                upstream_project_id,
 6857                None,
 6858                LSP_REQUEST_TIMEOUT,
 6859                cx.background_executor().clone(),
 6860                request.to_proto(upstream_project_id, buffer.read(cx)),
 6861            );
 6862            cx.background_spawn(async move {
 6863                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6864                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6865                // Do not attempt to further process the dummy responses here.
 6866                let _response = request_task.await?;
 6867                Ok(None)
 6868            })
 6869        } else {
 6870            let servers = buffer.update(cx, |buffer, cx| {
 6871                self.running_language_servers_for_local_buffer(buffer, cx)
 6872                    .map(|(_, server)| server.clone())
 6873                    .collect::<Vec<_>>()
 6874            });
 6875
 6876            let pull_diagnostics = servers
 6877                .into_iter()
 6878                .flat_map(|server| {
 6879                    let result = maybe!({
 6880                        let local = self.as_local()?;
 6881                        let server_id = server.server_id();
 6882                        let providers_with_identifiers = local
 6883                            .language_server_dynamic_registrations
 6884                            .get(&server_id)
 6885                            .into_iter()
 6886                            .flat_map(|registrations| registrations.diagnostics.clone())
 6887                            .collect::<Vec<_>>();
 6888                        Some(
 6889                            providers_with_identifiers
 6890                                .into_iter()
 6891                                .map(|(registration_id, dynamic_caps)| {
 6892                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6893                                    let registration_id = registration_id.map(SharedString::from);
 6894                                    let result_id = self.result_id_for_buffer_pull(
 6895                                        server_id,
 6896                                        buffer_id,
 6897                                        &registration_id,
 6898                                        cx,
 6899                                    );
 6900                                    self.request_lsp(
 6901                                        buffer.clone(),
 6902                                        LanguageServerToQuery::Other(server_id),
 6903                                        GetDocumentDiagnostics {
 6904                                            previous_result_id: result_id,
 6905                                            registration_id,
 6906                                            identifier,
 6907                                        },
 6908                                        cx,
 6909                                    )
 6910                                })
 6911                                .collect::<Vec<_>>(),
 6912                        )
 6913                    });
 6914
 6915                    result.unwrap_or_default()
 6916                })
 6917                .collect::<Vec<_>>();
 6918
 6919            cx.background_spawn(async move {
 6920                let mut responses = Vec::new();
 6921                for diagnostics in join_all(pull_diagnostics).await {
 6922                    responses.extend(diagnostics?);
 6923                }
 6924                Ok(Some(responses))
 6925            })
 6926        }
 6927    }
 6928
 6929    pub fn applicable_inlay_chunks(
 6930        &mut self,
 6931        buffer: &Entity<Buffer>,
 6932        ranges: &[Range<text::Anchor>],
 6933        cx: &mut Context<Self>,
 6934    ) -> Vec<Range<BufferRow>> {
 6935        let buffer_snapshot = buffer.read(cx).snapshot();
 6936        let ranges = ranges
 6937            .iter()
 6938            .map(|range| range.to_point(&buffer_snapshot))
 6939            .collect::<Vec<_>>();
 6940
 6941        self.latest_lsp_data(buffer, cx)
 6942            .inlay_hints
 6943            .applicable_chunks(ranges.as_slice())
 6944            .map(|chunk| chunk.row_range())
 6945            .collect()
 6946    }
 6947
 6948    pub fn invalidate_inlay_hints<'a>(
 6949        &'a mut self,
 6950        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6951    ) {
 6952        for buffer_id in for_buffers {
 6953            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6954                lsp_data.inlay_hints.clear();
 6955            }
 6956        }
 6957    }
 6958
 6959    pub fn inlay_hints(
 6960        &mut self,
 6961        invalidate: InvalidationStrategy,
 6962        buffer: Entity<Buffer>,
 6963        ranges: Vec<Range<text::Anchor>>,
 6964        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6965        cx: &mut Context<Self>,
 6966    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6967        let next_hint_id = self.next_hint_id.clone();
 6968        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6969        let query_version = lsp_data.buffer_version.clone();
 6970        let mut lsp_refresh_requested = false;
 6971        let for_server = if let InvalidationStrategy::RefreshRequested {
 6972            server_id,
 6973            request_id,
 6974        } = invalidate
 6975        {
 6976            let invalidated = lsp_data
 6977                .inlay_hints
 6978                .invalidate_for_server_refresh(server_id, request_id);
 6979            lsp_refresh_requested = invalidated;
 6980            Some(server_id)
 6981        } else {
 6982            None
 6983        };
 6984        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6985        let known_chunks = known_chunks
 6986            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6987            .map(|(_, known_chunks)| known_chunks)
 6988            .unwrap_or_default();
 6989
 6990        let buffer_snapshot = buffer.read(cx).snapshot();
 6991        let ranges = ranges
 6992            .iter()
 6993            .map(|range| range.to_point(&buffer_snapshot))
 6994            .collect::<Vec<_>>();
 6995
 6996        let mut hint_fetch_tasks = Vec::new();
 6997        let mut cached_inlay_hints = None;
 6998        let mut ranges_to_query = None;
 6999        let applicable_chunks = existing_inlay_hints
 7000            .applicable_chunks(ranges.as_slice())
 7001            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7002            .collect::<Vec<_>>();
 7003        if applicable_chunks.is_empty() {
 7004            return HashMap::default();
 7005        }
 7006
 7007        for row_chunk in applicable_chunks {
 7008            match (
 7009                existing_inlay_hints
 7010                    .cached_hints(&row_chunk)
 7011                    .filter(|_| !lsp_refresh_requested)
 7012                    .cloned(),
 7013                existing_inlay_hints
 7014                    .fetched_hints(&row_chunk)
 7015                    .as_ref()
 7016                    .filter(|_| !lsp_refresh_requested)
 7017                    .cloned(),
 7018            ) {
 7019                (None, None) => {
 7020                    let chunk_range = row_chunk.anchor_range();
 7021                    ranges_to_query
 7022                        .get_or_insert_with(Vec::new)
 7023                        .push((row_chunk, chunk_range));
 7024                }
 7025                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7026                (Some(cached_hints), None) => {
 7027                    for (server_id, cached_hints) in cached_hints {
 7028                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7029                            cached_inlay_hints
 7030                                .get_or_insert_with(HashMap::default)
 7031                                .entry(row_chunk.row_range())
 7032                                .or_insert_with(HashMap::default)
 7033                                .entry(server_id)
 7034                                .or_insert_with(Vec::new)
 7035                                .extend(cached_hints);
 7036                        }
 7037                    }
 7038                }
 7039                (Some(cached_hints), Some(fetched_hints)) => {
 7040                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7041                    for (server_id, cached_hints) in cached_hints {
 7042                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7043                            cached_inlay_hints
 7044                                .get_or_insert_with(HashMap::default)
 7045                                .entry(row_chunk.row_range())
 7046                                .or_insert_with(HashMap::default)
 7047                                .entry(server_id)
 7048                                .or_insert_with(Vec::new)
 7049                                .extend(cached_hints);
 7050                        }
 7051                    }
 7052                }
 7053            }
 7054        }
 7055
 7056        if hint_fetch_tasks.is_empty()
 7057            && ranges_to_query
 7058                .as_ref()
 7059                .is_none_or(|ranges| ranges.is_empty())
 7060            && let Some(cached_inlay_hints) = cached_inlay_hints
 7061        {
 7062            cached_inlay_hints
 7063                .into_iter()
 7064                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7065                .collect()
 7066        } else {
 7067            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7068                let next_hint_id = next_hint_id.clone();
 7069                let buffer = buffer.clone();
 7070                let query_version = query_version.clone();
 7071                let new_inlay_hints = cx
 7072                    .spawn(async move |lsp_store, cx| {
 7073                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7074                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7075                        })?;
 7076                        new_fetch_task
 7077                            .await
 7078                            .and_then(|new_hints_by_server| {
 7079                                lsp_store.update(cx, |lsp_store, cx| {
 7080                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7081                                    let update_cache = lsp_data.buffer_version == query_version;
 7082                                    if new_hints_by_server.is_empty() {
 7083                                        if update_cache {
 7084                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7085                                        }
 7086                                        HashMap::default()
 7087                                    } else {
 7088                                        new_hints_by_server
 7089                                            .into_iter()
 7090                                            .map(|(server_id, new_hints)| {
 7091                                                let new_hints = new_hints
 7092                                                    .into_iter()
 7093                                                    .map(|new_hint| {
 7094                                                        (
 7095                                                            InlayId::Hint(next_hint_id.fetch_add(
 7096                                                                1,
 7097                                                                atomic::Ordering::AcqRel,
 7098                                                            )),
 7099                                                            new_hint,
 7100                                                        )
 7101                                                    })
 7102                                                    .collect::<Vec<_>>();
 7103                                                if update_cache {
 7104                                                    lsp_data.inlay_hints.insert_new_hints(
 7105                                                        chunk,
 7106                                                        server_id,
 7107                                                        new_hints.clone(),
 7108                                                    );
 7109                                                }
 7110                                                (server_id, new_hints)
 7111                                            })
 7112                                            .collect()
 7113                                    }
 7114                                })
 7115                            })
 7116                            .map_err(Arc::new)
 7117                    })
 7118                    .shared();
 7119
 7120                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7121                *fetch_task = Some(new_inlay_hints.clone());
 7122                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7123            }
 7124
 7125            cached_inlay_hints
 7126                .unwrap_or_default()
 7127                .into_iter()
 7128                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7129                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7130                    (
 7131                        chunk.row_range(),
 7132                        cx.spawn(async move |_, _| {
 7133                            hints_fetch.await.map_err(|e| {
 7134                                if e.error_code() != ErrorCode::Internal {
 7135                                    anyhow!(e.error_code())
 7136                                } else {
 7137                                    anyhow!("{e:#}")
 7138                                }
 7139                            })
 7140                        }),
 7141                    )
 7142                }))
 7143                .collect()
 7144        }
 7145    }
 7146
 7147    fn fetch_inlay_hints(
 7148        &mut self,
 7149        for_server: Option<LanguageServerId>,
 7150        buffer: &Entity<Buffer>,
 7151        range: Range<Anchor>,
 7152        cx: &mut Context<Self>,
 7153    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7154        let request = InlayHints {
 7155            range: range.clone(),
 7156        };
 7157        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7158            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7159                return Task::ready(Ok(HashMap::default()));
 7160            }
 7161            let request_task = upstream_client.request_lsp(
 7162                project_id,
 7163                for_server.map(|id| id.to_proto()),
 7164                LSP_REQUEST_TIMEOUT,
 7165                cx.background_executor().clone(),
 7166                request.to_proto(project_id, buffer.read(cx)),
 7167            );
 7168            let buffer = buffer.clone();
 7169            cx.spawn(async move |weak_lsp_store, cx| {
 7170                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7171                    return Ok(HashMap::default());
 7172                };
 7173                let Some(responses) = request_task.await? else {
 7174                    return Ok(HashMap::default());
 7175                };
 7176
 7177                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7178                    let lsp_store = lsp_store.clone();
 7179                    let buffer = buffer.clone();
 7180                    let cx = cx.clone();
 7181                    let request = request.clone();
 7182                    async move {
 7183                        (
 7184                            LanguageServerId::from_proto(response.server_id),
 7185                            request
 7186                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7187                                .await,
 7188                        )
 7189                    }
 7190                }))
 7191                .await;
 7192
 7193                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7194                let mut has_errors = false;
 7195                let inlay_hints = inlay_hints
 7196                    .into_iter()
 7197                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7198                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7199                        Err(e) => {
 7200                            has_errors = true;
 7201                            log::error!("{e:#}");
 7202                            None
 7203                        }
 7204                    })
 7205                    .map(|(server_id, mut new_hints)| {
 7206                        new_hints.retain(|hint| {
 7207                            hint.position.is_valid(&buffer_snapshot)
 7208                                && range.start.is_valid(&buffer_snapshot)
 7209                                && range.end.is_valid(&buffer_snapshot)
 7210                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7211                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7212                        });
 7213                        (server_id, new_hints)
 7214                    })
 7215                    .collect::<HashMap<_, _>>();
 7216                anyhow::ensure!(
 7217                    !has_errors || !inlay_hints.is_empty(),
 7218                    "Failed to fetch inlay hints"
 7219                );
 7220                Ok(inlay_hints)
 7221            })
 7222        } else {
 7223            let inlay_hints_task = match for_server {
 7224                Some(server_id) => {
 7225                    let server_task = self.request_lsp(
 7226                        buffer.clone(),
 7227                        LanguageServerToQuery::Other(server_id),
 7228                        request,
 7229                        cx,
 7230                    );
 7231                    cx.background_spawn(async move {
 7232                        let mut responses = Vec::new();
 7233                        match server_task.await {
 7234                            Ok(response) => responses.push((server_id, response)),
 7235                            // rust-analyzer likes to error with this when its still loading up
 7236                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7237                            Err(e) => log::error!(
 7238                                "Error handling response for inlay hints request: {e:#}"
 7239                            ),
 7240                        }
 7241                        responses
 7242                    })
 7243                }
 7244                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7245            };
 7246            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7247            cx.background_spawn(async move {
 7248                Ok(inlay_hints_task
 7249                    .await
 7250                    .into_iter()
 7251                    .map(|(server_id, mut new_hints)| {
 7252                        new_hints.retain(|hint| {
 7253                            hint.position.is_valid(&buffer_snapshot)
 7254                                && range.start.is_valid(&buffer_snapshot)
 7255                                && range.end.is_valid(&buffer_snapshot)
 7256                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7257                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7258                        });
 7259                        (server_id, new_hints)
 7260                    })
 7261                    .collect())
 7262            })
 7263        }
 7264    }
 7265
 7266    pub fn pull_diagnostics_for_buffer(
 7267        &mut self,
 7268        buffer: Entity<Buffer>,
 7269        cx: &mut Context<Self>,
 7270    ) -> Task<anyhow::Result<()>> {
 7271        let diagnostics = self.pull_diagnostics(buffer, cx);
 7272        cx.spawn(async move |lsp_store, cx| {
 7273            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7274                return Ok(());
 7275            };
 7276            lsp_store.update(cx, |lsp_store, cx| {
 7277                if lsp_store.as_local().is_none() {
 7278                    return;
 7279                }
 7280
 7281                let mut unchanged_buffers = HashMap::default();
 7282                let server_diagnostics_updates = diagnostics
 7283                    .into_iter()
 7284                    .filter_map(|diagnostics_set| match diagnostics_set {
 7285                        LspPullDiagnostics::Response {
 7286                            server_id,
 7287                            uri,
 7288                            diagnostics,
 7289                            registration_id,
 7290                        } => Some((server_id, uri, diagnostics, registration_id)),
 7291                        LspPullDiagnostics::Default => None,
 7292                    })
 7293                    .fold(
 7294                        HashMap::default(),
 7295                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7296                            let (result_id, diagnostics) = match diagnostics {
 7297                                PulledDiagnostics::Unchanged { result_id } => {
 7298                                    unchanged_buffers
 7299                                        .entry(new_registration_id.clone())
 7300                                        .or_insert_with(HashSet::default)
 7301                                        .insert(uri.clone());
 7302                                    (Some(result_id), Vec::new())
 7303                                }
 7304                                PulledDiagnostics::Changed {
 7305                                    result_id,
 7306                                    diagnostics,
 7307                                } => (result_id, diagnostics),
 7308                            };
 7309                            let disk_based_sources = Cow::Owned(
 7310                                lsp_store
 7311                                    .language_server_adapter_for_id(server_id)
 7312                                    .as_ref()
 7313                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7314                                    .unwrap_or(&[])
 7315                                    .to_vec(),
 7316                            );
 7317                            acc.entry(server_id)
 7318                                .or_insert_with(HashMap::default)
 7319                                .entry(new_registration_id.clone())
 7320                                .or_insert_with(Vec::new)
 7321                                .push(DocumentDiagnosticsUpdate {
 7322                                    server_id,
 7323                                    diagnostics: lsp::PublishDiagnosticsParams {
 7324                                        uri,
 7325                                        diagnostics,
 7326                                        version: None,
 7327                                    },
 7328                                    result_id,
 7329                                    disk_based_sources,
 7330                                    registration_id: new_registration_id,
 7331                                });
 7332                            acc
 7333                        },
 7334                    );
 7335
 7336                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7337                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7338                        lsp_store
 7339                            .merge_lsp_diagnostics(
 7340                                DiagnosticSourceKind::Pulled,
 7341                                diagnostic_updates,
 7342                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7343                                    DiagnosticSourceKind::Pulled => {
 7344                                        old_diagnostic.registration_id != registration_id
 7345                                            || unchanged_buffers
 7346                                                .get(&old_diagnostic.registration_id)
 7347                                                .is_some_and(|unchanged_buffers| {
 7348                                                    unchanged_buffers.contains(&document_uri)
 7349                                                })
 7350                                    }
 7351                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7352                                        true
 7353                                    }
 7354                                },
 7355                                cx,
 7356                            )
 7357                            .log_err();
 7358                    }
 7359                }
 7360            })
 7361        })
 7362    }
 7363
 7364    pub fn document_colors(
 7365        &mut self,
 7366        known_cache_version: Option<usize>,
 7367        buffer: Entity<Buffer>,
 7368        cx: &mut Context<Self>,
 7369    ) -> Option<DocumentColorTask> {
 7370        let version_queried_for = buffer.read(cx).version();
 7371        let buffer_id = buffer.read(cx).remote_id();
 7372
 7373        let current_language_servers = self.as_local().map(|local| {
 7374            local
 7375                .buffers_opened_in_servers
 7376                .get(&buffer_id)
 7377                .cloned()
 7378                .unwrap_or_default()
 7379        });
 7380
 7381        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7382            if let Some(cached_colors) = &lsp_data.document_colors {
 7383                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7384                    let has_different_servers =
 7385                        current_language_servers.is_some_and(|current_language_servers| {
 7386                            current_language_servers
 7387                                != cached_colors.colors.keys().copied().collect()
 7388                        });
 7389                    if !has_different_servers {
 7390                        let cache_version = cached_colors.cache_version;
 7391                        if Some(cache_version) == known_cache_version {
 7392                            return None;
 7393                        } else {
 7394                            return Some(
 7395                                Task::ready(Ok(DocumentColors {
 7396                                    colors: cached_colors
 7397                                        .colors
 7398                                        .values()
 7399                                        .flatten()
 7400                                        .cloned()
 7401                                        .collect(),
 7402                                    cache_version: Some(cache_version),
 7403                                }))
 7404                                .shared(),
 7405                            );
 7406                        }
 7407                    }
 7408                }
 7409            }
 7410        }
 7411
 7412        let color_lsp_data = self
 7413            .latest_lsp_data(&buffer, cx)
 7414            .document_colors
 7415            .get_or_insert_default();
 7416        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7417            && !version_queried_for.changed_since(updating_for)
 7418        {
 7419            return Some(running_update.clone());
 7420        }
 7421        let buffer_version_queried_for = version_queried_for.clone();
 7422        let new_task = cx
 7423            .spawn(async move |lsp_store, cx| {
 7424                cx.background_executor()
 7425                    .timer(Duration::from_millis(30))
 7426                    .await;
 7427                let fetched_colors = lsp_store
 7428                    .update(cx, |lsp_store, cx| {
 7429                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7430                    })?
 7431                    .await
 7432                    .context("fetching document colors")
 7433                    .map_err(Arc::new);
 7434                let fetched_colors = match fetched_colors {
 7435                    Ok(fetched_colors) => {
 7436                        if Some(true)
 7437                            == buffer
 7438                                .update(cx, |buffer, _| {
 7439                                    buffer.version() != buffer_version_queried_for
 7440                                })
 7441                                .ok()
 7442                        {
 7443                            return Ok(DocumentColors::default());
 7444                        }
 7445                        fetched_colors
 7446                    }
 7447                    Err(e) => {
 7448                        lsp_store
 7449                            .update(cx, |lsp_store, _| {
 7450                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7451                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7452                                        document_colors.colors_update = None;
 7453                                    }
 7454                                }
 7455                            })
 7456                            .ok();
 7457                        return Err(e);
 7458                    }
 7459                };
 7460
 7461                lsp_store
 7462                    .update(cx, |lsp_store, cx| {
 7463                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7464                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7465
 7466                        if let Some(fetched_colors) = fetched_colors {
 7467                            if lsp_data.buffer_version == buffer_version_queried_for {
 7468                                lsp_colors.colors.extend(fetched_colors);
 7469                                lsp_colors.cache_version += 1;
 7470                            } else if !lsp_data
 7471                                .buffer_version
 7472                                .changed_since(&buffer_version_queried_for)
 7473                            {
 7474                                lsp_data.buffer_version = buffer_version_queried_for;
 7475                                lsp_colors.colors = fetched_colors;
 7476                                lsp_colors.cache_version += 1;
 7477                            }
 7478                        }
 7479                        lsp_colors.colors_update = None;
 7480                        let colors = lsp_colors
 7481                            .colors
 7482                            .values()
 7483                            .flatten()
 7484                            .cloned()
 7485                            .collect::<HashSet<_>>();
 7486                        DocumentColors {
 7487                            colors,
 7488                            cache_version: Some(lsp_colors.cache_version),
 7489                        }
 7490                    })
 7491                    .map_err(Arc::new)
 7492            })
 7493            .shared();
 7494        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7495        Some(new_task)
 7496    }
 7497
 7498    fn fetch_document_colors_for_buffer(
 7499        &mut self,
 7500        buffer: &Entity<Buffer>,
 7501        cx: &mut Context<Self>,
 7502    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7503        if let Some((client, project_id)) = self.upstream_client() {
 7504            let request = GetDocumentColor {};
 7505            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7506                return Task::ready(Ok(None));
 7507            }
 7508
 7509            let request_task = client.request_lsp(
 7510                project_id,
 7511                None,
 7512                LSP_REQUEST_TIMEOUT,
 7513                cx.background_executor().clone(),
 7514                request.to_proto(project_id, buffer.read(cx)),
 7515            );
 7516            let buffer = buffer.clone();
 7517            cx.spawn(async move |lsp_store, cx| {
 7518                let Some(lsp_store) = lsp_store.upgrade() else {
 7519                    return Ok(None);
 7520                };
 7521                let colors = join_all(
 7522                    request_task
 7523                        .await
 7524                        .log_err()
 7525                        .flatten()
 7526                        .map(|response| response.payload)
 7527                        .unwrap_or_default()
 7528                        .into_iter()
 7529                        .map(|color_response| {
 7530                            let response = request.response_from_proto(
 7531                                color_response.response,
 7532                                lsp_store.clone(),
 7533                                buffer.clone(),
 7534                                cx.clone(),
 7535                            );
 7536                            async move {
 7537                                (
 7538                                    LanguageServerId::from_proto(color_response.server_id),
 7539                                    response.await.log_err().unwrap_or_default(),
 7540                                )
 7541                            }
 7542                        }),
 7543                )
 7544                .await
 7545                .into_iter()
 7546                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7547                    acc.entry(server_id)
 7548                        .or_insert_with(HashSet::default)
 7549                        .extend(colors);
 7550                    acc
 7551                });
 7552                Ok(Some(colors))
 7553            })
 7554        } else {
 7555            let document_colors_task =
 7556                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7557            cx.background_spawn(async move {
 7558                Ok(Some(
 7559                    document_colors_task
 7560                        .await
 7561                        .into_iter()
 7562                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7563                            acc.entry(server_id)
 7564                                .or_insert_with(HashSet::default)
 7565                                .extend(colors);
 7566                            acc
 7567                        })
 7568                        .into_iter()
 7569                        .collect(),
 7570                ))
 7571            })
 7572        }
 7573    }
 7574
 7575    pub fn signature_help<T: ToPointUtf16>(
 7576        &mut self,
 7577        buffer: &Entity<Buffer>,
 7578        position: T,
 7579        cx: &mut Context<Self>,
 7580    ) -> Task<Option<Vec<SignatureHelp>>> {
 7581        let position = position.to_point_utf16(buffer.read(cx));
 7582
 7583        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7584            let request = GetSignatureHelp { position };
 7585            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7586                return Task::ready(None);
 7587            }
 7588            let request_task = client.request_lsp(
 7589                upstream_project_id,
 7590                None,
 7591                LSP_REQUEST_TIMEOUT,
 7592                cx.background_executor().clone(),
 7593                request.to_proto(upstream_project_id, buffer.read(cx)),
 7594            );
 7595            let buffer = buffer.clone();
 7596            cx.spawn(async move |weak_lsp_store, cx| {
 7597                let lsp_store = weak_lsp_store.upgrade()?;
 7598                let signatures = join_all(
 7599                    request_task
 7600                        .await
 7601                        .log_err()
 7602                        .flatten()
 7603                        .map(|response| response.payload)
 7604                        .unwrap_or_default()
 7605                        .into_iter()
 7606                        .map(|response| {
 7607                            let response = GetSignatureHelp { position }.response_from_proto(
 7608                                response.response,
 7609                                lsp_store.clone(),
 7610                                buffer.clone(),
 7611                                cx.clone(),
 7612                            );
 7613                            async move { response.await.log_err().flatten() }
 7614                        }),
 7615                )
 7616                .await
 7617                .into_iter()
 7618                .flatten()
 7619                .collect();
 7620                Some(signatures)
 7621            })
 7622        } else {
 7623            let all_actions_task = self.request_multiple_lsp_locally(
 7624                buffer,
 7625                Some(position),
 7626                GetSignatureHelp { position },
 7627                cx,
 7628            );
 7629            cx.background_spawn(async move {
 7630                Some(
 7631                    all_actions_task
 7632                        .await
 7633                        .into_iter()
 7634                        .flat_map(|(_, actions)| actions)
 7635                        .collect::<Vec<_>>(),
 7636                )
 7637            })
 7638        }
 7639    }
 7640
 7641    pub fn hover(
 7642        &mut self,
 7643        buffer: &Entity<Buffer>,
 7644        position: PointUtf16,
 7645        cx: &mut Context<Self>,
 7646    ) -> Task<Option<Vec<Hover>>> {
 7647        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7648            let request = GetHover { position };
 7649            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7650                return Task::ready(None);
 7651            }
 7652            let request_task = client.request_lsp(
 7653                upstream_project_id,
 7654                None,
 7655                LSP_REQUEST_TIMEOUT,
 7656                cx.background_executor().clone(),
 7657                request.to_proto(upstream_project_id, buffer.read(cx)),
 7658            );
 7659            let buffer = buffer.clone();
 7660            cx.spawn(async move |weak_lsp_store, cx| {
 7661                let lsp_store = weak_lsp_store.upgrade()?;
 7662                let hovers = join_all(
 7663                    request_task
 7664                        .await
 7665                        .log_err()
 7666                        .flatten()
 7667                        .map(|response| response.payload)
 7668                        .unwrap_or_default()
 7669                        .into_iter()
 7670                        .map(|response| {
 7671                            let response = GetHover { position }.response_from_proto(
 7672                                response.response,
 7673                                lsp_store.clone(),
 7674                                buffer.clone(),
 7675                                cx.clone(),
 7676                            );
 7677                            async move {
 7678                                response
 7679                                    .await
 7680                                    .log_err()
 7681                                    .flatten()
 7682                                    .and_then(remove_empty_hover_blocks)
 7683                            }
 7684                        }),
 7685                )
 7686                .await
 7687                .into_iter()
 7688                .flatten()
 7689                .collect();
 7690                Some(hovers)
 7691            })
 7692        } else {
 7693            let all_actions_task = self.request_multiple_lsp_locally(
 7694                buffer,
 7695                Some(position),
 7696                GetHover { position },
 7697                cx,
 7698            );
 7699            cx.background_spawn(async move {
 7700                Some(
 7701                    all_actions_task
 7702                        .await
 7703                        .into_iter()
 7704                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7705                        .collect::<Vec<Hover>>(),
 7706                )
 7707            })
 7708        }
 7709    }
 7710
 7711    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7712        let language_registry = self.languages.clone();
 7713
 7714        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7715            let request = upstream_client.request(proto::GetProjectSymbols {
 7716                project_id: *project_id,
 7717                query: query.to_string(),
 7718            });
 7719            cx.foreground_executor().spawn(async move {
 7720                let response = request.await?;
 7721                let mut symbols = Vec::new();
 7722                let core_symbols = response
 7723                    .symbols
 7724                    .into_iter()
 7725                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7726                    .collect::<Vec<_>>();
 7727                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7728                    .await;
 7729                Ok(symbols)
 7730            })
 7731        } else if let Some(local) = self.as_local() {
 7732            struct WorkspaceSymbolsResult {
 7733                server_id: LanguageServerId,
 7734                lsp_adapter: Arc<CachedLspAdapter>,
 7735                worktree: WeakEntity<Worktree>,
 7736                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7737            }
 7738
 7739            let mut requests = Vec::new();
 7740            let mut requested_servers = BTreeSet::new();
 7741            for (seed, state) in local.language_server_ids.iter() {
 7742                let Some(worktree_handle) = self
 7743                    .worktree_store
 7744                    .read(cx)
 7745                    .worktree_for_id(seed.worktree_id, cx)
 7746                else {
 7747                    continue;
 7748                };
 7749                let worktree = worktree_handle.read(cx);
 7750                if !worktree.is_visible() {
 7751                    continue;
 7752                }
 7753
 7754                if !requested_servers.insert(state.id) {
 7755                    continue;
 7756                }
 7757
 7758                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7759                    Some(LanguageServerState::Running {
 7760                        adapter, server, ..
 7761                    }) => (adapter.clone(), server),
 7762
 7763                    _ => continue,
 7764                };
 7765                let supports_workspace_symbol_request =
 7766                    match server.capabilities().workspace_symbol_provider {
 7767                        Some(OneOf::Left(supported)) => supported,
 7768                        Some(OneOf::Right(_)) => true,
 7769                        None => false,
 7770                    };
 7771                if !supports_workspace_symbol_request {
 7772                    continue;
 7773                }
 7774                let worktree_handle = worktree_handle.clone();
 7775                let server_id = server.server_id();
 7776                requests.push(
 7777                        server
 7778                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7779                                lsp::WorkspaceSymbolParams {
 7780                                    query: query.to_string(),
 7781                                    ..Default::default()
 7782                                },
 7783                            )
 7784                            .map(move |response| {
 7785                                let lsp_symbols = response.into_response()
 7786                                    .context("workspace symbols request")
 7787                                    .log_err()
 7788                                    .flatten()
 7789                                    .map(|symbol_response| match symbol_response {
 7790                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7791                                            flat_responses.into_iter().map(|lsp_symbol| {
 7792                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7793                                            }).collect::<Vec<_>>()
 7794                                        }
 7795                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7796                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7797                                                let location = match lsp_symbol.location {
 7798                                                    OneOf::Left(location) => location,
 7799                                                    OneOf::Right(_) => {
 7800                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7801                                                        return None
 7802                                                    }
 7803                                                };
 7804                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7805                                            }).collect::<Vec<_>>()
 7806                                        }
 7807                                    }).unwrap_or_default();
 7808
 7809                                WorkspaceSymbolsResult {
 7810                                    server_id,
 7811                                    lsp_adapter,
 7812                                    worktree: worktree_handle.downgrade(),
 7813                                    lsp_symbols,
 7814                                }
 7815                            }),
 7816                    );
 7817            }
 7818
 7819            cx.spawn(async move |this, cx| {
 7820                let responses = futures::future::join_all(requests).await;
 7821                let this = match this.upgrade() {
 7822                    Some(this) => this,
 7823                    None => return Ok(Vec::new()),
 7824                };
 7825
 7826                let mut symbols = Vec::new();
 7827                for result in responses {
 7828                    let core_symbols = this.update(cx, |this, cx| {
 7829                        result
 7830                            .lsp_symbols
 7831                            .into_iter()
 7832                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7833                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7834                                let source_worktree = result.worktree.upgrade()?;
 7835                                let source_worktree_id = source_worktree.read(cx).id();
 7836
 7837                                let path = if let Some((tree, rel_path)) =
 7838                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7839                                {
 7840                                    let worktree_id = tree.read(cx).id();
 7841                                    SymbolLocation::InProject(ProjectPath {
 7842                                        worktree_id,
 7843                                        path: rel_path,
 7844                                    })
 7845                                } else {
 7846                                    SymbolLocation::OutsideProject {
 7847                                        signature: this.symbol_signature(&abs_path),
 7848                                        abs_path: abs_path.into(),
 7849                                    }
 7850                                };
 7851
 7852                                Some(CoreSymbol {
 7853                                    source_language_server_id: result.server_id,
 7854                                    language_server_name: result.lsp_adapter.name.clone(),
 7855                                    source_worktree_id,
 7856                                    path,
 7857                                    kind: symbol_kind,
 7858                                    name: symbol_name,
 7859                                    range: range_from_lsp(symbol_location.range),
 7860                                })
 7861                            })
 7862                            .collect()
 7863                    })?;
 7864
 7865                    populate_labels_for_symbols(
 7866                        core_symbols,
 7867                        &language_registry,
 7868                        Some(result.lsp_adapter),
 7869                        &mut symbols,
 7870                    )
 7871                    .await;
 7872                }
 7873
 7874                Ok(symbols)
 7875            })
 7876        } else {
 7877            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7878        }
 7879    }
 7880
 7881    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7882        let mut summary = DiagnosticSummary::default();
 7883        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7884            summary.error_count += path_summary.error_count;
 7885            summary.warning_count += path_summary.warning_count;
 7886        }
 7887        summary
 7888    }
 7889
 7890    /// Returns the diagnostic summary for a specific project path.
 7891    pub fn diagnostic_summary_for_path(
 7892        &self,
 7893        project_path: &ProjectPath,
 7894        _: &App,
 7895    ) -> DiagnosticSummary {
 7896        if let Some(summaries) = self
 7897            .diagnostic_summaries
 7898            .get(&project_path.worktree_id)
 7899            .and_then(|map| map.get(&project_path.path))
 7900        {
 7901            let (error_count, warning_count) = summaries.iter().fold(
 7902                (0, 0),
 7903                |(error_count, warning_count), (_language_server_id, summary)| {
 7904                    (
 7905                        error_count + summary.error_count,
 7906                        warning_count + summary.warning_count,
 7907                    )
 7908                },
 7909            );
 7910
 7911            DiagnosticSummary {
 7912                error_count,
 7913                warning_count,
 7914            }
 7915        } else {
 7916            DiagnosticSummary::default()
 7917        }
 7918    }
 7919
 7920    pub fn diagnostic_summaries<'a>(
 7921        &'a self,
 7922        include_ignored: bool,
 7923        cx: &'a App,
 7924    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7925        self.worktree_store
 7926            .read(cx)
 7927            .visible_worktrees(cx)
 7928            .filter_map(|worktree| {
 7929                let worktree = worktree.read(cx);
 7930                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7931            })
 7932            .flat_map(move |(worktree, summaries)| {
 7933                let worktree_id = worktree.id();
 7934                summaries
 7935                    .iter()
 7936                    .filter(move |(path, _)| {
 7937                        include_ignored
 7938                            || worktree
 7939                                .entry_for_path(path.as_ref())
 7940                                .is_some_and(|entry| !entry.is_ignored)
 7941                    })
 7942                    .flat_map(move |(path, summaries)| {
 7943                        summaries.iter().map(move |(server_id, summary)| {
 7944                            (
 7945                                ProjectPath {
 7946                                    worktree_id,
 7947                                    path: path.clone(),
 7948                                },
 7949                                *server_id,
 7950                                *summary,
 7951                            )
 7952                        })
 7953                    })
 7954            })
 7955    }
 7956
 7957    pub fn on_buffer_edited(
 7958        &mut self,
 7959        buffer: Entity<Buffer>,
 7960        cx: &mut Context<Self>,
 7961    ) -> Option<()> {
 7962        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7963            Some(
 7964                self.as_local()?
 7965                    .language_servers_for_buffer(buffer, cx)
 7966                    .map(|i| i.1.clone())
 7967                    .collect(),
 7968            )
 7969        })?;
 7970
 7971        let buffer = buffer.read(cx);
 7972        let file = File::from_dyn(buffer.file())?;
 7973        let abs_path = file.as_local()?.abs_path(cx);
 7974        let uri = lsp::Uri::from_file_path(&abs_path)
 7975            .ok()
 7976            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7977            .log_err()?;
 7978        let next_snapshot = buffer.text_snapshot();
 7979        for language_server in language_servers {
 7980            let language_server = language_server.clone();
 7981
 7982            let buffer_snapshots = self
 7983                .as_local_mut()?
 7984                .buffer_snapshots
 7985                .get_mut(&buffer.remote_id())
 7986                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7987            let previous_snapshot = buffer_snapshots.last()?;
 7988
 7989            let build_incremental_change = || {
 7990                buffer
 7991                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7992                        previous_snapshot.snapshot.version(),
 7993                    )
 7994                    .map(|edit| {
 7995                        let edit_start = edit.new.start.0;
 7996                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7997                        let new_text = next_snapshot
 7998                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7999                            .collect();
 8000                        lsp::TextDocumentContentChangeEvent {
 8001                            range: Some(lsp::Range::new(
 8002                                point_to_lsp(edit_start),
 8003                                point_to_lsp(edit_end),
 8004                            )),
 8005                            range_length: None,
 8006                            text: new_text,
 8007                        }
 8008                    })
 8009                    .collect()
 8010            };
 8011
 8012            let document_sync_kind = language_server
 8013                .capabilities()
 8014                .text_document_sync
 8015                .as_ref()
 8016                .and_then(|sync| match sync {
 8017                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8018                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8019                });
 8020
 8021            let content_changes: Vec<_> = match document_sync_kind {
 8022                Some(lsp::TextDocumentSyncKind::FULL) => {
 8023                    vec![lsp::TextDocumentContentChangeEvent {
 8024                        range: None,
 8025                        range_length: None,
 8026                        text: next_snapshot.text(),
 8027                    }]
 8028                }
 8029                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8030                _ => {
 8031                    #[cfg(any(test, feature = "test-support"))]
 8032                    {
 8033                        build_incremental_change()
 8034                    }
 8035
 8036                    #[cfg(not(any(test, feature = "test-support")))]
 8037                    {
 8038                        continue;
 8039                    }
 8040                }
 8041            };
 8042
 8043            let next_version = previous_snapshot.version + 1;
 8044            buffer_snapshots.push(LspBufferSnapshot {
 8045                version: next_version,
 8046                snapshot: next_snapshot.clone(),
 8047            });
 8048
 8049            language_server
 8050                .notify::<lsp::notification::DidChangeTextDocument>(
 8051                    lsp::DidChangeTextDocumentParams {
 8052                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8053                            uri.clone(),
 8054                            next_version,
 8055                        ),
 8056                        content_changes,
 8057                    },
 8058                )
 8059                .ok();
 8060            self.pull_workspace_diagnostics(language_server.server_id());
 8061        }
 8062
 8063        None
 8064    }
 8065
 8066    pub fn on_buffer_saved(
 8067        &mut self,
 8068        buffer: Entity<Buffer>,
 8069        cx: &mut Context<Self>,
 8070    ) -> Option<()> {
 8071        let file = File::from_dyn(buffer.read(cx).file())?;
 8072        let worktree_id = file.worktree_id(cx);
 8073        let abs_path = file.as_local()?.abs_path(cx);
 8074        let text_document = lsp::TextDocumentIdentifier {
 8075            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8076        };
 8077        let local = self.as_local()?;
 8078
 8079        for server in local.language_servers_for_worktree(worktree_id) {
 8080            if let Some(include_text) = include_text(server.as_ref()) {
 8081                let text = if include_text {
 8082                    Some(buffer.read(cx).text())
 8083                } else {
 8084                    None
 8085                };
 8086                server
 8087                    .notify::<lsp::notification::DidSaveTextDocument>(
 8088                        lsp::DidSaveTextDocumentParams {
 8089                            text_document: text_document.clone(),
 8090                            text,
 8091                        },
 8092                    )
 8093                    .ok();
 8094            }
 8095        }
 8096
 8097        let language_servers = buffer.update(cx, |buffer, cx| {
 8098            local.language_server_ids_for_buffer(buffer, cx)
 8099        });
 8100        for language_server_id in language_servers {
 8101            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8102        }
 8103
 8104        None
 8105    }
 8106
 8107    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8108        maybe!(async move {
 8109            let mut refreshed_servers = HashSet::default();
 8110            let servers = lsp_store
 8111                .update(cx, |lsp_store, cx| {
 8112                    let local = lsp_store.as_local()?;
 8113
 8114                    let servers = local
 8115                        .language_server_ids
 8116                        .iter()
 8117                        .filter_map(|(seed, state)| {
 8118                            let worktree = lsp_store
 8119                                .worktree_store
 8120                                .read(cx)
 8121                                .worktree_for_id(seed.worktree_id, cx);
 8122                            let delegate: Arc<dyn LspAdapterDelegate> =
 8123                                worktree.map(|worktree| {
 8124                                    LocalLspAdapterDelegate::new(
 8125                                        local.languages.clone(),
 8126                                        &local.environment,
 8127                                        cx.weak_entity(),
 8128                                        &worktree,
 8129                                        local.http_client.clone(),
 8130                                        local.fs.clone(),
 8131                                        cx,
 8132                                    )
 8133                                })?;
 8134                            let server_id = state.id;
 8135
 8136                            let states = local.language_servers.get(&server_id)?;
 8137
 8138                            match states {
 8139                                LanguageServerState::Starting { .. } => None,
 8140                                LanguageServerState::Running {
 8141                                    adapter, server, ..
 8142                                } => {
 8143                                    let adapter = adapter.clone();
 8144                                    let server = server.clone();
 8145                                    refreshed_servers.insert(server.name());
 8146                                    let toolchain = seed.toolchain.clone();
 8147                                    Some(cx.spawn(async move |_, cx| {
 8148                                        let settings =
 8149                                            LocalLspStore::workspace_configuration_for_adapter(
 8150                                                adapter.adapter.clone(),
 8151                                                &delegate,
 8152                                                toolchain,
 8153                                                None,
 8154                                                cx,
 8155                                            )
 8156                                            .await
 8157                                            .ok()?;
 8158                                        server
 8159                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8160                                                lsp::DidChangeConfigurationParams { settings },
 8161                                            )
 8162                                            .ok()?;
 8163                                        Some(())
 8164                                    }))
 8165                                }
 8166                            }
 8167                        })
 8168                        .collect::<Vec<_>>();
 8169
 8170                    Some(servers)
 8171                })
 8172                .ok()
 8173                .flatten()?;
 8174
 8175            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8176            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8177            // to stop and unregister its language server wrapper.
 8178            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8179            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8180            let _: Vec<Option<()>> = join_all(servers).await;
 8181
 8182            Some(())
 8183        })
 8184        .await;
 8185    }
 8186
 8187    fn maintain_workspace_config(
 8188        external_refresh_requests: watch::Receiver<()>,
 8189        cx: &mut Context<Self>,
 8190    ) -> Task<Result<()>> {
 8191        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8192        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8193
 8194        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8195            *settings_changed_tx.borrow_mut() = ();
 8196        });
 8197
 8198        let mut joint_future =
 8199            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8200        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8201        // - 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).
 8202        // - 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.
 8203        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8204        // - 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,
 8205        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8206        cx.spawn(async move |this, cx| {
 8207            while let Some(()) = joint_future.next().await {
 8208                this.update(cx, |this, cx| {
 8209                    this.refresh_server_tree(cx);
 8210                })
 8211                .ok();
 8212
 8213                Self::refresh_workspace_configurations(&this, cx).await;
 8214            }
 8215
 8216            drop(settings_observation);
 8217            anyhow::Ok(())
 8218        })
 8219    }
 8220
 8221    pub fn running_language_servers_for_local_buffer<'a>(
 8222        &'a self,
 8223        buffer: &Buffer,
 8224        cx: &mut App,
 8225    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8226        let local = self.as_local();
 8227        let language_server_ids = local
 8228            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8229            .unwrap_or_default();
 8230
 8231        language_server_ids
 8232            .into_iter()
 8233            .filter_map(
 8234                move |server_id| match local?.language_servers.get(&server_id)? {
 8235                    LanguageServerState::Running {
 8236                        adapter, server, ..
 8237                    } => Some((adapter, server)),
 8238                    _ => None,
 8239                },
 8240            )
 8241    }
 8242
 8243    pub fn language_servers_for_local_buffer(
 8244        &self,
 8245        buffer: &Buffer,
 8246        cx: &mut App,
 8247    ) -> Vec<LanguageServerId> {
 8248        let local = self.as_local();
 8249        local
 8250            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8251            .unwrap_or_default()
 8252    }
 8253
 8254    pub fn language_server_for_local_buffer<'a>(
 8255        &'a self,
 8256        buffer: &'a Buffer,
 8257        server_id: LanguageServerId,
 8258        cx: &'a mut App,
 8259    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8260        self.as_local()?
 8261            .language_servers_for_buffer(buffer, cx)
 8262            .find(|(_, s)| s.server_id() == server_id)
 8263    }
 8264
 8265    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8266        self.diagnostic_summaries.remove(&id_to_remove);
 8267        if let Some(local) = self.as_local_mut() {
 8268            let to_remove = local.remove_worktree(id_to_remove, cx);
 8269            for server in to_remove {
 8270                self.language_server_statuses.remove(&server);
 8271            }
 8272        }
 8273    }
 8274
 8275    pub fn shared(
 8276        &mut self,
 8277        project_id: u64,
 8278        downstream_client: AnyProtoClient,
 8279        _: &mut Context<Self>,
 8280    ) {
 8281        self.downstream_client = Some((downstream_client.clone(), project_id));
 8282
 8283        for (server_id, status) in &self.language_server_statuses {
 8284            if let Some(server) = self.language_server_for_id(*server_id) {
 8285                downstream_client
 8286                    .send(proto::StartLanguageServer {
 8287                        project_id,
 8288                        server: Some(proto::LanguageServer {
 8289                            id: server_id.to_proto(),
 8290                            name: status.name.to_string(),
 8291                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8292                        }),
 8293                        capabilities: serde_json::to_string(&server.capabilities())
 8294                            .expect("serializing server LSP capabilities"),
 8295                    })
 8296                    .log_err();
 8297            }
 8298        }
 8299    }
 8300
 8301    pub fn disconnected_from_host(&mut self) {
 8302        self.downstream_client.take();
 8303    }
 8304
 8305    pub fn disconnected_from_ssh_remote(&mut self) {
 8306        if let LspStoreMode::Remote(RemoteLspStore {
 8307            upstream_client, ..
 8308        }) = &mut self.mode
 8309        {
 8310            upstream_client.take();
 8311        }
 8312    }
 8313
 8314    pub(crate) fn set_language_server_statuses_from_proto(
 8315        &mut self,
 8316        project: WeakEntity<Project>,
 8317        language_servers: Vec<proto::LanguageServer>,
 8318        server_capabilities: Vec<String>,
 8319        cx: &mut Context<Self>,
 8320    ) {
 8321        let lsp_logs = cx
 8322            .try_global::<GlobalLogStore>()
 8323            .map(|lsp_store| lsp_store.0.clone());
 8324
 8325        self.language_server_statuses = language_servers
 8326            .into_iter()
 8327            .zip(server_capabilities)
 8328            .map(|(server, server_capabilities)| {
 8329                let server_id = LanguageServerId(server.id as usize);
 8330                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8331                    self.lsp_server_capabilities
 8332                        .insert(server_id, server_capabilities);
 8333                }
 8334
 8335                let name = LanguageServerName::from_proto(server.name);
 8336                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8337
 8338                if let Some(lsp_logs) = &lsp_logs {
 8339                    lsp_logs.update(cx, |lsp_logs, cx| {
 8340                        lsp_logs.add_language_server(
 8341                            // Only remote clients get their language servers set from proto
 8342                            LanguageServerKind::Remote {
 8343                                project: project.clone(),
 8344                            },
 8345                            server_id,
 8346                            Some(name.clone()),
 8347                            worktree,
 8348                            None,
 8349                            cx,
 8350                        );
 8351                    });
 8352                }
 8353
 8354                (
 8355                    server_id,
 8356                    LanguageServerStatus {
 8357                        name,
 8358                        server_version: None,
 8359                        pending_work: Default::default(),
 8360                        has_pending_diagnostic_updates: false,
 8361                        progress_tokens: Default::default(),
 8362                        worktree,
 8363                        binary: None,
 8364                        configuration: None,
 8365                        workspace_folders: BTreeSet::new(),
 8366                    },
 8367                )
 8368            })
 8369            .collect();
 8370    }
 8371
 8372    #[cfg(test)]
 8373    pub fn update_diagnostic_entries(
 8374        &mut self,
 8375        server_id: LanguageServerId,
 8376        abs_path: PathBuf,
 8377        result_id: Option<SharedString>,
 8378        version: Option<i32>,
 8379        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8380        cx: &mut Context<Self>,
 8381    ) -> anyhow::Result<()> {
 8382        self.merge_diagnostic_entries(
 8383            vec![DocumentDiagnosticsUpdate {
 8384                diagnostics: DocumentDiagnostics {
 8385                    diagnostics,
 8386                    document_abs_path: abs_path,
 8387                    version,
 8388                },
 8389                result_id,
 8390                server_id,
 8391                disk_based_sources: Cow::Borrowed(&[]),
 8392                registration_id: None,
 8393            }],
 8394            |_, _, _| false,
 8395            cx,
 8396        )?;
 8397        Ok(())
 8398    }
 8399
 8400    pub fn merge_diagnostic_entries<'a>(
 8401        &mut self,
 8402        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8403        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8404        cx: &mut Context<Self>,
 8405    ) -> anyhow::Result<()> {
 8406        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8407        let mut updated_diagnostics_paths = HashMap::default();
 8408        for mut update in diagnostic_updates {
 8409            let abs_path = &update.diagnostics.document_abs_path;
 8410            let server_id = update.server_id;
 8411            let Some((worktree, relative_path)) =
 8412                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8413            else {
 8414                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8415                return Ok(());
 8416            };
 8417
 8418            let worktree_id = worktree.read(cx).id();
 8419            let project_path = ProjectPath {
 8420                worktree_id,
 8421                path: relative_path,
 8422            };
 8423
 8424            let document_uri = lsp::Uri::from_file_path(abs_path)
 8425                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8426            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8427                let snapshot = buffer_handle.read(cx).snapshot();
 8428                let buffer = buffer_handle.read(cx);
 8429                let reused_diagnostics = buffer
 8430                    .buffer_diagnostics(Some(server_id))
 8431                    .iter()
 8432                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8433                    .map(|v| {
 8434                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8435                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8436                        DiagnosticEntry {
 8437                            range: start..end,
 8438                            diagnostic: v.diagnostic.clone(),
 8439                        }
 8440                    })
 8441                    .collect::<Vec<_>>();
 8442
 8443                self.as_local_mut()
 8444                    .context("cannot merge diagnostics on a remote LspStore")?
 8445                    .update_buffer_diagnostics(
 8446                        &buffer_handle,
 8447                        server_id,
 8448                        Some(update.registration_id),
 8449                        update.result_id,
 8450                        update.diagnostics.version,
 8451                        update.diagnostics.diagnostics.clone(),
 8452                        reused_diagnostics.clone(),
 8453                        cx,
 8454                    )?;
 8455
 8456                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8457            } else if let Some(local) = self.as_local() {
 8458                let reused_diagnostics = local
 8459                    .diagnostics
 8460                    .get(&worktree_id)
 8461                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8462                    .and_then(|diagnostics_by_server_id| {
 8463                        diagnostics_by_server_id
 8464                            .binary_search_by_key(&server_id, |e| e.0)
 8465                            .ok()
 8466                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8467                    })
 8468                    .into_iter()
 8469                    .flatten()
 8470                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8471
 8472                update
 8473                    .diagnostics
 8474                    .diagnostics
 8475                    .extend(reused_diagnostics.cloned());
 8476            }
 8477
 8478            let updated = worktree.update(cx, |worktree, cx| {
 8479                self.update_worktree_diagnostics(
 8480                    worktree.id(),
 8481                    server_id,
 8482                    project_path.path.clone(),
 8483                    update.diagnostics.diagnostics,
 8484                    cx,
 8485                )
 8486            })?;
 8487            match updated {
 8488                ControlFlow::Continue(new_summary) => {
 8489                    if let Some((project_id, new_summary)) = new_summary {
 8490                        match &mut diagnostics_summary {
 8491                            Some(diagnostics_summary) => {
 8492                                diagnostics_summary
 8493                                    .more_summaries
 8494                                    .push(proto::DiagnosticSummary {
 8495                                        path: project_path.path.as_ref().to_proto(),
 8496                                        language_server_id: server_id.0 as u64,
 8497                                        error_count: new_summary.error_count,
 8498                                        warning_count: new_summary.warning_count,
 8499                                    })
 8500                            }
 8501                            None => {
 8502                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8503                                    project_id,
 8504                                    worktree_id: worktree_id.to_proto(),
 8505                                    summary: Some(proto::DiagnosticSummary {
 8506                                        path: project_path.path.as_ref().to_proto(),
 8507                                        language_server_id: server_id.0 as u64,
 8508                                        error_count: new_summary.error_count,
 8509                                        warning_count: new_summary.warning_count,
 8510                                    }),
 8511                                    more_summaries: Vec::new(),
 8512                                })
 8513                            }
 8514                        }
 8515                    }
 8516                    updated_diagnostics_paths
 8517                        .entry(server_id)
 8518                        .or_insert_with(Vec::new)
 8519                        .push(project_path);
 8520                }
 8521                ControlFlow::Break(()) => {}
 8522            }
 8523        }
 8524
 8525        if let Some((diagnostics_summary, (downstream_client, _))) =
 8526            diagnostics_summary.zip(self.downstream_client.as_ref())
 8527        {
 8528            downstream_client.send(diagnostics_summary).log_err();
 8529        }
 8530        for (server_id, paths) in updated_diagnostics_paths {
 8531            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8532        }
 8533        Ok(())
 8534    }
 8535
 8536    fn update_worktree_diagnostics(
 8537        &mut self,
 8538        worktree_id: WorktreeId,
 8539        server_id: LanguageServerId,
 8540        path_in_worktree: Arc<RelPath>,
 8541        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8542        _: &mut Context<Worktree>,
 8543    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8544        let local = match &mut self.mode {
 8545            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8546            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8547        };
 8548
 8549        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8550        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8551        let summaries_by_server_id = summaries_for_tree
 8552            .entry(path_in_worktree.clone())
 8553            .or_default();
 8554
 8555        let old_summary = summaries_by_server_id
 8556            .remove(&server_id)
 8557            .unwrap_or_default();
 8558
 8559        let new_summary = DiagnosticSummary::new(&diagnostics);
 8560        if diagnostics.is_empty() {
 8561            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8562            {
 8563                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8564                    diagnostics_by_server_id.remove(ix);
 8565                }
 8566                if diagnostics_by_server_id.is_empty() {
 8567                    diagnostics_for_tree.remove(&path_in_worktree);
 8568                }
 8569            }
 8570        } else {
 8571            summaries_by_server_id.insert(server_id, new_summary);
 8572            let diagnostics_by_server_id = diagnostics_for_tree
 8573                .entry(path_in_worktree.clone())
 8574                .or_default();
 8575            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8576                Ok(ix) => {
 8577                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8578                }
 8579                Err(ix) => {
 8580                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8581                }
 8582            }
 8583        }
 8584
 8585        if !old_summary.is_empty() || !new_summary.is_empty() {
 8586            if let Some((_, project_id)) = &self.downstream_client {
 8587                Ok(ControlFlow::Continue(Some((
 8588                    *project_id,
 8589                    proto::DiagnosticSummary {
 8590                        path: path_in_worktree.to_proto(),
 8591                        language_server_id: server_id.0 as u64,
 8592                        error_count: new_summary.error_count as u32,
 8593                        warning_count: new_summary.warning_count as u32,
 8594                    },
 8595                ))))
 8596            } else {
 8597                Ok(ControlFlow::Continue(None))
 8598            }
 8599        } else {
 8600            Ok(ControlFlow::Break(()))
 8601        }
 8602    }
 8603
 8604    pub fn open_buffer_for_symbol(
 8605        &mut self,
 8606        symbol: &Symbol,
 8607        cx: &mut Context<Self>,
 8608    ) -> Task<Result<Entity<Buffer>>> {
 8609        if let Some((client, project_id)) = self.upstream_client() {
 8610            let request = client.request(proto::OpenBufferForSymbol {
 8611                project_id,
 8612                symbol: Some(Self::serialize_symbol(symbol)),
 8613            });
 8614            cx.spawn(async move |this, cx| {
 8615                let response = request.await?;
 8616                let buffer_id = BufferId::new(response.buffer_id)?;
 8617                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8618                    .await
 8619            })
 8620        } else if let Some(local) = self.as_local() {
 8621            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8622                seed.worktree_id == symbol.source_worktree_id
 8623                    && state.id == symbol.source_language_server_id
 8624                    && symbol.language_server_name == seed.name
 8625            });
 8626            if !is_valid {
 8627                return Task::ready(Err(anyhow!(
 8628                    "language server for worktree and language not found"
 8629                )));
 8630            };
 8631
 8632            let symbol_abs_path = match &symbol.path {
 8633                SymbolLocation::InProject(project_path) => self
 8634                    .worktree_store
 8635                    .read(cx)
 8636                    .absolutize(&project_path, cx)
 8637                    .context("no such worktree"),
 8638                SymbolLocation::OutsideProject {
 8639                    abs_path,
 8640                    signature: _,
 8641                } => Ok(abs_path.to_path_buf()),
 8642            };
 8643            let symbol_abs_path = match symbol_abs_path {
 8644                Ok(abs_path) => abs_path,
 8645                Err(err) => return Task::ready(Err(err)),
 8646            };
 8647            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8648                uri
 8649            } else {
 8650                return Task::ready(Err(anyhow!("invalid symbol path")));
 8651            };
 8652
 8653            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8654        } else {
 8655            Task::ready(Err(anyhow!("no upstream client or local store")))
 8656        }
 8657    }
 8658
 8659    pub(crate) fn open_local_buffer_via_lsp(
 8660        &mut self,
 8661        abs_path: lsp::Uri,
 8662        language_server_id: LanguageServerId,
 8663        cx: &mut Context<Self>,
 8664    ) -> Task<Result<Entity<Buffer>>> {
 8665        cx.spawn(async move |lsp_store, cx| {
 8666            // Escape percent-encoded string.
 8667            let current_scheme = abs_path.scheme().to_owned();
 8668            // Uri is immutable, so we can't modify the scheme
 8669
 8670            let abs_path = abs_path
 8671                .to_file_path()
 8672                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8673            let p = abs_path.clone();
 8674            let yarn_worktree = lsp_store
 8675                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8676                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8677                        cx.spawn(async move |this, cx| {
 8678                            let t = this
 8679                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8680                                .ok()?;
 8681                            t.await
 8682                        })
 8683                    }),
 8684                    None => Task::ready(None),
 8685                })?
 8686                .await;
 8687            let (worktree_root_target, known_relative_path) =
 8688                if let Some((zip_root, relative_path)) = yarn_worktree {
 8689                    (zip_root, Some(relative_path))
 8690                } else {
 8691                    (Arc::<Path>::from(abs_path.as_path()), None)
 8692                };
 8693            let (worktree, relative_path) = if let Some(result) =
 8694                lsp_store.update(cx, |lsp_store, cx| {
 8695                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8696                        worktree_store.find_worktree(&worktree_root_target, cx)
 8697                    })
 8698                })? {
 8699                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8700                (result.0, relative_path)
 8701            } else {
 8702                let worktree = lsp_store
 8703                    .update(cx, |lsp_store, cx| {
 8704                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8705                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8706                        })
 8707                    })?
 8708                    .await?;
 8709                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8710                    lsp_store
 8711                        .update(cx, |lsp_store, cx| {
 8712                            if let Some(local) = lsp_store.as_local_mut() {
 8713                                local.register_language_server_for_invisible_worktree(
 8714                                    &worktree,
 8715                                    language_server_id,
 8716                                    cx,
 8717                                )
 8718                            }
 8719                        })
 8720                        .ok();
 8721                }
 8722                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8723                let relative_path = if let Some(known_path) = known_relative_path {
 8724                    known_path
 8725                } else {
 8726                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8727                        .into_arc()
 8728                };
 8729                (worktree, relative_path)
 8730            };
 8731            let project_path = ProjectPath {
 8732                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8733                path: relative_path,
 8734            };
 8735            lsp_store
 8736                .update(cx, |lsp_store, cx| {
 8737                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8738                        buffer_store.open_buffer(project_path, cx)
 8739                    })
 8740                })?
 8741                .await
 8742        })
 8743    }
 8744
 8745    fn request_multiple_lsp_locally<P, R>(
 8746        &mut self,
 8747        buffer: &Entity<Buffer>,
 8748        position: Option<P>,
 8749        request: R,
 8750        cx: &mut Context<Self>,
 8751    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8752    where
 8753        P: ToOffset,
 8754        R: LspCommand + Clone,
 8755        <R::LspRequest as lsp::request::Request>::Result: Send,
 8756        <R::LspRequest as lsp::request::Request>::Params: Send,
 8757    {
 8758        let Some(local) = self.as_local() else {
 8759            return Task::ready(Vec::new());
 8760        };
 8761
 8762        let snapshot = buffer.read(cx).snapshot();
 8763        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8764
 8765        let server_ids = buffer.update(cx, |buffer, cx| {
 8766            local
 8767                .language_servers_for_buffer(buffer, cx)
 8768                .filter(|(adapter, _)| {
 8769                    scope
 8770                        .as_ref()
 8771                        .map(|scope| scope.language_allowed(&adapter.name))
 8772                        .unwrap_or(true)
 8773                })
 8774                .map(|(_, server)| server.server_id())
 8775                .filter(|server_id| {
 8776                    self.as_local().is_none_or(|local| {
 8777                        local
 8778                            .buffers_opened_in_servers
 8779                            .get(&snapshot.remote_id())
 8780                            .is_some_and(|servers| servers.contains(server_id))
 8781                    })
 8782                })
 8783                .collect::<Vec<_>>()
 8784        });
 8785
 8786        let mut response_results = server_ids
 8787            .into_iter()
 8788            .map(|server_id| {
 8789                let task = self.request_lsp(
 8790                    buffer.clone(),
 8791                    LanguageServerToQuery::Other(server_id),
 8792                    request.clone(),
 8793                    cx,
 8794                );
 8795                async move { (server_id, task.await) }
 8796            })
 8797            .collect::<FuturesUnordered<_>>();
 8798
 8799        cx.background_spawn(async move {
 8800            let mut responses = Vec::with_capacity(response_results.len());
 8801            while let Some((server_id, response_result)) = response_results.next().await {
 8802                match response_result {
 8803                    Ok(response) => responses.push((server_id, response)),
 8804                    // rust-analyzer likes to error with this when its still loading up
 8805                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8806                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8807                }
 8808            }
 8809            responses
 8810        })
 8811    }
 8812
 8813    async fn handle_lsp_get_completions(
 8814        this: Entity<Self>,
 8815        envelope: TypedEnvelope<proto::GetCompletions>,
 8816        mut cx: AsyncApp,
 8817    ) -> Result<proto::GetCompletionsResponse> {
 8818        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8819
 8820        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8821        let buffer_handle = this.update(&mut cx, |this, cx| {
 8822            this.buffer_store.read(cx).get_existing(buffer_id)
 8823        })??;
 8824        let request = GetCompletions::from_proto(
 8825            envelope.payload,
 8826            this.clone(),
 8827            buffer_handle.clone(),
 8828            cx.clone(),
 8829        )
 8830        .await?;
 8831
 8832        let server_to_query = match request.server_id {
 8833            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8834            None => LanguageServerToQuery::FirstCapable,
 8835        };
 8836
 8837        let response = this
 8838            .update(&mut cx, |this, cx| {
 8839                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8840            })?
 8841            .await?;
 8842        this.update(&mut cx, |this, cx| {
 8843            Ok(GetCompletions::response_to_proto(
 8844                response,
 8845                this,
 8846                sender_id,
 8847                &buffer_handle.read(cx).version(),
 8848                cx,
 8849            ))
 8850        })?
 8851    }
 8852
 8853    async fn handle_lsp_command<T: LspCommand>(
 8854        this: Entity<Self>,
 8855        envelope: TypedEnvelope<T::ProtoRequest>,
 8856        mut cx: AsyncApp,
 8857    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8858    where
 8859        <T::LspRequest as lsp::request::Request>::Params: Send,
 8860        <T::LspRequest as lsp::request::Request>::Result: Send,
 8861    {
 8862        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8863        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8864        let buffer_handle = this.update(&mut cx, |this, cx| {
 8865            this.buffer_store.read(cx).get_existing(buffer_id)
 8866        })??;
 8867        let request = T::from_proto(
 8868            envelope.payload,
 8869            this.clone(),
 8870            buffer_handle.clone(),
 8871            cx.clone(),
 8872        )
 8873        .await?;
 8874        let response = this
 8875            .update(&mut cx, |this, cx| {
 8876                this.request_lsp(
 8877                    buffer_handle.clone(),
 8878                    LanguageServerToQuery::FirstCapable,
 8879                    request,
 8880                    cx,
 8881                )
 8882            })?
 8883            .await?;
 8884        this.update(&mut cx, |this, cx| {
 8885            Ok(T::response_to_proto(
 8886                response,
 8887                this,
 8888                sender_id,
 8889                &buffer_handle.read(cx).version(),
 8890                cx,
 8891            ))
 8892        })?
 8893    }
 8894
 8895    async fn handle_lsp_query(
 8896        lsp_store: Entity<Self>,
 8897        envelope: TypedEnvelope<proto::LspQuery>,
 8898        mut cx: AsyncApp,
 8899    ) -> Result<proto::Ack> {
 8900        use proto::lsp_query::Request;
 8901        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8902        let lsp_query = envelope.payload;
 8903        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8904        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8905        match lsp_query.request.context("invalid LSP query request")? {
 8906            Request::GetReferences(get_references) => {
 8907                let position = get_references.position.clone().and_then(deserialize_anchor);
 8908                Self::query_lsp_locally::<GetReferences>(
 8909                    lsp_store,
 8910                    server_id,
 8911                    sender_id,
 8912                    lsp_request_id,
 8913                    get_references,
 8914                    position,
 8915                    &mut cx,
 8916                )
 8917                .await?;
 8918            }
 8919            Request::GetDocumentColor(get_document_color) => {
 8920                Self::query_lsp_locally::<GetDocumentColor>(
 8921                    lsp_store,
 8922                    server_id,
 8923                    sender_id,
 8924                    lsp_request_id,
 8925                    get_document_color,
 8926                    None,
 8927                    &mut cx,
 8928                )
 8929                .await?;
 8930            }
 8931            Request::GetHover(get_hover) => {
 8932                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8933                Self::query_lsp_locally::<GetHover>(
 8934                    lsp_store,
 8935                    server_id,
 8936                    sender_id,
 8937                    lsp_request_id,
 8938                    get_hover,
 8939                    position,
 8940                    &mut cx,
 8941                )
 8942                .await?;
 8943            }
 8944            Request::GetCodeActions(get_code_actions) => {
 8945                Self::query_lsp_locally::<GetCodeActions>(
 8946                    lsp_store,
 8947                    server_id,
 8948                    sender_id,
 8949                    lsp_request_id,
 8950                    get_code_actions,
 8951                    None,
 8952                    &mut cx,
 8953                )
 8954                .await?;
 8955            }
 8956            Request::GetSignatureHelp(get_signature_help) => {
 8957                let position = get_signature_help
 8958                    .position
 8959                    .clone()
 8960                    .and_then(deserialize_anchor);
 8961                Self::query_lsp_locally::<GetSignatureHelp>(
 8962                    lsp_store,
 8963                    server_id,
 8964                    sender_id,
 8965                    lsp_request_id,
 8966                    get_signature_help,
 8967                    position,
 8968                    &mut cx,
 8969                )
 8970                .await?;
 8971            }
 8972            Request::GetCodeLens(get_code_lens) => {
 8973                Self::query_lsp_locally::<GetCodeLens>(
 8974                    lsp_store,
 8975                    server_id,
 8976                    sender_id,
 8977                    lsp_request_id,
 8978                    get_code_lens,
 8979                    None,
 8980                    &mut cx,
 8981                )
 8982                .await?;
 8983            }
 8984            Request::GetDefinition(get_definition) => {
 8985                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8986                Self::query_lsp_locally::<GetDefinitions>(
 8987                    lsp_store,
 8988                    server_id,
 8989                    sender_id,
 8990                    lsp_request_id,
 8991                    get_definition,
 8992                    position,
 8993                    &mut cx,
 8994                )
 8995                .await?;
 8996            }
 8997            Request::GetDeclaration(get_declaration) => {
 8998                let position = get_declaration
 8999                    .position
 9000                    .clone()
 9001                    .and_then(deserialize_anchor);
 9002                Self::query_lsp_locally::<GetDeclarations>(
 9003                    lsp_store,
 9004                    server_id,
 9005                    sender_id,
 9006                    lsp_request_id,
 9007                    get_declaration,
 9008                    position,
 9009                    &mut cx,
 9010                )
 9011                .await?;
 9012            }
 9013            Request::GetTypeDefinition(get_type_definition) => {
 9014                let position = get_type_definition
 9015                    .position
 9016                    .clone()
 9017                    .and_then(deserialize_anchor);
 9018                Self::query_lsp_locally::<GetTypeDefinitions>(
 9019                    lsp_store,
 9020                    server_id,
 9021                    sender_id,
 9022                    lsp_request_id,
 9023                    get_type_definition,
 9024                    position,
 9025                    &mut cx,
 9026                )
 9027                .await?;
 9028            }
 9029            Request::GetImplementation(get_implementation) => {
 9030                let position = get_implementation
 9031                    .position
 9032                    .clone()
 9033                    .and_then(deserialize_anchor);
 9034                Self::query_lsp_locally::<GetImplementations>(
 9035                    lsp_store,
 9036                    server_id,
 9037                    sender_id,
 9038                    lsp_request_id,
 9039                    get_implementation,
 9040                    position,
 9041                    &mut cx,
 9042                )
 9043                .await?;
 9044            }
 9045            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9046                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9047                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9048                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9049                    this.buffer_store.read(cx).get_existing(buffer_id)
 9050                })??;
 9051                buffer
 9052                    .update(&mut cx, |buffer, _| {
 9053                        buffer.wait_for_version(version.clone())
 9054                    })?
 9055                    .await?;
 9056                lsp_store.update(&mut cx, |lsp_store, cx| {
 9057                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9058                    let key = LspKey {
 9059                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9060                        server_queried: server_id,
 9061                    };
 9062                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9063                    ) {
 9064                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9065                            lsp_requests.clear();
 9066                        };
 9067                    }
 9068
 9069                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9070                    existing_queries.insert(
 9071                        lsp_request_id,
 9072                        cx.spawn(async move |lsp_store, cx| {
 9073                            let diagnostics_pull = lsp_store
 9074                                .update(cx, |lsp_store, cx| {
 9075                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9076                                })
 9077                                .ok();
 9078                            if let Some(diagnostics_pull) = diagnostics_pull {
 9079                                match diagnostics_pull.await {
 9080                                    Ok(()) => {}
 9081                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9082                                };
 9083                            }
 9084                        }),
 9085                    );
 9086                })?;
 9087            }
 9088            Request::InlayHints(inlay_hints) => {
 9089                let query_start = inlay_hints
 9090                    .start
 9091                    .clone()
 9092                    .and_then(deserialize_anchor)
 9093                    .context("invalid inlay hints range start")?;
 9094                let query_end = inlay_hints
 9095                    .end
 9096                    .clone()
 9097                    .and_then(deserialize_anchor)
 9098                    .context("invalid inlay hints range end")?;
 9099                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9100                    &lsp_store,
 9101                    server_id,
 9102                    lsp_request_id,
 9103                    &inlay_hints,
 9104                    query_start..query_end,
 9105                    &mut cx,
 9106                )
 9107                .await
 9108                .context("preparing inlay hints request")?;
 9109                Self::query_lsp_locally::<InlayHints>(
 9110                    lsp_store,
 9111                    server_id,
 9112                    sender_id,
 9113                    lsp_request_id,
 9114                    inlay_hints,
 9115                    None,
 9116                    &mut cx,
 9117                )
 9118                .await
 9119                .context("querying for inlay hints")?
 9120            }
 9121        }
 9122        Ok(proto::Ack {})
 9123    }
 9124
 9125    async fn handle_lsp_query_response(
 9126        lsp_store: Entity<Self>,
 9127        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9128        cx: AsyncApp,
 9129    ) -> Result<()> {
 9130        lsp_store.read_with(&cx, |lsp_store, _| {
 9131            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9132                upstream_client.handle_lsp_response(envelope.clone());
 9133            }
 9134        })?;
 9135        Ok(())
 9136    }
 9137
 9138    async fn handle_apply_code_action(
 9139        this: Entity<Self>,
 9140        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9141        mut cx: AsyncApp,
 9142    ) -> Result<proto::ApplyCodeActionResponse> {
 9143        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9144        let action =
 9145            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9146        let apply_code_action = this.update(&mut cx, |this, cx| {
 9147            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9148            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9149            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9150        })??;
 9151
 9152        let project_transaction = apply_code_action.await?;
 9153        let project_transaction = this.update(&mut cx, |this, cx| {
 9154            this.buffer_store.update(cx, |buffer_store, cx| {
 9155                buffer_store.serialize_project_transaction_for_peer(
 9156                    project_transaction,
 9157                    sender_id,
 9158                    cx,
 9159                )
 9160            })
 9161        })?;
 9162        Ok(proto::ApplyCodeActionResponse {
 9163            transaction: Some(project_transaction),
 9164        })
 9165    }
 9166
 9167    async fn handle_register_buffer_with_language_servers(
 9168        this: Entity<Self>,
 9169        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9170        mut cx: AsyncApp,
 9171    ) -> Result<proto::Ack> {
 9172        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9173        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9174        this.update(&mut cx, |this, cx| {
 9175            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9176                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9177                    project_id: upstream_project_id,
 9178                    buffer_id: buffer_id.to_proto(),
 9179                    only_servers: envelope.payload.only_servers,
 9180                });
 9181            }
 9182
 9183            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9184                anyhow::bail!("buffer is not open");
 9185            };
 9186
 9187            let handle = this.register_buffer_with_language_servers(
 9188                &buffer,
 9189                envelope
 9190                    .payload
 9191                    .only_servers
 9192                    .into_iter()
 9193                    .filter_map(|selector| {
 9194                        Some(match selector.selector? {
 9195                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9196                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9197                            }
 9198                            proto::language_server_selector::Selector::Name(name) => {
 9199                                LanguageServerSelector::Name(LanguageServerName(
 9200                                    SharedString::from(name),
 9201                                ))
 9202                            }
 9203                        })
 9204                    })
 9205                    .collect(),
 9206                false,
 9207                cx,
 9208            );
 9209            this.buffer_store().update(cx, |buffer_store, _| {
 9210                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9211            });
 9212
 9213            Ok(())
 9214        })??;
 9215        Ok(proto::Ack {})
 9216    }
 9217
 9218    async fn handle_rename_project_entry(
 9219        this: Entity<Self>,
 9220        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9221        mut cx: AsyncApp,
 9222    ) -> Result<proto::ProjectEntryResponse> {
 9223        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9224        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9225        let new_path =
 9226            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9227
 9228        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9229            .update(&mut cx, |this, cx| {
 9230                let (worktree, entry) = this
 9231                    .worktree_store
 9232                    .read(cx)
 9233                    .worktree_and_entry_for_id(entry_id, cx)?;
 9234                let new_worktree = this
 9235                    .worktree_store
 9236                    .read(cx)
 9237                    .worktree_for_id(new_worktree_id, cx)?;
 9238                Some((
 9239                    this.worktree_store.clone(),
 9240                    worktree,
 9241                    new_worktree,
 9242                    entry.clone(),
 9243                ))
 9244            })?
 9245            .context("worktree not found")?;
 9246        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9247            (worktree.absolutize(&old_entry.path), worktree.id())
 9248        })?;
 9249        let new_abs_path =
 9250            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9251
 9252        let _transaction = Self::will_rename_entry(
 9253            this.downgrade(),
 9254            old_worktree_id,
 9255            &old_abs_path,
 9256            &new_abs_path,
 9257            old_entry.is_dir(),
 9258            cx.clone(),
 9259        )
 9260        .await;
 9261        let response = WorktreeStore::handle_rename_project_entry(
 9262            worktree_store,
 9263            envelope.payload,
 9264            cx.clone(),
 9265        )
 9266        .await;
 9267        this.read_with(&cx, |this, _| {
 9268            this.did_rename_entry(
 9269                old_worktree_id,
 9270                &old_abs_path,
 9271                &new_abs_path,
 9272                old_entry.is_dir(),
 9273            );
 9274        })
 9275        .ok();
 9276        response
 9277    }
 9278
 9279    async fn handle_update_diagnostic_summary(
 9280        this: Entity<Self>,
 9281        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9282        mut cx: AsyncApp,
 9283    ) -> Result<()> {
 9284        this.update(&mut cx, |lsp_store, cx| {
 9285            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9286            let mut updated_diagnostics_paths = HashMap::default();
 9287            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9288            for message_summary in envelope
 9289                .payload
 9290                .summary
 9291                .into_iter()
 9292                .chain(envelope.payload.more_summaries)
 9293            {
 9294                let project_path = ProjectPath {
 9295                    worktree_id,
 9296                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9297                };
 9298                let path = project_path.path.clone();
 9299                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9300                let summary = DiagnosticSummary {
 9301                    error_count: message_summary.error_count as usize,
 9302                    warning_count: message_summary.warning_count as usize,
 9303                };
 9304
 9305                if summary.is_empty() {
 9306                    if let Some(worktree_summaries) =
 9307                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9308                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9309                    {
 9310                        summaries.remove(&server_id);
 9311                        if summaries.is_empty() {
 9312                            worktree_summaries.remove(&path);
 9313                        }
 9314                    }
 9315                } else {
 9316                    lsp_store
 9317                        .diagnostic_summaries
 9318                        .entry(worktree_id)
 9319                        .or_default()
 9320                        .entry(path)
 9321                        .or_default()
 9322                        .insert(server_id, summary);
 9323                }
 9324
 9325                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9326                    match &mut diagnostics_summary {
 9327                        Some(diagnostics_summary) => {
 9328                            diagnostics_summary
 9329                                .more_summaries
 9330                                .push(proto::DiagnosticSummary {
 9331                                    path: project_path.path.as_ref().to_proto(),
 9332                                    language_server_id: server_id.0 as u64,
 9333                                    error_count: summary.error_count as u32,
 9334                                    warning_count: summary.warning_count as u32,
 9335                                })
 9336                        }
 9337                        None => {
 9338                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9339                                project_id: *project_id,
 9340                                worktree_id: worktree_id.to_proto(),
 9341                                summary: Some(proto::DiagnosticSummary {
 9342                                    path: project_path.path.as_ref().to_proto(),
 9343                                    language_server_id: server_id.0 as u64,
 9344                                    error_count: summary.error_count as u32,
 9345                                    warning_count: summary.warning_count as u32,
 9346                                }),
 9347                                more_summaries: Vec::new(),
 9348                            })
 9349                        }
 9350                    }
 9351                }
 9352                updated_diagnostics_paths
 9353                    .entry(server_id)
 9354                    .or_insert_with(Vec::new)
 9355                    .push(project_path);
 9356            }
 9357
 9358            if let Some((diagnostics_summary, (downstream_client, _))) =
 9359                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9360            {
 9361                downstream_client.send(diagnostics_summary).log_err();
 9362            }
 9363            for (server_id, paths) in updated_diagnostics_paths {
 9364                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9365            }
 9366            Ok(())
 9367        })?
 9368    }
 9369
 9370    async fn handle_start_language_server(
 9371        lsp_store: Entity<Self>,
 9372        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9373        mut cx: AsyncApp,
 9374    ) -> Result<()> {
 9375        let server = envelope.payload.server.context("invalid server")?;
 9376        let server_capabilities =
 9377            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9378                .with_context(|| {
 9379                    format!(
 9380                        "incorrect server capabilities {}",
 9381                        envelope.payload.capabilities
 9382                    )
 9383                })?;
 9384        lsp_store.update(&mut cx, |lsp_store, cx| {
 9385            let server_id = LanguageServerId(server.id as usize);
 9386            let server_name = LanguageServerName::from_proto(server.name.clone());
 9387            lsp_store
 9388                .lsp_server_capabilities
 9389                .insert(server_id, server_capabilities);
 9390            lsp_store.language_server_statuses.insert(
 9391                server_id,
 9392                LanguageServerStatus {
 9393                    name: server_name.clone(),
 9394                    server_version: None,
 9395                    pending_work: Default::default(),
 9396                    has_pending_diagnostic_updates: false,
 9397                    progress_tokens: Default::default(),
 9398                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9399                    binary: None,
 9400                    configuration: None,
 9401                    workspace_folders: BTreeSet::new(),
 9402                },
 9403            );
 9404            cx.emit(LspStoreEvent::LanguageServerAdded(
 9405                server_id,
 9406                server_name,
 9407                server.worktree_id.map(WorktreeId::from_proto),
 9408            ));
 9409            cx.notify();
 9410        })?;
 9411        Ok(())
 9412    }
 9413
 9414    async fn handle_update_language_server(
 9415        lsp_store: Entity<Self>,
 9416        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9417        mut cx: AsyncApp,
 9418    ) -> Result<()> {
 9419        lsp_store.update(&mut cx, |lsp_store, cx| {
 9420            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9421
 9422            match envelope.payload.variant.context("invalid variant")? {
 9423                proto::update_language_server::Variant::WorkStart(payload) => {
 9424                    lsp_store.on_lsp_work_start(
 9425                        language_server_id,
 9426                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9427                            .context("invalid progress token value")?,
 9428                        LanguageServerProgress {
 9429                            title: payload.title,
 9430                            is_disk_based_diagnostics_progress: false,
 9431                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9432                            message: payload.message,
 9433                            percentage: payload.percentage.map(|p| p as usize),
 9434                            last_update_at: cx.background_executor().now(),
 9435                        },
 9436                        cx,
 9437                    );
 9438                }
 9439                proto::update_language_server::Variant::WorkProgress(payload) => {
 9440                    lsp_store.on_lsp_work_progress(
 9441                        language_server_id,
 9442                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9443                            .context("invalid progress token value")?,
 9444                        LanguageServerProgress {
 9445                            title: None,
 9446                            is_disk_based_diagnostics_progress: false,
 9447                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9448                            message: payload.message,
 9449                            percentage: payload.percentage.map(|p| p as usize),
 9450                            last_update_at: cx.background_executor().now(),
 9451                        },
 9452                        cx,
 9453                    );
 9454                }
 9455
 9456                proto::update_language_server::Variant::WorkEnd(payload) => {
 9457                    lsp_store.on_lsp_work_end(
 9458                        language_server_id,
 9459                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9460                            .context("invalid progress token value")?,
 9461                        cx,
 9462                    );
 9463                }
 9464
 9465                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9466                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9467                }
 9468
 9469                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9470                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9471                }
 9472
 9473                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9474                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9475                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9476                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9477                        language_server_id,
 9478                        name: envelope
 9479                            .payload
 9480                            .server_name
 9481                            .map(SharedString::new)
 9482                            .map(LanguageServerName),
 9483                        message: non_lsp,
 9484                    });
 9485                }
 9486            }
 9487
 9488            Ok(())
 9489        })?
 9490    }
 9491
 9492    async fn handle_language_server_log(
 9493        this: Entity<Self>,
 9494        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9495        mut cx: AsyncApp,
 9496    ) -> Result<()> {
 9497        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9498        let log_type = envelope
 9499            .payload
 9500            .log_type
 9501            .map(LanguageServerLogType::from_proto)
 9502            .context("invalid language server log type")?;
 9503
 9504        let message = envelope.payload.message;
 9505
 9506        this.update(&mut cx, |_, cx| {
 9507            cx.emit(LspStoreEvent::LanguageServerLog(
 9508                language_server_id,
 9509                log_type,
 9510                message,
 9511            ));
 9512        })
 9513    }
 9514
 9515    async fn handle_lsp_ext_cancel_flycheck(
 9516        lsp_store: Entity<Self>,
 9517        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9518        cx: AsyncApp,
 9519    ) -> Result<proto::Ack> {
 9520        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9521        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9522            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9523                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9524            } else {
 9525                None
 9526            }
 9527        })?;
 9528        if let Some(task) = task {
 9529            task.context("handling lsp ext cancel flycheck")?;
 9530        }
 9531
 9532        Ok(proto::Ack {})
 9533    }
 9534
 9535    async fn handle_lsp_ext_run_flycheck(
 9536        lsp_store: Entity<Self>,
 9537        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9538        mut cx: AsyncApp,
 9539    ) -> Result<proto::Ack> {
 9540        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9541        lsp_store.update(&mut cx, |lsp_store, cx| {
 9542            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9543                let text_document = if envelope.payload.current_file_only {
 9544                    let buffer_id = envelope
 9545                        .payload
 9546                        .buffer_id
 9547                        .map(|id| BufferId::new(id))
 9548                        .transpose()?;
 9549                    buffer_id
 9550                        .and_then(|buffer_id| {
 9551                            lsp_store
 9552                                .buffer_store()
 9553                                .read(cx)
 9554                                .get(buffer_id)
 9555                                .and_then(|buffer| {
 9556                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9557                                })
 9558                                .map(|path| make_text_document_identifier(&path))
 9559                        })
 9560                        .transpose()?
 9561                } else {
 9562                    None
 9563                };
 9564                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9565                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9566                )?;
 9567            }
 9568            anyhow::Ok(())
 9569        })??;
 9570
 9571        Ok(proto::Ack {})
 9572    }
 9573
 9574    async fn handle_lsp_ext_clear_flycheck(
 9575        lsp_store: Entity<Self>,
 9576        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9577        cx: AsyncApp,
 9578    ) -> Result<proto::Ack> {
 9579        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9580        lsp_store
 9581            .read_with(&cx, |lsp_store, _| {
 9582                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9583                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9584                } else {
 9585                    None
 9586                }
 9587            })
 9588            .context("handling lsp ext clear flycheck")?;
 9589
 9590        Ok(proto::Ack {})
 9591    }
 9592
 9593    pub fn disk_based_diagnostics_started(
 9594        &mut self,
 9595        language_server_id: LanguageServerId,
 9596        cx: &mut Context<Self>,
 9597    ) {
 9598        if let Some(language_server_status) =
 9599            self.language_server_statuses.get_mut(&language_server_id)
 9600        {
 9601            language_server_status.has_pending_diagnostic_updates = true;
 9602        }
 9603
 9604        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9605        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9606            language_server_id,
 9607            name: self
 9608                .language_server_adapter_for_id(language_server_id)
 9609                .map(|adapter| adapter.name()),
 9610            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9611                Default::default(),
 9612            ),
 9613        })
 9614    }
 9615
 9616    pub fn disk_based_diagnostics_finished(
 9617        &mut self,
 9618        language_server_id: LanguageServerId,
 9619        cx: &mut Context<Self>,
 9620    ) {
 9621        if let Some(language_server_status) =
 9622            self.language_server_statuses.get_mut(&language_server_id)
 9623        {
 9624            language_server_status.has_pending_diagnostic_updates = false;
 9625        }
 9626
 9627        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9628        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9629            language_server_id,
 9630            name: self
 9631                .language_server_adapter_for_id(language_server_id)
 9632                .map(|adapter| adapter.name()),
 9633            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9634                Default::default(),
 9635            ),
 9636        })
 9637    }
 9638
 9639    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9640    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9641    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9642    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9643    // the language server might take some time to publish diagnostics.
 9644    fn simulate_disk_based_diagnostics_events_if_needed(
 9645        &mut self,
 9646        language_server_id: LanguageServerId,
 9647        cx: &mut Context<Self>,
 9648    ) {
 9649        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9650
 9651        let Some(LanguageServerState::Running {
 9652            simulate_disk_based_diagnostics_completion,
 9653            adapter,
 9654            ..
 9655        }) = self
 9656            .as_local_mut()
 9657            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9658        else {
 9659            return;
 9660        };
 9661
 9662        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9663            return;
 9664        }
 9665
 9666        let prev_task =
 9667            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9668                cx.background_executor()
 9669                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9670                    .await;
 9671
 9672                this.update(cx, |this, cx| {
 9673                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9674
 9675                    if let Some(LanguageServerState::Running {
 9676                        simulate_disk_based_diagnostics_completion,
 9677                        ..
 9678                    }) = this.as_local_mut().and_then(|local_store| {
 9679                        local_store.language_servers.get_mut(&language_server_id)
 9680                    }) {
 9681                        *simulate_disk_based_diagnostics_completion = None;
 9682                    }
 9683                })
 9684                .ok();
 9685            }));
 9686
 9687        if prev_task.is_none() {
 9688            self.disk_based_diagnostics_started(language_server_id, cx);
 9689        }
 9690    }
 9691
 9692    pub fn language_server_statuses(
 9693        &self,
 9694    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9695        self.language_server_statuses
 9696            .iter()
 9697            .map(|(key, value)| (*key, value))
 9698    }
 9699
 9700    pub(super) fn did_rename_entry(
 9701        &self,
 9702        worktree_id: WorktreeId,
 9703        old_path: &Path,
 9704        new_path: &Path,
 9705        is_dir: bool,
 9706    ) {
 9707        maybe!({
 9708            let local_store = self.as_local()?;
 9709
 9710            let old_uri = lsp::Uri::from_file_path(old_path)
 9711                .ok()
 9712                .map(|uri| uri.to_string())?;
 9713            let new_uri = lsp::Uri::from_file_path(new_path)
 9714                .ok()
 9715                .map(|uri| uri.to_string())?;
 9716
 9717            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9718                let Some(filter) = local_store
 9719                    .language_server_paths_watched_for_rename
 9720                    .get(&language_server.server_id())
 9721                else {
 9722                    continue;
 9723                };
 9724
 9725                if filter.should_send_did_rename(&old_uri, is_dir) {
 9726                    language_server
 9727                        .notify::<DidRenameFiles>(RenameFilesParams {
 9728                            files: vec![FileRename {
 9729                                old_uri: old_uri.clone(),
 9730                                new_uri: new_uri.clone(),
 9731                            }],
 9732                        })
 9733                        .ok();
 9734                }
 9735            }
 9736            Some(())
 9737        });
 9738    }
 9739
 9740    pub(super) fn will_rename_entry(
 9741        this: WeakEntity<Self>,
 9742        worktree_id: WorktreeId,
 9743        old_path: &Path,
 9744        new_path: &Path,
 9745        is_dir: bool,
 9746        cx: AsyncApp,
 9747    ) -> Task<ProjectTransaction> {
 9748        let old_uri = lsp::Uri::from_file_path(old_path)
 9749            .ok()
 9750            .map(|uri| uri.to_string());
 9751        let new_uri = lsp::Uri::from_file_path(new_path)
 9752            .ok()
 9753            .map(|uri| uri.to_string());
 9754        cx.spawn(async move |cx| {
 9755            let mut tasks = vec![];
 9756            this.update(cx, |this, cx| {
 9757                let local_store = this.as_local()?;
 9758                let old_uri = old_uri?;
 9759                let new_uri = new_uri?;
 9760                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9761                    let Some(filter) = local_store
 9762                        .language_server_paths_watched_for_rename
 9763                        .get(&language_server.server_id())
 9764                    else {
 9765                        continue;
 9766                    };
 9767
 9768                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9769                        let apply_edit = cx.spawn({
 9770                            let old_uri = old_uri.clone();
 9771                            let new_uri = new_uri.clone();
 9772                            let language_server = language_server.clone();
 9773                            async move |this, cx| {
 9774                                let edit = language_server
 9775                                    .request::<WillRenameFiles>(RenameFilesParams {
 9776                                        files: vec![FileRename { old_uri, new_uri }],
 9777                                    })
 9778                                    .await
 9779                                    .into_response()
 9780                                    .context("will rename files")
 9781                                    .log_err()
 9782                                    .flatten()?;
 9783
 9784                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9785                                    this.upgrade()?,
 9786                                    edit,
 9787                                    false,
 9788                                    language_server.clone(),
 9789                                    cx,
 9790                                )
 9791                                .await
 9792                                .ok()?;
 9793                                Some(transaction)
 9794                            }
 9795                        });
 9796                        tasks.push(apply_edit);
 9797                    }
 9798                }
 9799                Some(())
 9800            })
 9801            .ok()
 9802            .flatten();
 9803            let mut merged_transaction = ProjectTransaction::default();
 9804            for task in tasks {
 9805                // Await on tasks sequentially so that the order of application of edits is deterministic
 9806                // (at least with regards to the order of registration of language servers)
 9807                if let Some(transaction) = task.await {
 9808                    for (buffer, buffer_transaction) in transaction.0 {
 9809                        merged_transaction.0.insert(buffer, buffer_transaction);
 9810                    }
 9811                }
 9812            }
 9813            merged_transaction
 9814        })
 9815    }
 9816
 9817    fn lsp_notify_abs_paths_changed(
 9818        &mut self,
 9819        server_id: LanguageServerId,
 9820        changes: Vec<PathEvent>,
 9821    ) {
 9822        maybe!({
 9823            let server = self.language_server_for_id(server_id)?;
 9824            let changes = changes
 9825                .into_iter()
 9826                .filter_map(|event| {
 9827                    let typ = match event.kind? {
 9828                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9829                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9830                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9831                    };
 9832                    Some(lsp::FileEvent {
 9833                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9834                        typ,
 9835                    })
 9836                })
 9837                .collect::<Vec<_>>();
 9838            if !changes.is_empty() {
 9839                server
 9840                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9841                        lsp::DidChangeWatchedFilesParams { changes },
 9842                    )
 9843                    .ok();
 9844            }
 9845            Some(())
 9846        });
 9847    }
 9848
 9849    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9850        self.as_local()?.language_server_for_id(id)
 9851    }
 9852
 9853    fn on_lsp_progress(
 9854        &mut self,
 9855        progress_params: lsp::ProgressParams,
 9856        language_server_id: LanguageServerId,
 9857        disk_based_diagnostics_progress_token: Option<String>,
 9858        cx: &mut Context<Self>,
 9859    ) {
 9860        match progress_params.value {
 9861            lsp::ProgressParamsValue::WorkDone(progress) => {
 9862                self.handle_work_done_progress(
 9863                    progress,
 9864                    language_server_id,
 9865                    disk_based_diagnostics_progress_token,
 9866                    ProgressToken::from_lsp(progress_params.token),
 9867                    cx,
 9868                );
 9869            }
 9870            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9871                let registration_id = match progress_params.token {
 9872                    lsp::NumberOrString::Number(_) => None,
 9873                    lsp::NumberOrString::String(token) => token
 9874                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9875                        .map(|(_, id)| id.to_owned()),
 9876                };
 9877                if let Some(LanguageServerState::Running {
 9878                    workspace_diagnostics_refresh_tasks,
 9879                    ..
 9880                }) = self
 9881                    .as_local_mut()
 9882                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9883                    && let Some(workspace_diagnostics) =
 9884                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9885                {
 9886                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9887                    self.apply_workspace_diagnostic_report(
 9888                        language_server_id,
 9889                        report,
 9890                        registration_id.map(SharedString::from),
 9891                        cx,
 9892                    )
 9893                }
 9894            }
 9895        }
 9896    }
 9897
 9898    fn handle_work_done_progress(
 9899        &mut self,
 9900        progress: lsp::WorkDoneProgress,
 9901        language_server_id: LanguageServerId,
 9902        disk_based_diagnostics_progress_token: Option<String>,
 9903        token: ProgressToken,
 9904        cx: &mut Context<Self>,
 9905    ) {
 9906        let language_server_status =
 9907            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9908                status
 9909            } else {
 9910                return;
 9911            };
 9912
 9913        if !language_server_status.progress_tokens.contains(&token) {
 9914            return;
 9915        }
 9916
 9917        let is_disk_based_diagnostics_progress =
 9918            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9919                (&disk_based_diagnostics_progress_token, &token)
 9920            {
 9921                token.starts_with(disk_based_token)
 9922            } else {
 9923                false
 9924            };
 9925
 9926        match progress {
 9927            lsp::WorkDoneProgress::Begin(report) => {
 9928                if is_disk_based_diagnostics_progress {
 9929                    self.disk_based_diagnostics_started(language_server_id, cx);
 9930                }
 9931                self.on_lsp_work_start(
 9932                    language_server_id,
 9933                    token.clone(),
 9934                    LanguageServerProgress {
 9935                        title: Some(report.title),
 9936                        is_disk_based_diagnostics_progress,
 9937                        is_cancellable: report.cancellable.unwrap_or(false),
 9938                        message: report.message.clone(),
 9939                        percentage: report.percentage.map(|p| p as usize),
 9940                        last_update_at: cx.background_executor().now(),
 9941                    },
 9942                    cx,
 9943                );
 9944            }
 9945            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9946                language_server_id,
 9947                token,
 9948                LanguageServerProgress {
 9949                    title: None,
 9950                    is_disk_based_diagnostics_progress,
 9951                    is_cancellable: report.cancellable.unwrap_or(false),
 9952                    message: report.message,
 9953                    percentage: report.percentage.map(|p| p as usize),
 9954                    last_update_at: cx.background_executor().now(),
 9955                },
 9956                cx,
 9957            ),
 9958            lsp::WorkDoneProgress::End(_) => {
 9959                language_server_status.progress_tokens.remove(&token);
 9960                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9961                if is_disk_based_diagnostics_progress {
 9962                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9963                }
 9964            }
 9965        }
 9966    }
 9967
 9968    fn on_lsp_work_start(
 9969        &mut self,
 9970        language_server_id: LanguageServerId,
 9971        token: ProgressToken,
 9972        progress: LanguageServerProgress,
 9973        cx: &mut Context<Self>,
 9974    ) {
 9975        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9976            status.pending_work.insert(token.clone(), progress.clone());
 9977            cx.notify();
 9978        }
 9979        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9980            language_server_id,
 9981            name: self
 9982                .language_server_adapter_for_id(language_server_id)
 9983                .map(|adapter| adapter.name()),
 9984            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9985                token: Some(token.to_proto()),
 9986                title: progress.title,
 9987                message: progress.message,
 9988                percentage: progress.percentage.map(|p| p as u32),
 9989                is_cancellable: Some(progress.is_cancellable),
 9990            }),
 9991        })
 9992    }
 9993
 9994    fn on_lsp_work_progress(
 9995        &mut self,
 9996        language_server_id: LanguageServerId,
 9997        token: ProgressToken,
 9998        progress: LanguageServerProgress,
 9999        cx: &mut Context<Self>,
10000    ) {
10001        let mut did_update = false;
10002        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10003            match status.pending_work.entry(token.clone()) {
10004                btree_map::Entry::Vacant(entry) => {
10005                    entry.insert(progress.clone());
10006                    did_update = true;
10007                }
10008                btree_map::Entry::Occupied(mut entry) => {
10009                    let entry = entry.get_mut();
10010                    if (progress.last_update_at - entry.last_update_at)
10011                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10012                    {
10013                        entry.last_update_at = progress.last_update_at;
10014                        if progress.message.is_some() {
10015                            entry.message = progress.message.clone();
10016                        }
10017                        if progress.percentage.is_some() {
10018                            entry.percentage = progress.percentage;
10019                        }
10020                        if progress.is_cancellable != entry.is_cancellable {
10021                            entry.is_cancellable = progress.is_cancellable;
10022                        }
10023                        did_update = true;
10024                    }
10025                }
10026            }
10027        }
10028
10029        if did_update {
10030            cx.emit(LspStoreEvent::LanguageServerUpdate {
10031                language_server_id,
10032                name: self
10033                    .language_server_adapter_for_id(language_server_id)
10034                    .map(|adapter| adapter.name()),
10035                message: proto::update_language_server::Variant::WorkProgress(
10036                    proto::LspWorkProgress {
10037                        token: Some(token.to_proto()),
10038                        message: progress.message,
10039                        percentage: progress.percentage.map(|p| p as u32),
10040                        is_cancellable: Some(progress.is_cancellable),
10041                    },
10042                ),
10043            })
10044        }
10045    }
10046
10047    fn on_lsp_work_end(
10048        &mut self,
10049        language_server_id: LanguageServerId,
10050        token: ProgressToken,
10051        cx: &mut Context<Self>,
10052    ) {
10053        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10054            if let Some(work) = status.pending_work.remove(&token)
10055                && !work.is_disk_based_diagnostics_progress
10056            {
10057                cx.emit(LspStoreEvent::RefreshInlayHints {
10058                    server_id: language_server_id,
10059                    request_id: None,
10060                });
10061            }
10062            cx.notify();
10063        }
10064
10065        cx.emit(LspStoreEvent::LanguageServerUpdate {
10066            language_server_id,
10067            name: self
10068                .language_server_adapter_for_id(language_server_id)
10069                .map(|adapter| adapter.name()),
10070            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10071                token: Some(token.to_proto()),
10072            }),
10073        })
10074    }
10075
10076    pub async fn handle_resolve_completion_documentation(
10077        this: Entity<Self>,
10078        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10079        mut cx: AsyncApp,
10080    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10081        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10082
10083        let completion = this
10084            .read_with(&cx, |this, cx| {
10085                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10086                let server = this
10087                    .language_server_for_id(id)
10088                    .with_context(|| format!("No language server {id}"))?;
10089
10090                anyhow::Ok(cx.background_spawn(async move {
10091                    let can_resolve = server
10092                        .capabilities()
10093                        .completion_provider
10094                        .as_ref()
10095                        .and_then(|options| options.resolve_provider)
10096                        .unwrap_or(false);
10097                    if can_resolve {
10098                        server
10099                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10100                            .await
10101                            .into_response()
10102                            .context("resolve completion item")
10103                    } else {
10104                        anyhow::Ok(lsp_completion)
10105                    }
10106                }))
10107            })??
10108            .await?;
10109
10110        let mut documentation_is_markdown = false;
10111        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10112        let documentation = match completion.documentation {
10113            Some(lsp::Documentation::String(text)) => text,
10114
10115            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10116                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10117                value
10118            }
10119
10120            _ => String::new(),
10121        };
10122
10123        // If we have a new buffer_id, that means we're talking to a new client
10124        // and want to check for new text_edits in the completion too.
10125        let mut old_replace_start = None;
10126        let mut old_replace_end = None;
10127        let mut old_insert_start = None;
10128        let mut old_insert_end = None;
10129        let mut new_text = String::default();
10130        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10131            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10132                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10133                anyhow::Ok(buffer.read(cx).snapshot())
10134            })??;
10135
10136            if let Some(text_edit) = completion.text_edit.as_ref() {
10137                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10138
10139                if let Some(mut edit) = edit {
10140                    LineEnding::normalize(&mut edit.new_text);
10141
10142                    new_text = edit.new_text;
10143                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10144                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10145                    if let Some(insert_range) = edit.insert_range {
10146                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10147                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10148                    }
10149                }
10150            }
10151        }
10152
10153        Ok(proto::ResolveCompletionDocumentationResponse {
10154            documentation,
10155            documentation_is_markdown,
10156            old_replace_start,
10157            old_replace_end,
10158            new_text,
10159            lsp_completion,
10160            old_insert_start,
10161            old_insert_end,
10162        })
10163    }
10164
10165    async fn handle_on_type_formatting(
10166        this: Entity<Self>,
10167        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10168        mut cx: AsyncApp,
10169    ) -> Result<proto::OnTypeFormattingResponse> {
10170        let on_type_formatting = this.update(&mut cx, |this, cx| {
10171            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10172            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10173            let position = envelope
10174                .payload
10175                .position
10176                .and_then(deserialize_anchor)
10177                .context("invalid position")?;
10178            anyhow::Ok(this.apply_on_type_formatting(
10179                buffer,
10180                position,
10181                envelope.payload.trigger.clone(),
10182                cx,
10183            ))
10184        })??;
10185
10186        let transaction = on_type_formatting
10187            .await?
10188            .as_ref()
10189            .map(language::proto::serialize_transaction);
10190        Ok(proto::OnTypeFormattingResponse { transaction })
10191    }
10192
10193    async fn handle_refresh_inlay_hints(
10194        lsp_store: Entity<Self>,
10195        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10196        mut cx: AsyncApp,
10197    ) -> Result<proto::Ack> {
10198        lsp_store.update(&mut cx, |_, cx| {
10199            cx.emit(LspStoreEvent::RefreshInlayHints {
10200                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10201                request_id: envelope.payload.request_id.map(|id| id as usize),
10202            });
10203        })?;
10204        Ok(proto::Ack {})
10205    }
10206
10207    async fn handle_pull_workspace_diagnostics(
10208        lsp_store: Entity<Self>,
10209        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10210        mut cx: AsyncApp,
10211    ) -> Result<proto::Ack> {
10212        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10213        lsp_store.update(&mut cx, |lsp_store, _| {
10214            lsp_store.pull_workspace_diagnostics(server_id);
10215        })?;
10216        Ok(proto::Ack {})
10217    }
10218
10219    async fn handle_get_color_presentation(
10220        lsp_store: Entity<Self>,
10221        envelope: TypedEnvelope<proto::GetColorPresentation>,
10222        mut cx: AsyncApp,
10223    ) -> Result<proto::GetColorPresentationResponse> {
10224        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10225        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10226            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10227        })??;
10228
10229        let color = envelope
10230            .payload
10231            .color
10232            .context("invalid color resolve request")?;
10233        let start = color
10234            .lsp_range_start
10235            .context("invalid color resolve request")?;
10236        let end = color
10237            .lsp_range_end
10238            .context("invalid color resolve request")?;
10239
10240        let color = DocumentColor {
10241            lsp_range: lsp::Range {
10242                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10243                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10244            },
10245            color: lsp::Color {
10246                red: color.red,
10247                green: color.green,
10248                blue: color.blue,
10249                alpha: color.alpha,
10250            },
10251            resolved: false,
10252            color_presentations: Vec::new(),
10253        };
10254        let resolved_color = lsp_store
10255            .update(&mut cx, |lsp_store, cx| {
10256                lsp_store.resolve_color_presentation(
10257                    color,
10258                    buffer.clone(),
10259                    LanguageServerId(envelope.payload.server_id as usize),
10260                    cx,
10261                )
10262            })?
10263            .await
10264            .context("resolving color presentation")?;
10265
10266        Ok(proto::GetColorPresentationResponse {
10267            presentations: resolved_color
10268                .color_presentations
10269                .into_iter()
10270                .map(|presentation| proto::ColorPresentation {
10271                    label: presentation.label.to_string(),
10272                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10273                    additional_text_edits: presentation
10274                        .additional_text_edits
10275                        .into_iter()
10276                        .map(serialize_lsp_edit)
10277                        .collect(),
10278                })
10279                .collect(),
10280        })
10281    }
10282
10283    async fn handle_resolve_inlay_hint(
10284        lsp_store: Entity<Self>,
10285        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10286        mut cx: AsyncApp,
10287    ) -> Result<proto::ResolveInlayHintResponse> {
10288        let proto_hint = envelope
10289            .payload
10290            .hint
10291            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10292        let hint = InlayHints::proto_to_project_hint(proto_hint)
10293            .context("resolved proto inlay hint conversion")?;
10294        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10295            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10296            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10297        })??;
10298        let response_hint = lsp_store
10299            .update(&mut cx, |lsp_store, cx| {
10300                lsp_store.resolve_inlay_hint(
10301                    hint,
10302                    buffer,
10303                    LanguageServerId(envelope.payload.language_server_id as usize),
10304                    cx,
10305                )
10306            })?
10307            .await
10308            .context("inlay hints fetch")?;
10309        Ok(proto::ResolveInlayHintResponse {
10310            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10311        })
10312    }
10313
10314    async fn handle_refresh_code_lens(
10315        this: Entity<Self>,
10316        _: TypedEnvelope<proto::RefreshCodeLens>,
10317        mut cx: AsyncApp,
10318    ) -> Result<proto::Ack> {
10319        this.update(&mut cx, |_, cx| {
10320            cx.emit(LspStoreEvent::RefreshCodeLens);
10321        })?;
10322        Ok(proto::Ack {})
10323    }
10324
10325    async fn handle_open_buffer_for_symbol(
10326        this: Entity<Self>,
10327        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10328        mut cx: AsyncApp,
10329    ) -> Result<proto::OpenBufferForSymbolResponse> {
10330        let peer_id = envelope.original_sender_id().unwrap_or_default();
10331        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10332        let symbol = Self::deserialize_symbol(symbol)?;
10333        this.read_with(&cx, |this, _| {
10334            if let SymbolLocation::OutsideProject {
10335                abs_path,
10336                signature,
10337            } = &symbol.path
10338            {
10339                let new_signature = this.symbol_signature(&abs_path);
10340                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10341            }
10342            Ok(())
10343        })??;
10344        let buffer = this
10345            .update(&mut cx, |this, cx| {
10346                this.open_buffer_for_symbol(
10347                    &Symbol {
10348                        language_server_name: symbol.language_server_name,
10349                        source_worktree_id: symbol.source_worktree_id,
10350                        source_language_server_id: symbol.source_language_server_id,
10351                        path: symbol.path,
10352                        name: symbol.name,
10353                        kind: symbol.kind,
10354                        range: symbol.range,
10355                        label: CodeLabel::default(),
10356                    },
10357                    cx,
10358                )
10359            })?
10360            .await?;
10361
10362        this.update(&mut cx, |this, cx| {
10363            let is_private = buffer
10364                .read(cx)
10365                .file()
10366                .map(|f| f.is_private())
10367                .unwrap_or_default();
10368            if is_private {
10369                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10370            } else {
10371                this.buffer_store
10372                    .update(cx, |buffer_store, cx| {
10373                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10374                    })
10375                    .detach_and_log_err(cx);
10376                let buffer_id = buffer.read(cx).remote_id().to_proto();
10377                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10378            }
10379        })?
10380    }
10381
10382    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10383        let mut hasher = Sha256::new();
10384        hasher.update(abs_path.to_string_lossy().as_bytes());
10385        hasher.update(self.nonce.to_be_bytes());
10386        hasher.finalize().as_slice().try_into().unwrap()
10387    }
10388
10389    pub async fn handle_get_project_symbols(
10390        this: Entity<Self>,
10391        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10392        mut cx: AsyncApp,
10393    ) -> Result<proto::GetProjectSymbolsResponse> {
10394        let symbols = this
10395            .update(&mut cx, |this, cx| {
10396                this.symbols(&envelope.payload.query, cx)
10397            })?
10398            .await?;
10399
10400        Ok(proto::GetProjectSymbolsResponse {
10401            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10402        })
10403    }
10404
10405    pub async fn handle_restart_language_servers(
10406        this: Entity<Self>,
10407        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10408        mut cx: AsyncApp,
10409    ) -> Result<proto::Ack> {
10410        this.update(&mut cx, |lsp_store, cx| {
10411            let buffers =
10412                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10413            lsp_store.restart_language_servers_for_buffers(
10414                buffers,
10415                envelope
10416                    .payload
10417                    .only_servers
10418                    .into_iter()
10419                    .filter_map(|selector| {
10420                        Some(match selector.selector? {
10421                            proto::language_server_selector::Selector::ServerId(server_id) => {
10422                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10423                            }
10424                            proto::language_server_selector::Selector::Name(name) => {
10425                                LanguageServerSelector::Name(LanguageServerName(
10426                                    SharedString::from(name),
10427                                ))
10428                            }
10429                        })
10430                    })
10431                    .collect(),
10432                cx,
10433            );
10434        })?;
10435
10436        Ok(proto::Ack {})
10437    }
10438
10439    pub async fn handle_stop_language_servers(
10440        lsp_store: Entity<Self>,
10441        envelope: TypedEnvelope<proto::StopLanguageServers>,
10442        mut cx: AsyncApp,
10443    ) -> Result<proto::Ack> {
10444        lsp_store.update(&mut cx, |lsp_store, cx| {
10445            if envelope.payload.all
10446                && envelope.payload.also_servers.is_empty()
10447                && envelope.payload.buffer_ids.is_empty()
10448            {
10449                lsp_store.stop_all_language_servers(cx);
10450            } else {
10451                let buffers =
10452                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10453                lsp_store
10454                    .stop_language_servers_for_buffers(
10455                        buffers,
10456                        envelope
10457                            .payload
10458                            .also_servers
10459                            .into_iter()
10460                            .filter_map(|selector| {
10461                                Some(match selector.selector? {
10462                                    proto::language_server_selector::Selector::ServerId(
10463                                        server_id,
10464                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10465                                        server_id,
10466                                    )),
10467                                    proto::language_server_selector::Selector::Name(name) => {
10468                                        LanguageServerSelector::Name(LanguageServerName(
10469                                            SharedString::from(name),
10470                                        ))
10471                                    }
10472                                })
10473                            })
10474                            .collect(),
10475                        cx,
10476                    )
10477                    .detach_and_log_err(cx);
10478            }
10479        })?;
10480
10481        Ok(proto::Ack {})
10482    }
10483
10484    pub async fn handle_cancel_language_server_work(
10485        lsp_store: Entity<Self>,
10486        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10487        mut cx: AsyncApp,
10488    ) -> Result<proto::Ack> {
10489        lsp_store.update(&mut cx, |lsp_store, cx| {
10490            if let Some(work) = envelope.payload.work {
10491                match work {
10492                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10493                        let buffers =
10494                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10495                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10496                    }
10497                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10498                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10499                        let token = work
10500                            .token
10501                            .map(|token| {
10502                                ProgressToken::from_proto(token)
10503                                    .context("invalid work progress token")
10504                            })
10505                            .transpose()?;
10506                        lsp_store.cancel_language_server_work(server_id, token, cx);
10507                    }
10508                }
10509            }
10510            anyhow::Ok(())
10511        })??;
10512
10513        Ok(proto::Ack {})
10514    }
10515
10516    fn buffer_ids_to_buffers(
10517        &mut self,
10518        buffer_ids: impl Iterator<Item = u64>,
10519        cx: &mut Context<Self>,
10520    ) -> Vec<Entity<Buffer>> {
10521        buffer_ids
10522            .into_iter()
10523            .flat_map(|buffer_id| {
10524                self.buffer_store
10525                    .read(cx)
10526                    .get(BufferId::new(buffer_id).log_err()?)
10527            })
10528            .collect::<Vec<_>>()
10529    }
10530
10531    async fn handle_apply_additional_edits_for_completion(
10532        this: Entity<Self>,
10533        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10534        mut cx: AsyncApp,
10535    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10536        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10537            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10538            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10539            let completion = Self::deserialize_completion(
10540                envelope.payload.completion.context("invalid completion")?,
10541            )?;
10542            anyhow::Ok((buffer, completion))
10543        })??;
10544
10545        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10546            this.apply_additional_edits_for_completion(
10547                buffer,
10548                Rc::new(RefCell::new(Box::new([Completion {
10549                    replace_range: completion.replace_range,
10550                    new_text: completion.new_text,
10551                    source: completion.source,
10552                    documentation: None,
10553                    label: CodeLabel::default(),
10554                    match_start: None,
10555                    snippet_deduplication_key: None,
10556                    insert_text_mode: None,
10557                    icon_path: None,
10558                    confirm: None,
10559                }]))),
10560                0,
10561                false,
10562                cx,
10563            )
10564        })?;
10565
10566        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10567            transaction: apply_additional_edits
10568                .await?
10569                .as_ref()
10570                .map(language::proto::serialize_transaction),
10571        })
10572    }
10573
10574    pub fn last_formatting_failure(&self) -> Option<&str> {
10575        self.last_formatting_failure.as_deref()
10576    }
10577
10578    pub fn reset_last_formatting_failure(&mut self) {
10579        self.last_formatting_failure = None;
10580    }
10581
10582    pub fn environment_for_buffer(
10583        &self,
10584        buffer: &Entity<Buffer>,
10585        cx: &mut Context<Self>,
10586    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10587        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10588            environment.update(cx, |env, cx| {
10589                env.buffer_environment(buffer, &self.worktree_store, cx)
10590            })
10591        } else {
10592            Task::ready(None).shared()
10593        }
10594    }
10595
10596    pub fn format(
10597        &mut self,
10598        buffers: HashSet<Entity<Buffer>>,
10599        target: LspFormatTarget,
10600        push_to_history: bool,
10601        trigger: FormatTrigger,
10602        cx: &mut Context<Self>,
10603    ) -> Task<anyhow::Result<ProjectTransaction>> {
10604        let logger = zlog::scoped!("format");
10605        if self.as_local().is_some() {
10606            zlog::trace!(logger => "Formatting locally");
10607            let logger = zlog::scoped!(logger => "local");
10608            let buffers = buffers
10609                .into_iter()
10610                .map(|buffer_handle| {
10611                    let buffer = buffer_handle.read(cx);
10612                    let buffer_abs_path = File::from_dyn(buffer.file())
10613                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10614
10615                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10616                })
10617                .collect::<Vec<_>>();
10618
10619            cx.spawn(async move |lsp_store, cx| {
10620                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10621
10622                for (handle, abs_path, id) in buffers {
10623                    let env = lsp_store
10624                        .update(cx, |lsp_store, cx| {
10625                            lsp_store.environment_for_buffer(&handle, cx)
10626                        })?
10627                        .await;
10628
10629                    let ranges = match &target {
10630                        LspFormatTarget::Buffers => None,
10631                        LspFormatTarget::Ranges(ranges) => {
10632                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10633                        }
10634                    };
10635
10636                    formattable_buffers.push(FormattableBuffer {
10637                        handle,
10638                        abs_path,
10639                        env,
10640                        ranges,
10641                    });
10642                }
10643                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10644
10645                let format_timer = zlog::time!(logger => "Formatting buffers");
10646                let result = LocalLspStore::format_locally(
10647                    lsp_store.clone(),
10648                    formattable_buffers,
10649                    push_to_history,
10650                    trigger,
10651                    logger,
10652                    cx,
10653                )
10654                .await;
10655                format_timer.end();
10656
10657                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10658
10659                lsp_store.update(cx, |lsp_store, _| {
10660                    lsp_store.update_last_formatting_failure(&result);
10661                })?;
10662
10663                result
10664            })
10665        } else if let Some((client, project_id)) = self.upstream_client() {
10666            zlog::trace!(logger => "Formatting remotely");
10667            let logger = zlog::scoped!(logger => "remote");
10668            // Don't support formatting ranges via remote
10669            match target {
10670                LspFormatTarget::Buffers => {}
10671                LspFormatTarget::Ranges(_) => {
10672                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10673                    return Task::ready(Ok(ProjectTransaction::default()));
10674                }
10675            }
10676
10677            let buffer_store = self.buffer_store();
10678            cx.spawn(async move |lsp_store, cx| {
10679                zlog::trace!(logger => "Sending remote format request");
10680                let request_timer = zlog::time!(logger => "remote format request");
10681                let result = client
10682                    .request(proto::FormatBuffers {
10683                        project_id,
10684                        trigger: trigger as i32,
10685                        buffer_ids: buffers
10686                            .iter()
10687                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10688                            .collect::<Result<_>>()?,
10689                    })
10690                    .await
10691                    .and_then(|result| result.transaction.context("missing transaction"));
10692                request_timer.end();
10693
10694                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10695
10696                lsp_store.update(cx, |lsp_store, _| {
10697                    lsp_store.update_last_formatting_failure(&result);
10698                })?;
10699
10700                let transaction_response = result?;
10701                let _timer = zlog::time!(logger => "deserializing project transaction");
10702                buffer_store
10703                    .update(cx, |buffer_store, cx| {
10704                        buffer_store.deserialize_project_transaction(
10705                            transaction_response,
10706                            push_to_history,
10707                            cx,
10708                        )
10709                    })?
10710                    .await
10711            })
10712        } else {
10713            zlog::trace!(logger => "Not formatting");
10714            Task::ready(Ok(ProjectTransaction::default()))
10715        }
10716    }
10717
10718    async fn handle_format_buffers(
10719        this: Entity<Self>,
10720        envelope: TypedEnvelope<proto::FormatBuffers>,
10721        mut cx: AsyncApp,
10722    ) -> Result<proto::FormatBuffersResponse> {
10723        let sender_id = envelope.original_sender_id().unwrap_or_default();
10724        let format = this.update(&mut cx, |this, cx| {
10725            let mut buffers = HashSet::default();
10726            for buffer_id in &envelope.payload.buffer_ids {
10727                let buffer_id = BufferId::new(*buffer_id)?;
10728                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10729            }
10730            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10731            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10732        })??;
10733
10734        let project_transaction = format.await?;
10735        let project_transaction = this.update(&mut cx, |this, cx| {
10736            this.buffer_store.update(cx, |buffer_store, cx| {
10737                buffer_store.serialize_project_transaction_for_peer(
10738                    project_transaction,
10739                    sender_id,
10740                    cx,
10741                )
10742            })
10743        })?;
10744        Ok(proto::FormatBuffersResponse {
10745            transaction: Some(project_transaction),
10746        })
10747    }
10748
10749    async fn handle_apply_code_action_kind(
10750        this: Entity<Self>,
10751        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10752        mut cx: AsyncApp,
10753    ) -> Result<proto::ApplyCodeActionKindResponse> {
10754        let sender_id = envelope.original_sender_id().unwrap_or_default();
10755        let format = this.update(&mut cx, |this, cx| {
10756            let mut buffers = HashSet::default();
10757            for buffer_id in &envelope.payload.buffer_ids {
10758                let buffer_id = BufferId::new(*buffer_id)?;
10759                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10760            }
10761            let kind = match envelope.payload.kind.as_str() {
10762                "" => CodeActionKind::EMPTY,
10763                "quickfix" => CodeActionKind::QUICKFIX,
10764                "refactor" => CodeActionKind::REFACTOR,
10765                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10766                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10767                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10768                "source" => CodeActionKind::SOURCE,
10769                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10770                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10771                _ => anyhow::bail!(
10772                    "Invalid code action kind {}",
10773                    envelope.payload.kind.as_str()
10774                ),
10775            };
10776            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10777        })??;
10778
10779        let project_transaction = format.await?;
10780        let project_transaction = this.update(&mut cx, |this, cx| {
10781            this.buffer_store.update(cx, |buffer_store, cx| {
10782                buffer_store.serialize_project_transaction_for_peer(
10783                    project_transaction,
10784                    sender_id,
10785                    cx,
10786                )
10787            })
10788        })?;
10789        Ok(proto::ApplyCodeActionKindResponse {
10790            transaction: Some(project_transaction),
10791        })
10792    }
10793
10794    async fn shutdown_language_server(
10795        server_state: Option<LanguageServerState>,
10796        name: LanguageServerName,
10797        cx: &mut AsyncApp,
10798    ) {
10799        let server = match server_state {
10800            Some(LanguageServerState::Starting { startup, .. }) => {
10801                let mut timer = cx
10802                    .background_executor()
10803                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10804                    .fuse();
10805
10806                select! {
10807                    server = startup.fuse() => server,
10808                    () = timer => {
10809                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10810                        None
10811                    },
10812                }
10813            }
10814
10815            Some(LanguageServerState::Running { server, .. }) => Some(server),
10816
10817            None => None,
10818        };
10819
10820        if let Some(server) = server
10821            && let Some(shutdown) = server.shutdown()
10822        {
10823            shutdown.await;
10824        }
10825    }
10826
10827    // Returns a list of all of the worktrees which no longer have a language server and the root path
10828    // for the stopped server
10829    fn stop_local_language_server(
10830        &mut self,
10831        server_id: LanguageServerId,
10832        cx: &mut Context<Self>,
10833    ) -> Task<()> {
10834        let local = match &mut self.mode {
10835            LspStoreMode::Local(local) => local,
10836            _ => {
10837                return Task::ready(());
10838            }
10839        };
10840
10841        // Remove this server ID from all entries in the given worktree.
10842        local
10843            .language_server_ids
10844            .retain(|_, state| state.id != server_id);
10845        self.buffer_store.update(cx, |buffer_store, cx| {
10846            for buffer in buffer_store.buffers() {
10847                buffer.update(cx, |buffer, cx| {
10848                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10849                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10850                });
10851            }
10852        });
10853
10854        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10855            summaries.retain(|path, summaries_by_server_id| {
10856                if summaries_by_server_id.remove(&server_id).is_some() {
10857                    if let Some((client, project_id)) = self.downstream_client.clone() {
10858                        client
10859                            .send(proto::UpdateDiagnosticSummary {
10860                                project_id,
10861                                worktree_id: worktree_id.to_proto(),
10862                                summary: Some(proto::DiagnosticSummary {
10863                                    path: path.as_ref().to_proto(),
10864                                    language_server_id: server_id.0 as u64,
10865                                    error_count: 0,
10866                                    warning_count: 0,
10867                                }),
10868                                more_summaries: Vec::new(),
10869                            })
10870                            .log_err();
10871                    }
10872                    !summaries_by_server_id.is_empty()
10873                } else {
10874                    true
10875                }
10876            });
10877        }
10878
10879        let local = self.as_local_mut().unwrap();
10880        for diagnostics in local.diagnostics.values_mut() {
10881            diagnostics.retain(|_, diagnostics_by_server_id| {
10882                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10883                    diagnostics_by_server_id.remove(ix);
10884                    !diagnostics_by_server_id.is_empty()
10885                } else {
10886                    true
10887                }
10888            });
10889        }
10890        local.language_server_watched_paths.remove(&server_id);
10891
10892        let server_state = local.language_servers.remove(&server_id);
10893        self.cleanup_lsp_data(server_id);
10894        let name = self
10895            .language_server_statuses
10896            .remove(&server_id)
10897            .map(|status| status.name)
10898            .or_else(|| {
10899                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10900                    Some(adapter.name())
10901                } else {
10902                    None
10903                }
10904            });
10905
10906        if let Some(name) = name {
10907            log::info!("stopping language server {name}");
10908            self.languages
10909                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10910            cx.notify();
10911
10912            return cx.spawn(async move |lsp_store, cx| {
10913                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10914                lsp_store
10915                    .update(cx, |lsp_store, cx| {
10916                        lsp_store
10917                            .languages
10918                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10919                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10920                        cx.notify();
10921                    })
10922                    .ok();
10923            });
10924        }
10925
10926        if server_state.is_some() {
10927            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10928        }
10929        Task::ready(())
10930    }
10931
10932    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10933        if let Some((client, project_id)) = self.upstream_client() {
10934            let request = client.request(proto::StopLanguageServers {
10935                project_id,
10936                buffer_ids: Vec::new(),
10937                also_servers: Vec::new(),
10938                all: true,
10939            });
10940            cx.background_spawn(request).detach_and_log_err(cx);
10941        } else {
10942            let Some(local) = self.as_local_mut() else {
10943                return;
10944            };
10945            let language_servers_to_stop = local
10946                .language_server_ids
10947                .values()
10948                .map(|state| state.id)
10949                .collect();
10950            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10951            let tasks = language_servers_to_stop
10952                .into_iter()
10953                .map(|server| self.stop_local_language_server(server, cx))
10954                .collect::<Vec<_>>();
10955            cx.background_spawn(async move {
10956                futures::future::join_all(tasks).await;
10957            })
10958            .detach();
10959        }
10960    }
10961
10962    pub fn restart_language_servers_for_buffers(
10963        &mut self,
10964        buffers: Vec<Entity<Buffer>>,
10965        only_restart_servers: HashSet<LanguageServerSelector>,
10966        cx: &mut Context<Self>,
10967    ) {
10968        if let Some((client, project_id)) = self.upstream_client() {
10969            let request = client.request(proto::RestartLanguageServers {
10970                project_id,
10971                buffer_ids: buffers
10972                    .into_iter()
10973                    .map(|b| b.read(cx).remote_id().to_proto())
10974                    .collect(),
10975                only_servers: only_restart_servers
10976                    .into_iter()
10977                    .map(|selector| {
10978                        let selector = match selector {
10979                            LanguageServerSelector::Id(language_server_id) => {
10980                                proto::language_server_selector::Selector::ServerId(
10981                                    language_server_id.to_proto(),
10982                                )
10983                            }
10984                            LanguageServerSelector::Name(language_server_name) => {
10985                                proto::language_server_selector::Selector::Name(
10986                                    language_server_name.to_string(),
10987                                )
10988                            }
10989                        };
10990                        proto::LanguageServerSelector {
10991                            selector: Some(selector),
10992                        }
10993                    })
10994                    .collect(),
10995                all: false,
10996            });
10997            cx.background_spawn(request).detach_and_log_err(cx);
10998        } else {
10999            let stop_task = if only_restart_servers.is_empty() {
11000                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11001            } else {
11002                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11003            };
11004            cx.spawn(async move |lsp_store, cx| {
11005                stop_task.await;
11006                lsp_store
11007                    .update(cx, |lsp_store, cx| {
11008                        for buffer in buffers {
11009                            lsp_store.register_buffer_with_language_servers(
11010                                &buffer,
11011                                only_restart_servers.clone(),
11012                                true,
11013                                cx,
11014                            );
11015                        }
11016                    })
11017                    .ok()
11018            })
11019            .detach();
11020        }
11021    }
11022
11023    pub fn stop_language_servers_for_buffers(
11024        &mut self,
11025        buffers: Vec<Entity<Buffer>>,
11026        also_stop_servers: HashSet<LanguageServerSelector>,
11027        cx: &mut Context<Self>,
11028    ) -> Task<Result<()>> {
11029        if let Some((client, project_id)) = self.upstream_client() {
11030            let request = client.request(proto::StopLanguageServers {
11031                project_id,
11032                buffer_ids: buffers
11033                    .into_iter()
11034                    .map(|b| b.read(cx).remote_id().to_proto())
11035                    .collect(),
11036                also_servers: also_stop_servers
11037                    .into_iter()
11038                    .map(|selector| {
11039                        let selector = match selector {
11040                            LanguageServerSelector::Id(language_server_id) => {
11041                                proto::language_server_selector::Selector::ServerId(
11042                                    language_server_id.to_proto(),
11043                                )
11044                            }
11045                            LanguageServerSelector::Name(language_server_name) => {
11046                                proto::language_server_selector::Selector::Name(
11047                                    language_server_name.to_string(),
11048                                )
11049                            }
11050                        };
11051                        proto::LanguageServerSelector {
11052                            selector: Some(selector),
11053                        }
11054                    })
11055                    .collect(),
11056                all: false,
11057            });
11058            cx.background_spawn(async move {
11059                let _ = request.await?;
11060                Ok(())
11061            })
11062        } else {
11063            let task =
11064                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11065            cx.background_spawn(async move {
11066                task.await;
11067                Ok(())
11068            })
11069        }
11070    }
11071
11072    fn stop_local_language_servers_for_buffers(
11073        &mut self,
11074        buffers: &[Entity<Buffer>],
11075        also_stop_servers: HashSet<LanguageServerSelector>,
11076        cx: &mut Context<Self>,
11077    ) -> Task<()> {
11078        let Some(local) = self.as_local_mut() else {
11079            return Task::ready(());
11080        };
11081        let mut language_server_names_to_stop = BTreeSet::default();
11082        let mut language_servers_to_stop = also_stop_servers
11083            .into_iter()
11084            .flat_map(|selector| match selector {
11085                LanguageServerSelector::Id(id) => Some(id),
11086                LanguageServerSelector::Name(name) => {
11087                    language_server_names_to_stop.insert(name);
11088                    None
11089                }
11090            })
11091            .collect::<BTreeSet<_>>();
11092
11093        let mut covered_worktrees = HashSet::default();
11094        for buffer in buffers {
11095            buffer.update(cx, |buffer, cx| {
11096                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11097                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11098                    && covered_worktrees.insert(worktree_id)
11099                {
11100                    language_server_names_to_stop.retain(|name| {
11101                        let old_ids_count = language_servers_to_stop.len();
11102                        let all_language_servers_with_this_name = local
11103                            .language_server_ids
11104                            .iter()
11105                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11106                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11107                        old_ids_count == language_servers_to_stop.len()
11108                    });
11109                }
11110            });
11111        }
11112        for name in language_server_names_to_stop {
11113            language_servers_to_stop.extend(
11114                local
11115                    .language_server_ids
11116                    .iter()
11117                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11118            );
11119        }
11120
11121        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11122        let tasks = language_servers_to_stop
11123            .into_iter()
11124            .map(|server| self.stop_local_language_server(server, cx))
11125            .collect::<Vec<_>>();
11126
11127        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11128    }
11129
11130    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11131        let (worktree, relative_path) =
11132            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11133
11134        let project_path = ProjectPath {
11135            worktree_id: worktree.read(cx).id(),
11136            path: relative_path,
11137        };
11138
11139        Some(
11140            self.buffer_store()
11141                .read(cx)
11142                .get_by_path(&project_path)?
11143                .read(cx),
11144        )
11145    }
11146
11147    #[cfg(any(test, feature = "test-support"))]
11148    pub fn update_diagnostics(
11149        &mut self,
11150        server_id: LanguageServerId,
11151        diagnostics: lsp::PublishDiagnosticsParams,
11152        result_id: Option<SharedString>,
11153        source_kind: DiagnosticSourceKind,
11154        disk_based_sources: &[String],
11155        cx: &mut Context<Self>,
11156    ) -> Result<()> {
11157        self.merge_lsp_diagnostics(
11158            source_kind,
11159            vec![DocumentDiagnosticsUpdate {
11160                diagnostics,
11161                result_id,
11162                server_id,
11163                disk_based_sources: Cow::Borrowed(disk_based_sources),
11164                registration_id: None,
11165            }],
11166            |_, _, _| false,
11167            cx,
11168        )
11169    }
11170
11171    pub fn merge_lsp_diagnostics(
11172        &mut self,
11173        source_kind: DiagnosticSourceKind,
11174        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11175        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11176        cx: &mut Context<Self>,
11177    ) -> Result<()> {
11178        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11179        let updates = lsp_diagnostics
11180            .into_iter()
11181            .filter_map(|update| {
11182                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11183                Some(DocumentDiagnosticsUpdate {
11184                    diagnostics: self.lsp_to_document_diagnostics(
11185                        abs_path,
11186                        source_kind,
11187                        update.server_id,
11188                        update.diagnostics,
11189                        &update.disk_based_sources,
11190                        update.registration_id.clone(),
11191                    ),
11192                    result_id: update.result_id,
11193                    server_id: update.server_id,
11194                    disk_based_sources: update.disk_based_sources,
11195                    registration_id: update.registration_id,
11196                })
11197            })
11198            .collect();
11199        self.merge_diagnostic_entries(updates, merge, cx)?;
11200        Ok(())
11201    }
11202
11203    fn lsp_to_document_diagnostics(
11204        &mut self,
11205        document_abs_path: PathBuf,
11206        source_kind: DiagnosticSourceKind,
11207        server_id: LanguageServerId,
11208        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11209        disk_based_sources: &[String],
11210        registration_id: Option<SharedString>,
11211    ) -> DocumentDiagnostics {
11212        let mut diagnostics = Vec::default();
11213        let mut primary_diagnostic_group_ids = HashMap::default();
11214        let mut sources_by_group_id = HashMap::default();
11215        let mut supporting_diagnostics = HashMap::default();
11216
11217        let adapter = self.language_server_adapter_for_id(server_id);
11218
11219        // Ensure that primary diagnostics are always the most severe
11220        lsp_diagnostics
11221            .diagnostics
11222            .sort_by_key(|item| item.severity);
11223
11224        for diagnostic in &lsp_diagnostics.diagnostics {
11225            let source = diagnostic.source.as_ref();
11226            let range = range_from_lsp(diagnostic.range);
11227            let is_supporting = diagnostic
11228                .related_information
11229                .as_ref()
11230                .is_some_and(|infos| {
11231                    infos.iter().any(|info| {
11232                        primary_diagnostic_group_ids.contains_key(&(
11233                            source,
11234                            diagnostic.code.clone(),
11235                            range_from_lsp(info.location.range),
11236                        ))
11237                    })
11238                });
11239
11240            let is_unnecessary = diagnostic
11241                .tags
11242                .as_ref()
11243                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11244
11245            let underline = self
11246                .language_server_adapter_for_id(server_id)
11247                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11248
11249            if is_supporting {
11250                supporting_diagnostics.insert(
11251                    (source, diagnostic.code.clone(), range),
11252                    (diagnostic.severity, is_unnecessary),
11253                );
11254            } else {
11255                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11256                let is_disk_based =
11257                    source.is_some_and(|source| disk_based_sources.contains(source));
11258
11259                sources_by_group_id.insert(group_id, source);
11260                primary_diagnostic_group_ids
11261                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11262
11263                diagnostics.push(DiagnosticEntry {
11264                    range,
11265                    diagnostic: Diagnostic {
11266                        source: diagnostic.source.clone(),
11267                        source_kind,
11268                        code: diagnostic.code.clone(),
11269                        code_description: diagnostic
11270                            .code_description
11271                            .as_ref()
11272                            .and_then(|d| d.href.clone()),
11273                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11274                        markdown: adapter.as_ref().and_then(|adapter| {
11275                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11276                        }),
11277                        message: diagnostic.message.trim().to_string(),
11278                        group_id,
11279                        is_primary: true,
11280                        is_disk_based,
11281                        is_unnecessary,
11282                        underline,
11283                        data: diagnostic.data.clone(),
11284                        registration_id: registration_id.clone(),
11285                    },
11286                });
11287                if let Some(infos) = &diagnostic.related_information {
11288                    for info in infos {
11289                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11290                            let range = range_from_lsp(info.location.range);
11291                            diagnostics.push(DiagnosticEntry {
11292                                range,
11293                                diagnostic: Diagnostic {
11294                                    source: diagnostic.source.clone(),
11295                                    source_kind,
11296                                    code: diagnostic.code.clone(),
11297                                    code_description: diagnostic
11298                                        .code_description
11299                                        .as_ref()
11300                                        .and_then(|d| d.href.clone()),
11301                                    severity: DiagnosticSeverity::INFORMATION,
11302                                    markdown: adapter.as_ref().and_then(|adapter| {
11303                                        adapter.diagnostic_message_to_markdown(&info.message)
11304                                    }),
11305                                    message: info.message.trim().to_string(),
11306                                    group_id,
11307                                    is_primary: false,
11308                                    is_disk_based,
11309                                    is_unnecessary: false,
11310                                    underline,
11311                                    data: diagnostic.data.clone(),
11312                                    registration_id: registration_id.clone(),
11313                                },
11314                            });
11315                        }
11316                    }
11317                }
11318            }
11319        }
11320
11321        for entry in &mut diagnostics {
11322            let diagnostic = &mut entry.diagnostic;
11323            if !diagnostic.is_primary {
11324                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11325                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11326                    source,
11327                    diagnostic.code.clone(),
11328                    entry.range.clone(),
11329                )) {
11330                    if let Some(severity) = severity {
11331                        diagnostic.severity = severity;
11332                    }
11333                    diagnostic.is_unnecessary = is_unnecessary;
11334                }
11335            }
11336        }
11337
11338        DocumentDiagnostics {
11339            diagnostics,
11340            document_abs_path,
11341            version: lsp_diagnostics.version,
11342        }
11343    }
11344
11345    fn insert_newly_running_language_server(
11346        &mut self,
11347        adapter: Arc<CachedLspAdapter>,
11348        language_server: Arc<LanguageServer>,
11349        server_id: LanguageServerId,
11350        key: LanguageServerSeed,
11351        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11352        cx: &mut Context<Self>,
11353    ) {
11354        let Some(local) = self.as_local_mut() else {
11355            return;
11356        };
11357        // If the language server for this key doesn't match the server id, don't store the
11358        // server. Which will cause it to be dropped, killing the process
11359        if local
11360            .language_server_ids
11361            .get(&key)
11362            .map(|state| state.id != server_id)
11363            .unwrap_or(false)
11364        {
11365            return;
11366        }
11367
11368        // Update language_servers collection with Running variant of LanguageServerState
11369        // indicating that the server is up and running and ready
11370        let workspace_folders = workspace_folders.lock().clone();
11371        language_server.set_workspace_folders(workspace_folders);
11372
11373        let workspace_diagnostics_refresh_tasks = language_server
11374            .capabilities()
11375            .diagnostic_provider
11376            .and_then(|provider| {
11377                local
11378                    .language_server_dynamic_registrations
11379                    .entry(server_id)
11380                    .or_default()
11381                    .diagnostics
11382                    .entry(None)
11383                    .or_insert(provider.clone());
11384                let workspace_refresher =
11385                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11386
11387                Some((None, workspace_refresher))
11388            })
11389            .into_iter()
11390            .collect();
11391        local.language_servers.insert(
11392            server_id,
11393            LanguageServerState::Running {
11394                workspace_diagnostics_refresh_tasks,
11395                adapter: adapter.clone(),
11396                server: language_server.clone(),
11397                simulate_disk_based_diagnostics_completion: None,
11398            },
11399        );
11400        local
11401            .languages
11402            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11403        if let Some(file_ops_caps) = language_server
11404            .capabilities()
11405            .workspace
11406            .as_ref()
11407            .and_then(|ws| ws.file_operations.as_ref())
11408        {
11409            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11410            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11411            if did_rename_caps.or(will_rename_caps).is_some() {
11412                let watcher = RenamePathsWatchedForServer::default()
11413                    .with_did_rename_patterns(did_rename_caps)
11414                    .with_will_rename_patterns(will_rename_caps);
11415                local
11416                    .language_server_paths_watched_for_rename
11417                    .insert(server_id, watcher);
11418            }
11419        }
11420
11421        self.language_server_statuses.insert(
11422            server_id,
11423            LanguageServerStatus {
11424                name: language_server.name(),
11425                server_version: language_server.version(),
11426                pending_work: Default::default(),
11427                has_pending_diagnostic_updates: false,
11428                progress_tokens: Default::default(),
11429                worktree: Some(key.worktree_id),
11430                binary: Some(language_server.binary().clone()),
11431                configuration: Some(language_server.configuration().clone()),
11432                workspace_folders: language_server.workspace_folders(),
11433            },
11434        );
11435
11436        cx.emit(LspStoreEvent::LanguageServerAdded(
11437            server_id,
11438            language_server.name(),
11439            Some(key.worktree_id),
11440        ));
11441
11442        let server_capabilities = language_server.capabilities();
11443        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11444            downstream_client
11445                .send(proto::StartLanguageServer {
11446                    project_id: *project_id,
11447                    server: Some(proto::LanguageServer {
11448                        id: server_id.to_proto(),
11449                        name: language_server.name().to_string(),
11450                        worktree_id: Some(key.worktree_id.to_proto()),
11451                    }),
11452                    capabilities: serde_json::to_string(&server_capabilities)
11453                        .expect("serializing server LSP capabilities"),
11454                })
11455                .log_err();
11456        }
11457        self.lsp_server_capabilities
11458            .insert(server_id, server_capabilities);
11459
11460        // Tell the language server about every open buffer in the worktree that matches the language.
11461        // Also check for buffers in worktrees that reused this server
11462        let mut worktrees_using_server = vec![key.worktree_id];
11463        if let Some(local) = self.as_local() {
11464            // Find all worktrees that have this server in their language server tree
11465            for (worktree_id, servers) in &local.lsp_tree.instances {
11466                if *worktree_id != key.worktree_id {
11467                    for server_map in servers.roots.values() {
11468                        if server_map
11469                            .values()
11470                            .any(|(node, _)| node.id() == Some(server_id))
11471                        {
11472                            worktrees_using_server.push(*worktree_id);
11473                        }
11474                    }
11475                }
11476            }
11477        }
11478
11479        let mut buffer_paths_registered = Vec::new();
11480        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11481            let mut lsp_adapters = HashMap::default();
11482            for buffer_handle in buffer_store.buffers() {
11483                let buffer = buffer_handle.read(cx);
11484                let file = match File::from_dyn(buffer.file()) {
11485                    Some(file) => file,
11486                    None => continue,
11487                };
11488                let language = match buffer.language() {
11489                    Some(language) => language,
11490                    None => continue,
11491                };
11492
11493                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11494                    || !lsp_adapters
11495                        .entry(language.name())
11496                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11497                        .iter()
11498                        .any(|a| a.name == key.name)
11499                {
11500                    continue;
11501                }
11502                // didOpen
11503                let file = match file.as_local() {
11504                    Some(file) => file,
11505                    None => continue,
11506                };
11507
11508                let local = self.as_local_mut().unwrap();
11509
11510                let buffer_id = buffer.remote_id();
11511                if local.registered_buffers.contains_key(&buffer_id) {
11512                    let versions = local
11513                        .buffer_snapshots
11514                        .entry(buffer_id)
11515                        .or_default()
11516                        .entry(server_id)
11517                        .and_modify(|_| {
11518                            assert!(
11519                            false,
11520                            "There should not be an existing snapshot for a newly inserted buffer"
11521                        )
11522                        })
11523                        .or_insert_with(|| {
11524                            vec![LspBufferSnapshot {
11525                                version: 0,
11526                                snapshot: buffer.text_snapshot(),
11527                            }]
11528                        });
11529
11530                    let snapshot = versions.last().unwrap();
11531                    let version = snapshot.version;
11532                    let initial_snapshot = &snapshot.snapshot;
11533                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11534                    language_server.register_buffer(
11535                        uri,
11536                        adapter.language_id(&language.name()),
11537                        version,
11538                        initial_snapshot.text(),
11539                    );
11540                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11541                    local
11542                        .buffers_opened_in_servers
11543                        .entry(buffer_id)
11544                        .or_default()
11545                        .insert(server_id);
11546                }
11547                buffer_handle.update(cx, |buffer, cx| {
11548                    buffer.set_completion_triggers(
11549                        server_id,
11550                        language_server
11551                            .capabilities()
11552                            .completion_provider
11553                            .as_ref()
11554                            .and_then(|provider| {
11555                                provider
11556                                    .trigger_characters
11557                                    .as_ref()
11558                                    .map(|characters| characters.iter().cloned().collect())
11559                            })
11560                            .unwrap_or_default(),
11561                        cx,
11562                    )
11563                });
11564            }
11565        });
11566
11567        for (buffer_id, abs_path) in buffer_paths_registered {
11568            cx.emit(LspStoreEvent::LanguageServerUpdate {
11569                language_server_id: server_id,
11570                name: Some(adapter.name()),
11571                message: proto::update_language_server::Variant::RegisteredForBuffer(
11572                    proto::RegisteredForBuffer {
11573                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11574                        buffer_id: buffer_id.to_proto(),
11575                    },
11576                ),
11577            });
11578        }
11579
11580        cx.notify();
11581    }
11582
11583    pub fn language_servers_running_disk_based_diagnostics(
11584        &self,
11585    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11586        self.language_server_statuses
11587            .iter()
11588            .filter_map(|(id, status)| {
11589                if status.has_pending_diagnostic_updates {
11590                    Some(*id)
11591                } else {
11592                    None
11593                }
11594            })
11595    }
11596
11597    pub(crate) fn cancel_language_server_work_for_buffers(
11598        &mut self,
11599        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11600        cx: &mut Context<Self>,
11601    ) {
11602        if let Some((client, project_id)) = self.upstream_client() {
11603            let request = client.request(proto::CancelLanguageServerWork {
11604                project_id,
11605                work: Some(proto::cancel_language_server_work::Work::Buffers(
11606                    proto::cancel_language_server_work::Buffers {
11607                        buffer_ids: buffers
11608                            .into_iter()
11609                            .map(|b| b.read(cx).remote_id().to_proto())
11610                            .collect(),
11611                    },
11612                )),
11613            });
11614            cx.background_spawn(request).detach_and_log_err(cx);
11615        } else if let Some(local) = self.as_local() {
11616            let servers = buffers
11617                .into_iter()
11618                .flat_map(|buffer| {
11619                    buffer.update(cx, |buffer, cx| {
11620                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11621                    })
11622                })
11623                .collect::<HashSet<_>>();
11624            for server_id in servers {
11625                self.cancel_language_server_work(server_id, None, cx);
11626            }
11627        }
11628    }
11629
11630    pub(crate) fn cancel_language_server_work(
11631        &mut self,
11632        server_id: LanguageServerId,
11633        token_to_cancel: Option<ProgressToken>,
11634        cx: &mut Context<Self>,
11635    ) {
11636        if let Some(local) = self.as_local() {
11637            let status = self.language_server_statuses.get(&server_id);
11638            let server = local.language_servers.get(&server_id);
11639            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11640            {
11641                for (token, progress) in &status.pending_work {
11642                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11643                        && token != token_to_cancel
11644                    {
11645                        continue;
11646                    }
11647                    if progress.is_cancellable {
11648                        server
11649                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11650                                WorkDoneProgressCancelParams {
11651                                    token: token.to_lsp(),
11652                                },
11653                            )
11654                            .ok();
11655                    }
11656                }
11657            }
11658        } else if let Some((client, project_id)) = self.upstream_client() {
11659            let request = client.request(proto::CancelLanguageServerWork {
11660                project_id,
11661                work: Some(
11662                    proto::cancel_language_server_work::Work::LanguageServerWork(
11663                        proto::cancel_language_server_work::LanguageServerWork {
11664                            language_server_id: server_id.to_proto(),
11665                            token: token_to_cancel.map(|token| token.to_proto()),
11666                        },
11667                    ),
11668                ),
11669            });
11670            cx.background_spawn(request).detach_and_log_err(cx);
11671        }
11672    }
11673
11674    fn register_supplementary_language_server(
11675        &mut self,
11676        id: LanguageServerId,
11677        name: LanguageServerName,
11678        server: Arc<LanguageServer>,
11679        cx: &mut Context<Self>,
11680    ) {
11681        if let Some(local) = self.as_local_mut() {
11682            local
11683                .supplementary_language_servers
11684                .insert(id, (name.clone(), server));
11685            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11686        }
11687    }
11688
11689    fn unregister_supplementary_language_server(
11690        &mut self,
11691        id: LanguageServerId,
11692        cx: &mut Context<Self>,
11693    ) {
11694        if let Some(local) = self.as_local_mut() {
11695            local.supplementary_language_servers.remove(&id);
11696            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11697        }
11698    }
11699
11700    pub(crate) fn supplementary_language_servers(
11701        &self,
11702    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11703        self.as_local().into_iter().flat_map(|local| {
11704            local
11705                .supplementary_language_servers
11706                .iter()
11707                .map(|(id, (name, _))| (*id, name.clone()))
11708        })
11709    }
11710
11711    pub fn language_server_adapter_for_id(
11712        &self,
11713        id: LanguageServerId,
11714    ) -> Option<Arc<CachedLspAdapter>> {
11715        self.as_local()
11716            .and_then(|local| local.language_servers.get(&id))
11717            .and_then(|language_server_state| match language_server_state {
11718                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11719                _ => None,
11720            })
11721    }
11722
11723    pub(super) fn update_local_worktree_language_servers(
11724        &mut self,
11725        worktree_handle: &Entity<Worktree>,
11726        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11727        cx: &mut Context<Self>,
11728    ) {
11729        if changes.is_empty() {
11730            return;
11731        }
11732
11733        let Some(local) = self.as_local() else { return };
11734
11735        local.prettier_store.update(cx, |prettier_store, cx| {
11736            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11737        });
11738
11739        let worktree_id = worktree_handle.read(cx).id();
11740        let mut language_server_ids = local
11741            .language_server_ids
11742            .iter()
11743            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11744            .collect::<Vec<_>>();
11745        language_server_ids.sort();
11746        language_server_ids.dedup();
11747
11748        // let abs_path = worktree_handle.read(cx).abs_path();
11749        for server_id in &language_server_ids {
11750            if let Some(LanguageServerState::Running { server, .. }) =
11751                local.language_servers.get(server_id)
11752                && let Some(watched_paths) = local
11753                    .language_server_watched_paths
11754                    .get(server_id)
11755                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11756            {
11757                let params = lsp::DidChangeWatchedFilesParams {
11758                    changes: changes
11759                        .iter()
11760                        .filter_map(|(path, _, change)| {
11761                            if !watched_paths.is_match(path.as_std_path()) {
11762                                return None;
11763                            }
11764                            let typ = match change {
11765                                PathChange::Loaded => return None,
11766                                PathChange::Added => lsp::FileChangeType::CREATED,
11767                                PathChange::Removed => lsp::FileChangeType::DELETED,
11768                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11769                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11770                            };
11771                            let uri = lsp::Uri::from_file_path(
11772                                worktree_handle.read(cx).absolutize(&path),
11773                            )
11774                            .ok()?;
11775                            Some(lsp::FileEvent { uri, typ })
11776                        })
11777                        .collect(),
11778                };
11779                if !params.changes.is_empty() {
11780                    server
11781                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11782                        .ok();
11783                }
11784            }
11785        }
11786        for (path, _, _) in changes {
11787            if let Some(file_name) = path.file_name()
11788                && local.watched_manifest_filenames.contains(file_name)
11789            {
11790                self.request_workspace_config_refresh();
11791                break;
11792            }
11793        }
11794    }
11795
11796    pub fn wait_for_remote_buffer(
11797        &mut self,
11798        id: BufferId,
11799        cx: &mut Context<Self>,
11800    ) -> Task<Result<Entity<Buffer>>> {
11801        self.buffer_store.update(cx, |buffer_store, cx| {
11802            buffer_store.wait_for_remote_buffer(id, cx)
11803        })
11804    }
11805
11806    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11807        let mut result = proto::Symbol {
11808            language_server_name: symbol.language_server_name.0.to_string(),
11809            source_worktree_id: symbol.source_worktree_id.to_proto(),
11810            language_server_id: symbol.source_language_server_id.to_proto(),
11811            name: symbol.name.clone(),
11812            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11813            start: Some(proto::PointUtf16 {
11814                row: symbol.range.start.0.row,
11815                column: symbol.range.start.0.column,
11816            }),
11817            end: Some(proto::PointUtf16 {
11818                row: symbol.range.end.0.row,
11819                column: symbol.range.end.0.column,
11820            }),
11821            worktree_id: Default::default(),
11822            path: Default::default(),
11823            signature: Default::default(),
11824        };
11825        match &symbol.path {
11826            SymbolLocation::InProject(path) => {
11827                result.worktree_id = path.worktree_id.to_proto();
11828                result.path = path.path.to_proto();
11829            }
11830            SymbolLocation::OutsideProject {
11831                abs_path,
11832                signature,
11833            } => {
11834                result.path = abs_path.to_string_lossy().into_owned();
11835                result.signature = signature.to_vec();
11836            }
11837        }
11838        result
11839    }
11840
11841    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11842        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11843        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11844        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11845
11846        let path = if serialized_symbol.signature.is_empty() {
11847            SymbolLocation::InProject(ProjectPath {
11848                worktree_id,
11849                path: RelPath::from_proto(&serialized_symbol.path)
11850                    .context("invalid symbol path")?,
11851            })
11852        } else {
11853            SymbolLocation::OutsideProject {
11854                abs_path: Path::new(&serialized_symbol.path).into(),
11855                signature: serialized_symbol
11856                    .signature
11857                    .try_into()
11858                    .map_err(|_| anyhow!("invalid signature"))?,
11859            }
11860        };
11861
11862        let start = serialized_symbol.start.context("invalid start")?;
11863        let end = serialized_symbol.end.context("invalid end")?;
11864        Ok(CoreSymbol {
11865            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11866            source_worktree_id,
11867            source_language_server_id: LanguageServerId::from_proto(
11868                serialized_symbol.language_server_id,
11869            ),
11870            path,
11871            name: serialized_symbol.name,
11872            range: Unclipped(PointUtf16::new(start.row, start.column))
11873                ..Unclipped(PointUtf16::new(end.row, end.column)),
11874            kind,
11875        })
11876    }
11877
11878    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11879        let mut serialized_completion = proto::Completion {
11880            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11881            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11882            new_text: completion.new_text.clone(),
11883            ..proto::Completion::default()
11884        };
11885        match &completion.source {
11886            CompletionSource::Lsp {
11887                insert_range,
11888                server_id,
11889                lsp_completion,
11890                lsp_defaults,
11891                resolved,
11892            } => {
11893                let (old_insert_start, old_insert_end) = insert_range
11894                    .as_ref()
11895                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11896                    .unzip();
11897
11898                serialized_completion.old_insert_start = old_insert_start;
11899                serialized_completion.old_insert_end = old_insert_end;
11900                serialized_completion.source = proto::completion::Source::Lsp as i32;
11901                serialized_completion.server_id = server_id.0 as u64;
11902                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11903                serialized_completion.lsp_defaults = lsp_defaults
11904                    .as_deref()
11905                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11906                serialized_completion.resolved = *resolved;
11907            }
11908            CompletionSource::BufferWord {
11909                word_range,
11910                resolved,
11911            } => {
11912                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11913                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11914                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11915                serialized_completion.resolved = *resolved;
11916            }
11917            CompletionSource::Custom => {
11918                serialized_completion.source = proto::completion::Source::Custom as i32;
11919                serialized_completion.resolved = true;
11920            }
11921            CompletionSource::Dap { sort_text } => {
11922                serialized_completion.source = proto::completion::Source::Dap as i32;
11923                serialized_completion.sort_text = Some(sort_text.clone());
11924            }
11925        }
11926
11927        serialized_completion
11928    }
11929
11930    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11931        let old_replace_start = completion
11932            .old_replace_start
11933            .and_then(deserialize_anchor)
11934            .context("invalid old start")?;
11935        let old_replace_end = completion
11936            .old_replace_end
11937            .and_then(deserialize_anchor)
11938            .context("invalid old end")?;
11939        let insert_range = {
11940            match completion.old_insert_start.zip(completion.old_insert_end) {
11941                Some((start, end)) => {
11942                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11943                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11944                    Some(start..end)
11945                }
11946                None => None,
11947            }
11948        };
11949        Ok(CoreCompletion {
11950            replace_range: old_replace_start..old_replace_end,
11951            new_text: completion.new_text,
11952            source: match proto::completion::Source::from_i32(completion.source) {
11953                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11954                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11955                    insert_range,
11956                    server_id: LanguageServerId::from_proto(completion.server_id),
11957                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11958                    lsp_defaults: completion
11959                        .lsp_defaults
11960                        .as_deref()
11961                        .map(serde_json::from_slice)
11962                        .transpose()?,
11963                    resolved: completion.resolved,
11964                },
11965                Some(proto::completion::Source::BufferWord) => {
11966                    let word_range = completion
11967                        .buffer_word_start
11968                        .and_then(deserialize_anchor)
11969                        .context("invalid buffer word start")?
11970                        ..completion
11971                            .buffer_word_end
11972                            .and_then(deserialize_anchor)
11973                            .context("invalid buffer word end")?;
11974                    CompletionSource::BufferWord {
11975                        word_range,
11976                        resolved: completion.resolved,
11977                    }
11978                }
11979                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11980                    sort_text: completion
11981                        .sort_text
11982                        .context("expected sort text to exist")?,
11983                },
11984                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11985            },
11986        })
11987    }
11988
11989    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11990        let (kind, lsp_action) = match &action.lsp_action {
11991            LspAction::Action(code_action) => (
11992                proto::code_action::Kind::Action as i32,
11993                serde_json::to_vec(code_action).unwrap(),
11994            ),
11995            LspAction::Command(command) => (
11996                proto::code_action::Kind::Command as i32,
11997                serde_json::to_vec(command).unwrap(),
11998            ),
11999            LspAction::CodeLens(code_lens) => (
12000                proto::code_action::Kind::CodeLens as i32,
12001                serde_json::to_vec(code_lens).unwrap(),
12002            ),
12003        };
12004
12005        proto::CodeAction {
12006            server_id: action.server_id.0 as u64,
12007            start: Some(serialize_anchor(&action.range.start)),
12008            end: Some(serialize_anchor(&action.range.end)),
12009            lsp_action,
12010            kind,
12011            resolved: action.resolved,
12012        }
12013    }
12014
12015    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12016        let start = action
12017            .start
12018            .and_then(deserialize_anchor)
12019            .context("invalid start")?;
12020        let end = action
12021            .end
12022            .and_then(deserialize_anchor)
12023            .context("invalid end")?;
12024        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12025            Some(proto::code_action::Kind::Action) => {
12026                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12027            }
12028            Some(proto::code_action::Kind::Command) => {
12029                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12030            }
12031            Some(proto::code_action::Kind::CodeLens) => {
12032                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12033            }
12034            None => anyhow::bail!("Unknown action kind {}", action.kind),
12035        };
12036        Ok(CodeAction {
12037            server_id: LanguageServerId(action.server_id as usize),
12038            range: start..end,
12039            resolved: action.resolved,
12040            lsp_action,
12041        })
12042    }
12043
12044    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12045        match &formatting_result {
12046            Ok(_) => self.last_formatting_failure = None,
12047            Err(error) => {
12048                let error_string = format!("{error:#}");
12049                log::error!("Formatting failed: {error_string}");
12050                self.last_formatting_failure
12051                    .replace(error_string.lines().join(" "));
12052            }
12053        }
12054    }
12055
12056    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12057        self.lsp_server_capabilities.remove(&for_server);
12058        for lsp_data in self.lsp_data.values_mut() {
12059            lsp_data.remove_server_data(for_server);
12060        }
12061        if let Some(local) = self.as_local_mut() {
12062            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12063            local
12064                .workspace_pull_diagnostics_result_ids
12065                .remove(&for_server);
12066            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12067                buffer_servers.remove(&for_server);
12068            }
12069        }
12070    }
12071
12072    pub fn result_id_for_buffer_pull(
12073        &self,
12074        server_id: LanguageServerId,
12075        buffer_id: BufferId,
12076        registration_id: &Option<SharedString>,
12077        cx: &App,
12078    ) -> Option<SharedString> {
12079        let abs_path = self
12080            .buffer_store
12081            .read(cx)
12082            .get(buffer_id)
12083            .and_then(|b| File::from_dyn(b.read(cx).file()))
12084            .map(|f| f.abs_path(cx))?;
12085        self.as_local()?
12086            .buffer_pull_diagnostics_result_ids
12087            .get(&server_id)?
12088            .get(registration_id)?
12089            .get(&abs_path)?
12090            .clone()
12091    }
12092
12093    /// Gets all result_ids for a workspace diagnostics pull request.
12094    /// First, it tries to find buffer's result_id retrieved via the diagnostics pull; if it fails, it falls back to the workspace disagnostics pull result_id.
12095    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12096    pub fn result_ids_for_workspace_refresh(
12097        &self,
12098        server_id: LanguageServerId,
12099        registration_id: &Option<SharedString>,
12100    ) -> HashMap<PathBuf, SharedString> {
12101        let Some(local) = self.as_local() else {
12102            return HashMap::default();
12103        };
12104        local
12105            .workspace_pull_diagnostics_result_ids
12106            .get(&server_id)
12107            .into_iter()
12108            .filter_map(|diagnostics| diagnostics.get(registration_id))
12109            .flatten()
12110            .filter_map(|(abs_path, result_id)| {
12111                let result_id = local
12112                    .buffer_pull_diagnostics_result_ids
12113                    .get(&server_id)
12114                    .and_then(|buffer_ids_result_ids| {
12115                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12116                    })
12117                    .cloned()
12118                    .flatten()
12119                    .or_else(|| result_id.clone())?;
12120                Some((abs_path.clone(), result_id))
12121            })
12122            .collect()
12123    }
12124
12125    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12126        if let Some(LanguageServerState::Running {
12127            workspace_diagnostics_refresh_tasks,
12128            ..
12129        }) = self
12130            .as_local_mut()
12131            .and_then(|local| local.language_servers.get_mut(&server_id))
12132        {
12133            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12134                diagnostics.refresh_tx.try_send(()).ok();
12135            }
12136        }
12137    }
12138
12139    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12140        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12141            return;
12142        };
12143        let Some(local) = self.as_local_mut() else {
12144            return;
12145        };
12146
12147        for server_id in buffer.update(cx, |buffer, cx| {
12148            local.language_server_ids_for_buffer(buffer, cx)
12149        }) {
12150            if let Some(LanguageServerState::Running {
12151                workspace_diagnostics_refresh_tasks,
12152                ..
12153            }) = local.language_servers.get_mut(&server_id)
12154            {
12155                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12156                    diagnostics.refresh_tx.try_send(()).ok();
12157                }
12158            }
12159        }
12160    }
12161
12162    fn apply_workspace_diagnostic_report(
12163        &mut self,
12164        server_id: LanguageServerId,
12165        report: lsp::WorkspaceDiagnosticReportResult,
12166        registration_id: Option<SharedString>,
12167        cx: &mut Context<Self>,
12168    ) {
12169        let workspace_diagnostics =
12170            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12171                report,
12172                server_id,
12173                registration_id,
12174            );
12175        let mut unchanged_buffers = HashMap::default();
12176        let workspace_diagnostics_updates = workspace_diagnostics
12177            .into_iter()
12178            .filter_map(
12179                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12180                    LspPullDiagnostics::Response {
12181                        server_id,
12182                        uri,
12183                        diagnostics,
12184                        registration_id,
12185                    } => Some((
12186                        server_id,
12187                        uri,
12188                        diagnostics,
12189                        workspace_diagnostics.version,
12190                        registration_id,
12191                    )),
12192                    LspPullDiagnostics::Default => None,
12193                },
12194            )
12195            .fold(
12196                HashMap::default(),
12197                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12198                    let (result_id, diagnostics) = match diagnostics {
12199                        PulledDiagnostics::Unchanged { result_id } => {
12200                            unchanged_buffers
12201                                .entry(new_registration_id.clone())
12202                                .or_insert_with(HashSet::default)
12203                                .insert(uri.clone());
12204                            (Some(result_id), Vec::new())
12205                        }
12206                        PulledDiagnostics::Changed {
12207                            result_id,
12208                            diagnostics,
12209                        } => (result_id, diagnostics),
12210                    };
12211                    let disk_based_sources = Cow::Owned(
12212                        self.language_server_adapter_for_id(server_id)
12213                            .as_ref()
12214                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12215                            .unwrap_or(&[])
12216                            .to_vec(),
12217                    );
12218
12219                    let Some(abs_path) = uri.to_file_path().ok() else {
12220                        return acc;
12221                    };
12222                    let Some((worktree, relative_path)) =
12223                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12224                    else {
12225                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12226                        return acc;
12227                    };
12228                    let worktree_id = worktree.read(cx).id();
12229                    let project_path = ProjectPath {
12230                        worktree_id,
12231                        path: relative_path,
12232                    };
12233                    if let Some(local_lsp_store) = self.as_local_mut() {
12234                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12235                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12236                    }
12237                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12238                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12239                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12240                        acc.entry(server_id)
12241                            .or_insert_with(HashMap::default)
12242                            .entry(new_registration_id.clone())
12243                            .or_insert_with(Vec::new)
12244                            .push(DocumentDiagnosticsUpdate {
12245                                server_id,
12246                                diagnostics: lsp::PublishDiagnosticsParams {
12247                                    uri,
12248                                    diagnostics,
12249                                    version,
12250                                },
12251                                result_id,
12252                                disk_based_sources,
12253                                registration_id: new_registration_id,
12254                            });
12255                    }
12256                    acc
12257                },
12258            );
12259
12260        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12261            for (registration_id, diagnostic_updates) in diagnostic_updates {
12262                self.merge_lsp_diagnostics(
12263                    DiagnosticSourceKind::Pulled,
12264                    diagnostic_updates,
12265                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12266                        DiagnosticSourceKind::Pulled => {
12267                            old_diagnostic.registration_id != registration_id
12268                                || unchanged_buffers
12269                                    .get(&old_diagnostic.registration_id)
12270                                    .is_some_and(|unchanged_buffers| {
12271                                        unchanged_buffers.contains(&document_uri)
12272                                    })
12273                        }
12274                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12275                    },
12276                    cx,
12277                )
12278                .log_err();
12279            }
12280        }
12281    }
12282
12283    fn register_server_capabilities(
12284        &mut self,
12285        server_id: LanguageServerId,
12286        params: lsp::RegistrationParams,
12287        cx: &mut Context<Self>,
12288    ) -> anyhow::Result<()> {
12289        let server = self
12290            .language_server_for_id(server_id)
12291            .with_context(|| format!("no server {server_id} found"))?;
12292        for reg in params.registrations {
12293            match reg.method.as_str() {
12294                "workspace/didChangeWatchedFiles" => {
12295                    if let Some(options) = reg.register_options {
12296                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12297                            let caps = serde_json::from_value(options)?;
12298                            local_lsp_store
12299                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12300                            true
12301                        } else {
12302                            false
12303                        };
12304                        if notify {
12305                            notify_server_capabilities_updated(&server, cx);
12306                        }
12307                    }
12308                }
12309                "workspace/didChangeConfiguration" => {
12310                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12311                }
12312                "workspace/didChangeWorkspaceFolders" => {
12313                    // In this case register options is an empty object, we can ignore it
12314                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12315                        supported: Some(true),
12316                        change_notifications: Some(OneOf::Right(reg.id)),
12317                    };
12318                    server.update_capabilities(|capabilities| {
12319                        capabilities
12320                            .workspace
12321                            .get_or_insert_default()
12322                            .workspace_folders = Some(caps);
12323                    });
12324                    notify_server_capabilities_updated(&server, cx);
12325                }
12326                "workspace/symbol" => {
12327                    let options = parse_register_capabilities(reg)?;
12328                    server.update_capabilities(|capabilities| {
12329                        capabilities.workspace_symbol_provider = Some(options);
12330                    });
12331                    notify_server_capabilities_updated(&server, cx);
12332                }
12333                "workspace/fileOperations" => {
12334                    if let Some(options) = reg.register_options {
12335                        let caps = serde_json::from_value(options)?;
12336                        server.update_capabilities(|capabilities| {
12337                            capabilities
12338                                .workspace
12339                                .get_or_insert_default()
12340                                .file_operations = Some(caps);
12341                        });
12342                        notify_server_capabilities_updated(&server, cx);
12343                    }
12344                }
12345                "workspace/executeCommand" => {
12346                    if let Some(options) = reg.register_options {
12347                        let options = serde_json::from_value(options)?;
12348                        server.update_capabilities(|capabilities| {
12349                            capabilities.execute_command_provider = Some(options);
12350                        });
12351                        notify_server_capabilities_updated(&server, cx);
12352                    }
12353                }
12354                "textDocument/rangeFormatting" => {
12355                    let options = parse_register_capabilities(reg)?;
12356                    server.update_capabilities(|capabilities| {
12357                        capabilities.document_range_formatting_provider = Some(options);
12358                    });
12359                    notify_server_capabilities_updated(&server, cx);
12360                }
12361                "textDocument/onTypeFormatting" => {
12362                    if let Some(options) = reg
12363                        .register_options
12364                        .map(serde_json::from_value)
12365                        .transpose()?
12366                    {
12367                        server.update_capabilities(|capabilities| {
12368                            capabilities.document_on_type_formatting_provider = Some(options);
12369                        });
12370                        notify_server_capabilities_updated(&server, cx);
12371                    }
12372                }
12373                "textDocument/formatting" => {
12374                    let options = parse_register_capabilities(reg)?;
12375                    server.update_capabilities(|capabilities| {
12376                        capabilities.document_formatting_provider = Some(options);
12377                    });
12378                    notify_server_capabilities_updated(&server, cx);
12379                }
12380                "textDocument/rename" => {
12381                    let options = parse_register_capabilities(reg)?;
12382                    server.update_capabilities(|capabilities| {
12383                        capabilities.rename_provider = Some(options);
12384                    });
12385                    notify_server_capabilities_updated(&server, cx);
12386                }
12387                "textDocument/inlayHint" => {
12388                    let options = parse_register_capabilities(reg)?;
12389                    server.update_capabilities(|capabilities| {
12390                        capabilities.inlay_hint_provider = Some(options);
12391                    });
12392                    notify_server_capabilities_updated(&server, cx);
12393                }
12394                "textDocument/documentSymbol" => {
12395                    let options = parse_register_capabilities(reg)?;
12396                    server.update_capabilities(|capabilities| {
12397                        capabilities.document_symbol_provider = Some(options);
12398                    });
12399                    notify_server_capabilities_updated(&server, cx);
12400                }
12401                "textDocument/codeAction" => {
12402                    let options = parse_register_capabilities(reg)?;
12403                    let provider = match options {
12404                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12405                        OneOf::Right(caps) => caps,
12406                    };
12407                    server.update_capabilities(|capabilities| {
12408                        capabilities.code_action_provider = Some(provider);
12409                    });
12410                    notify_server_capabilities_updated(&server, cx);
12411                }
12412                "textDocument/definition" => {
12413                    let options = parse_register_capabilities(reg)?;
12414                    server.update_capabilities(|capabilities| {
12415                        capabilities.definition_provider = Some(options);
12416                    });
12417                    notify_server_capabilities_updated(&server, cx);
12418                }
12419                "textDocument/completion" => {
12420                    if let Some(caps) = reg
12421                        .register_options
12422                        .map(serde_json::from_value::<CompletionOptions>)
12423                        .transpose()?
12424                    {
12425                        server.update_capabilities(|capabilities| {
12426                            capabilities.completion_provider = Some(caps.clone());
12427                        });
12428
12429                        if let Some(local) = self.as_local() {
12430                            let mut buffers_with_language_server = Vec::new();
12431                            for handle in self.buffer_store.read(cx).buffers() {
12432                                let buffer_id = handle.read(cx).remote_id();
12433                                if local
12434                                    .buffers_opened_in_servers
12435                                    .get(&buffer_id)
12436                                    .filter(|s| s.contains(&server_id))
12437                                    .is_some()
12438                                {
12439                                    buffers_with_language_server.push(handle);
12440                                }
12441                            }
12442                            let triggers = caps
12443                                .trigger_characters
12444                                .unwrap_or_default()
12445                                .into_iter()
12446                                .collect::<BTreeSet<_>>();
12447                            for handle in buffers_with_language_server {
12448                                let triggers = triggers.clone();
12449                                let _ = handle.update(cx, move |buffer, cx| {
12450                                    buffer.set_completion_triggers(server_id, triggers, cx);
12451                                });
12452                            }
12453                        }
12454                        notify_server_capabilities_updated(&server, cx);
12455                    }
12456                }
12457                "textDocument/hover" => {
12458                    let options = parse_register_capabilities(reg)?;
12459                    let provider = match options {
12460                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12461                        OneOf::Right(caps) => caps,
12462                    };
12463                    server.update_capabilities(|capabilities| {
12464                        capabilities.hover_provider = Some(provider);
12465                    });
12466                    notify_server_capabilities_updated(&server, cx);
12467                }
12468                "textDocument/signatureHelp" => {
12469                    if let Some(caps) = reg
12470                        .register_options
12471                        .map(serde_json::from_value)
12472                        .transpose()?
12473                    {
12474                        server.update_capabilities(|capabilities| {
12475                            capabilities.signature_help_provider = Some(caps);
12476                        });
12477                        notify_server_capabilities_updated(&server, cx);
12478                    }
12479                }
12480                "textDocument/didChange" => {
12481                    if let Some(sync_kind) = reg
12482                        .register_options
12483                        .and_then(|opts| opts.get("syncKind").cloned())
12484                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12485                        .transpose()?
12486                    {
12487                        server.update_capabilities(|capabilities| {
12488                            let mut sync_options =
12489                                Self::take_text_document_sync_options(capabilities);
12490                            sync_options.change = Some(sync_kind);
12491                            capabilities.text_document_sync =
12492                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12493                        });
12494                        notify_server_capabilities_updated(&server, cx);
12495                    }
12496                }
12497                "textDocument/didSave" => {
12498                    if let Some(include_text) = reg
12499                        .register_options
12500                        .map(|opts| {
12501                            let transpose = opts
12502                                .get("includeText")
12503                                .cloned()
12504                                .map(serde_json::from_value::<Option<bool>>)
12505                                .transpose();
12506                            match transpose {
12507                                Ok(value) => Ok(value.flatten()),
12508                                Err(e) => Err(e),
12509                            }
12510                        })
12511                        .transpose()?
12512                    {
12513                        server.update_capabilities(|capabilities| {
12514                            let mut sync_options =
12515                                Self::take_text_document_sync_options(capabilities);
12516                            sync_options.save =
12517                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12518                                    include_text,
12519                                }));
12520                            capabilities.text_document_sync =
12521                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12522                        });
12523                        notify_server_capabilities_updated(&server, cx);
12524                    }
12525                }
12526                "textDocument/codeLens" => {
12527                    if let Some(caps) = reg
12528                        .register_options
12529                        .map(serde_json::from_value)
12530                        .transpose()?
12531                    {
12532                        server.update_capabilities(|capabilities| {
12533                            capabilities.code_lens_provider = Some(caps);
12534                        });
12535                        notify_server_capabilities_updated(&server, cx);
12536                    }
12537                }
12538                "textDocument/diagnostic" => {
12539                    if let Some(caps) = reg
12540                        .register_options
12541                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12542                        .transpose()?
12543                    {
12544                        let local = self
12545                            .as_local_mut()
12546                            .context("Expected LSP Store to be local")?;
12547                        let state = local
12548                            .language_servers
12549                            .get_mut(&server_id)
12550                            .context("Could not obtain Language Servers state")?;
12551                        local
12552                            .language_server_dynamic_registrations
12553                            .entry(server_id)
12554                            .or_default()
12555                            .diagnostics
12556                            .insert(Some(reg.id.clone()), caps.clone());
12557
12558                        let supports_workspace_diagnostics =
12559                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12560                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12561                                    diagnostic_options.workspace_diagnostics
12562                                }
12563                                DiagnosticServerCapabilities::RegistrationOptions(
12564                                    diagnostic_registration_options,
12565                                ) => {
12566                                    diagnostic_registration_options
12567                                        .diagnostic_options
12568                                        .workspace_diagnostics
12569                                }
12570                            };
12571
12572                        if supports_workspace_diagnostics(&caps) {
12573                            if let LanguageServerState::Running {
12574                                workspace_diagnostics_refresh_tasks,
12575                                ..
12576                            } = state
12577                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12578                                    Some(reg.id.clone()),
12579                                    caps.clone(),
12580                                    server.clone(),
12581                                    cx,
12582                                )
12583                            {
12584                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12585                            }
12586                        }
12587
12588                        server.update_capabilities(|capabilities| {
12589                            capabilities.diagnostic_provider = Some(caps);
12590                        });
12591
12592                        notify_server_capabilities_updated(&server, cx);
12593                    }
12594                }
12595                "textDocument/documentColor" => {
12596                    let options = parse_register_capabilities(reg)?;
12597                    let provider = match options {
12598                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12599                        OneOf::Right(caps) => caps,
12600                    };
12601                    server.update_capabilities(|capabilities| {
12602                        capabilities.color_provider = Some(provider);
12603                    });
12604                    notify_server_capabilities_updated(&server, cx);
12605                }
12606                _ => log::warn!("unhandled capability registration: {reg:?}"),
12607            }
12608        }
12609
12610        Ok(())
12611    }
12612
12613    fn unregister_server_capabilities(
12614        &mut self,
12615        server_id: LanguageServerId,
12616        params: lsp::UnregistrationParams,
12617        cx: &mut Context<Self>,
12618    ) -> anyhow::Result<()> {
12619        let server = self
12620            .language_server_for_id(server_id)
12621            .with_context(|| format!("no server {server_id} found"))?;
12622        for unreg in params.unregisterations.iter() {
12623            match unreg.method.as_str() {
12624                "workspace/didChangeWatchedFiles" => {
12625                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12626                        local_lsp_store
12627                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12628                        true
12629                    } else {
12630                        false
12631                    };
12632                    if notify {
12633                        notify_server_capabilities_updated(&server, cx);
12634                    }
12635                }
12636                "workspace/didChangeConfiguration" => {
12637                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12638                }
12639                "workspace/didChangeWorkspaceFolders" => {
12640                    server.update_capabilities(|capabilities| {
12641                        capabilities
12642                            .workspace
12643                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12644                                workspace_folders: None,
12645                                file_operations: None,
12646                            })
12647                            .workspace_folders = None;
12648                    });
12649                    notify_server_capabilities_updated(&server, cx);
12650                }
12651                "workspace/symbol" => {
12652                    server.update_capabilities(|capabilities| {
12653                        capabilities.workspace_symbol_provider = None
12654                    });
12655                    notify_server_capabilities_updated(&server, cx);
12656                }
12657                "workspace/fileOperations" => {
12658                    server.update_capabilities(|capabilities| {
12659                        capabilities
12660                            .workspace
12661                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12662                                workspace_folders: None,
12663                                file_operations: None,
12664                            })
12665                            .file_operations = None;
12666                    });
12667                    notify_server_capabilities_updated(&server, cx);
12668                }
12669                "workspace/executeCommand" => {
12670                    server.update_capabilities(|capabilities| {
12671                        capabilities.execute_command_provider = None;
12672                    });
12673                    notify_server_capabilities_updated(&server, cx);
12674                }
12675                "textDocument/rangeFormatting" => {
12676                    server.update_capabilities(|capabilities| {
12677                        capabilities.document_range_formatting_provider = None
12678                    });
12679                    notify_server_capabilities_updated(&server, cx);
12680                }
12681                "textDocument/onTypeFormatting" => {
12682                    server.update_capabilities(|capabilities| {
12683                        capabilities.document_on_type_formatting_provider = None;
12684                    });
12685                    notify_server_capabilities_updated(&server, cx);
12686                }
12687                "textDocument/formatting" => {
12688                    server.update_capabilities(|capabilities| {
12689                        capabilities.document_formatting_provider = None;
12690                    });
12691                    notify_server_capabilities_updated(&server, cx);
12692                }
12693                "textDocument/rename" => {
12694                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12695                    notify_server_capabilities_updated(&server, cx);
12696                }
12697                "textDocument/codeAction" => {
12698                    server.update_capabilities(|capabilities| {
12699                        capabilities.code_action_provider = None;
12700                    });
12701                    notify_server_capabilities_updated(&server, cx);
12702                }
12703                "textDocument/definition" => {
12704                    server.update_capabilities(|capabilities| {
12705                        capabilities.definition_provider = None;
12706                    });
12707                    notify_server_capabilities_updated(&server, cx);
12708                }
12709                "textDocument/completion" => {
12710                    server.update_capabilities(|capabilities| {
12711                        capabilities.completion_provider = None;
12712                    });
12713                    notify_server_capabilities_updated(&server, cx);
12714                }
12715                "textDocument/hover" => {
12716                    server.update_capabilities(|capabilities| {
12717                        capabilities.hover_provider = None;
12718                    });
12719                    notify_server_capabilities_updated(&server, cx);
12720                }
12721                "textDocument/signatureHelp" => {
12722                    server.update_capabilities(|capabilities| {
12723                        capabilities.signature_help_provider = None;
12724                    });
12725                    notify_server_capabilities_updated(&server, cx);
12726                }
12727                "textDocument/didChange" => {
12728                    server.update_capabilities(|capabilities| {
12729                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12730                        sync_options.change = None;
12731                        capabilities.text_document_sync =
12732                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12733                    });
12734                    notify_server_capabilities_updated(&server, cx);
12735                }
12736                "textDocument/didSave" => {
12737                    server.update_capabilities(|capabilities| {
12738                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12739                        sync_options.save = None;
12740                        capabilities.text_document_sync =
12741                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12742                    });
12743                    notify_server_capabilities_updated(&server, cx);
12744                }
12745                "textDocument/codeLens" => {
12746                    server.update_capabilities(|capabilities| {
12747                        capabilities.code_lens_provider = None;
12748                    });
12749                    notify_server_capabilities_updated(&server, cx);
12750                }
12751                "textDocument/diagnostic" => {
12752                    let local = self
12753                        .as_local_mut()
12754                        .context("Expected LSP Store to be local")?;
12755
12756                    let state = local
12757                        .language_servers
12758                        .get_mut(&server_id)
12759                        .context("Could not obtain Language Servers state")?;
12760                    let registrations = local
12761                        .language_server_dynamic_registrations
12762                        .get_mut(&server_id)
12763                        .with_context(|| {
12764                            format!("Expected dynamic registration to exist for server {server_id}")
12765                        })?;
12766                    registrations.diagnostics
12767                        .remove(&Some(unreg.id.clone()))
12768                        .with_context(|| format!(
12769                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12770                            unreg.id)
12771                        )?;
12772                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12773
12774                    if let LanguageServerState::Running {
12775                        workspace_diagnostics_refresh_tasks,
12776                        ..
12777                    } = state
12778                    {
12779                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12780                    }
12781
12782                    if removed_last_diagnostic_provider {
12783                        server.update_capabilities(|capabilities| {
12784                            debug_assert!(capabilities.diagnostic_provider.is_some());
12785                            capabilities.diagnostic_provider = None;
12786                        });
12787                    }
12788
12789                    notify_server_capabilities_updated(&server, cx);
12790                }
12791                "textDocument/documentColor" => {
12792                    server.update_capabilities(|capabilities| {
12793                        capabilities.color_provider = None;
12794                    });
12795                    notify_server_capabilities_updated(&server, cx);
12796                }
12797                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12798            }
12799        }
12800
12801        Ok(())
12802    }
12803
12804    async fn deduplicate_range_based_lsp_requests<T>(
12805        lsp_store: &Entity<Self>,
12806        server_id: Option<LanguageServerId>,
12807        lsp_request_id: LspRequestId,
12808        proto_request: &T::ProtoRequest,
12809        range: Range<Anchor>,
12810        cx: &mut AsyncApp,
12811    ) -> Result<()>
12812    where
12813        T: LspCommand,
12814        T::ProtoRequest: proto::LspRequestMessage,
12815    {
12816        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12817        let version = deserialize_version(proto_request.buffer_version());
12818        let buffer = lsp_store.update(cx, |this, cx| {
12819            this.buffer_store.read(cx).get_existing(buffer_id)
12820        })??;
12821        buffer
12822            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12823            .await?;
12824        lsp_store.update(cx, |lsp_store, cx| {
12825            let buffer_snapshot = buffer.read(cx).snapshot();
12826            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12827            let chunks_queried_for = lsp_data
12828                .inlay_hints
12829                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12830                .collect::<Vec<_>>();
12831            match chunks_queried_for.as_slice() {
12832                &[chunk] => {
12833                    let key = LspKey {
12834                        request_type: TypeId::of::<T>(),
12835                        server_queried: server_id,
12836                    };
12837                    let previous_request = lsp_data
12838                        .chunk_lsp_requests
12839                        .entry(key)
12840                        .or_default()
12841                        .insert(chunk, lsp_request_id);
12842                    if let Some((previous_request, running_requests)) =
12843                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12844                    {
12845                        running_requests.remove(&previous_request);
12846                    }
12847                }
12848                _ambiguous_chunks => {
12849                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12850                    // there, a buffer version-based check will be performed and outdated requests discarded.
12851                }
12852            }
12853            anyhow::Ok(())
12854        })??;
12855
12856        Ok(())
12857    }
12858
12859    async fn query_lsp_locally<T>(
12860        lsp_store: Entity<Self>,
12861        for_server_id: Option<LanguageServerId>,
12862        sender_id: proto::PeerId,
12863        lsp_request_id: LspRequestId,
12864        proto_request: T::ProtoRequest,
12865        position: Option<Anchor>,
12866        cx: &mut AsyncApp,
12867    ) -> Result<()>
12868    where
12869        T: LspCommand + Clone,
12870        T::ProtoRequest: proto::LspRequestMessage,
12871        <T::ProtoRequest as proto::RequestMessage>::Response:
12872            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12873    {
12874        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12875        let version = deserialize_version(proto_request.buffer_version());
12876        let buffer = lsp_store.update(cx, |this, cx| {
12877            this.buffer_store.read(cx).get_existing(buffer_id)
12878        })??;
12879        buffer
12880            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12881            .await?;
12882        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12883        let request =
12884            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12885        let key = LspKey {
12886            request_type: TypeId::of::<T>(),
12887            server_queried: for_server_id,
12888        };
12889        lsp_store.update(cx, |lsp_store, cx| {
12890            let request_task = match for_server_id {
12891                Some(server_id) => {
12892                    let server_task = lsp_store.request_lsp(
12893                        buffer.clone(),
12894                        LanguageServerToQuery::Other(server_id),
12895                        request.clone(),
12896                        cx,
12897                    );
12898                    cx.background_spawn(async move {
12899                        let mut responses = Vec::new();
12900                        match server_task.await {
12901                            Ok(response) => responses.push((server_id, response)),
12902                            // rust-analyzer likes to error with this when its still loading up
12903                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12904                            Err(e) => log::error!(
12905                                "Error handling response for request {request:?}: {e:#}"
12906                            ),
12907                        }
12908                        responses
12909                    })
12910                }
12911                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12912            };
12913            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12914            if T::ProtoRequest::stop_previous_requests() {
12915                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12916                    lsp_requests.clear();
12917                }
12918            }
12919            lsp_data.lsp_requests.entry(key).or_default().insert(
12920                lsp_request_id,
12921                cx.spawn(async move |lsp_store, cx| {
12922                    let response = request_task.await;
12923                    lsp_store
12924                        .update(cx, |lsp_store, cx| {
12925                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12926                            {
12927                                let response = response
12928                                    .into_iter()
12929                                    .map(|(server_id, response)| {
12930                                        (
12931                                            server_id.to_proto(),
12932                                            T::response_to_proto(
12933                                                response,
12934                                                lsp_store,
12935                                                sender_id,
12936                                                &buffer_version,
12937                                                cx,
12938                                            )
12939                                            .into(),
12940                                        )
12941                                    })
12942                                    .collect::<HashMap<_, _>>();
12943                                match client.send_lsp_response::<T::ProtoRequest>(
12944                                    project_id,
12945                                    lsp_request_id,
12946                                    response,
12947                                ) {
12948                                    Ok(()) => {}
12949                                    Err(e) => {
12950                                        log::error!("Failed to send LSP response: {e:#}",)
12951                                    }
12952                                }
12953                            }
12954                        })
12955                        .ok();
12956                }),
12957            );
12958        })?;
12959        Ok(())
12960    }
12961
12962    fn take_text_document_sync_options(
12963        capabilities: &mut lsp::ServerCapabilities,
12964    ) -> lsp::TextDocumentSyncOptions {
12965        match capabilities.text_document_sync.take() {
12966            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12967            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12968                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12969                sync_options.change = Some(sync_kind);
12970                sync_options
12971            }
12972            None => lsp::TextDocumentSyncOptions::default(),
12973        }
12974    }
12975
12976    #[cfg(any(test, feature = "test-support"))]
12977    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12978        Some(
12979            self.lsp_data
12980                .get_mut(&buffer_id)?
12981                .code_lens
12982                .take()?
12983                .update
12984                .take()?
12985                .1,
12986        )
12987    }
12988
12989    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12990        self.downstream_client.clone()
12991    }
12992
12993    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12994        self.worktree_store.clone()
12995    }
12996
12997    /// Gets what's stored in the LSP data for the given buffer.
12998    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12999        self.lsp_data.get_mut(&buffer_id)
13000    }
13001
13002    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13003    /// new [`BufferLspData`] will be created to replace the previous state.
13004    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13005        let (buffer_id, buffer_version) =
13006            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13007        let lsp_data = self
13008            .lsp_data
13009            .entry(buffer_id)
13010            .or_insert_with(|| BufferLspData::new(buffer, cx));
13011        if buffer_version.changed_since(&lsp_data.buffer_version) {
13012            *lsp_data = BufferLspData::new(buffer, cx);
13013        }
13014        lsp_data
13015    }
13016}
13017
13018// Registration with registerOptions as null, should fallback to true.
13019// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13020fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13021    reg: lsp::Registration,
13022) -> Result<OneOf<bool, T>> {
13023    Ok(match reg.register_options {
13024        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13025        None => OneOf::Left(true),
13026    })
13027}
13028
13029fn subscribe_to_binary_statuses(
13030    languages: &Arc<LanguageRegistry>,
13031    cx: &mut Context<'_, LspStore>,
13032) -> Task<()> {
13033    let mut server_statuses = languages.language_server_binary_statuses();
13034    cx.spawn(async move |lsp_store, cx| {
13035        while let Some((server_name, binary_status)) = server_statuses.next().await {
13036            if lsp_store
13037                .update(cx, |_, cx| {
13038                    let mut message = None;
13039                    let binary_status = match binary_status {
13040                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13041                        BinaryStatus::CheckingForUpdate => {
13042                            proto::ServerBinaryStatus::CheckingForUpdate
13043                        }
13044                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13045                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13046                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13047                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13048                        BinaryStatus::Failed { error } => {
13049                            message = Some(error);
13050                            proto::ServerBinaryStatus::Failed
13051                        }
13052                    };
13053                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13054                        // Binary updates are about the binary that might not have any language server id at that point.
13055                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13056                        language_server_id: LanguageServerId(0),
13057                        name: Some(server_name),
13058                        message: proto::update_language_server::Variant::StatusUpdate(
13059                            proto::StatusUpdate {
13060                                message,
13061                                status: Some(proto::status_update::Status::Binary(
13062                                    binary_status as i32,
13063                                )),
13064                            },
13065                        ),
13066                    });
13067                })
13068                .is_err()
13069            {
13070                break;
13071            }
13072        }
13073    })
13074}
13075
13076fn lsp_workspace_diagnostics_refresh(
13077    registration_id: Option<String>,
13078    options: DiagnosticServerCapabilities,
13079    server: Arc<LanguageServer>,
13080    cx: &mut Context<'_, LspStore>,
13081) -> Option<WorkspaceRefreshTask> {
13082    let identifier = workspace_diagnostic_identifier(&options)?;
13083    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13084
13085    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13086    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13087    refresh_tx.try_send(()).ok();
13088
13089    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13090        let mut attempts = 0;
13091        let max_attempts = 50;
13092        let mut requests = 0;
13093
13094        loop {
13095            let Some(()) = refresh_rx.recv().await else {
13096                return;
13097            };
13098
13099            'request: loop {
13100                requests += 1;
13101                if attempts > max_attempts {
13102                    log::error!(
13103                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13104                    );
13105                    return;
13106                }
13107                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13108                cx.background_executor()
13109                    .timer(Duration::from_millis(backoff_millis))
13110                    .await;
13111                attempts += 1;
13112
13113                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13114                    lsp_store
13115                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13116                        .into_iter()
13117                        .filter_map(|(abs_path, result_id)| {
13118                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13119                            Some(lsp::PreviousResultId {
13120                                uri,
13121                                value: result_id.to_string(),
13122                            })
13123                        })
13124                        .collect()
13125                }) else {
13126                    return;
13127                };
13128
13129                let token = if let Some(registration_id) = &registration_id {
13130                    format!(
13131                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13132                        server.server_id(),
13133                    )
13134                } else {
13135                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13136                };
13137
13138                progress_rx.try_recv().ok();
13139                let timer =
13140                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13141                let progress = pin!(progress_rx.recv().fuse());
13142                let response_result = server
13143                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13144                        lsp::WorkspaceDiagnosticParams {
13145                            previous_result_ids,
13146                            identifier: identifier.clone(),
13147                            work_done_progress_params: Default::default(),
13148                            partial_result_params: lsp::PartialResultParams {
13149                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13150                            },
13151                        },
13152                        select(timer, progress).then(|either| match either {
13153                            Either::Left((message, ..)) => ready(message).left_future(),
13154                            Either::Right(..) => pending::<String>().right_future(),
13155                        }),
13156                    )
13157                    .await;
13158
13159                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13160                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13161                match response_result {
13162                    ConnectionResult::Timeout => {
13163                        log::error!("Timeout during workspace diagnostics pull");
13164                        continue 'request;
13165                    }
13166                    ConnectionResult::ConnectionReset => {
13167                        log::error!("Server closed a workspace diagnostics pull request");
13168                        continue 'request;
13169                    }
13170                    ConnectionResult::Result(Err(e)) => {
13171                        log::error!("Error during workspace diagnostics pull: {e:#}");
13172                        break 'request;
13173                    }
13174                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13175                        attempts = 0;
13176                        if lsp_store
13177                            .update(cx, |lsp_store, cx| {
13178                                lsp_store.apply_workspace_diagnostic_report(
13179                                    server.server_id(),
13180                                    pulled_diagnostics,
13181                                    registration_id_shared.clone(),
13182                                    cx,
13183                                )
13184                            })
13185                            .is_err()
13186                        {
13187                            return;
13188                        }
13189                        break 'request;
13190                    }
13191                }
13192            }
13193        }
13194    });
13195
13196    Some(WorkspaceRefreshTask {
13197        refresh_tx,
13198        progress_tx,
13199        task: workspace_query_language_server,
13200    })
13201}
13202
13203fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13204    match &options {
13205        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13206            diagnostic_options.identifier.clone()
13207        }
13208        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13209            let diagnostic_options = &registration_options.diagnostic_options;
13210            diagnostic_options.identifier.clone()
13211        }
13212    }
13213}
13214
13215fn workspace_diagnostic_identifier(
13216    options: &DiagnosticServerCapabilities,
13217) -> Option<Option<String>> {
13218    match &options {
13219        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13220            if !diagnostic_options.workspace_diagnostics {
13221                return None;
13222            }
13223            Some(diagnostic_options.identifier.clone())
13224        }
13225        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13226            let diagnostic_options = &registration_options.diagnostic_options;
13227            if !diagnostic_options.workspace_diagnostics {
13228                return None;
13229            }
13230            Some(diagnostic_options.identifier.clone())
13231        }
13232    }
13233}
13234
13235fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13236    let CompletionSource::BufferWord {
13237        word_range,
13238        resolved,
13239    } = &mut completion.source
13240    else {
13241        return;
13242    };
13243    if *resolved {
13244        return;
13245    }
13246
13247    if completion.new_text
13248        != snapshot
13249            .text_for_range(word_range.clone())
13250            .collect::<String>()
13251    {
13252        return;
13253    }
13254
13255    let mut offset = 0;
13256    for chunk in snapshot.chunks(word_range.clone(), true) {
13257        let end_offset = offset + chunk.text.len();
13258        if let Some(highlight_id) = chunk.syntax_highlight_id {
13259            completion
13260                .label
13261                .runs
13262                .push((offset..end_offset, highlight_id));
13263        }
13264        offset = end_offset;
13265    }
13266    *resolved = true;
13267}
13268
13269impl EventEmitter<LspStoreEvent> for LspStore {}
13270
13271fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13272    hover
13273        .contents
13274        .retain(|hover_block| !hover_block.text.trim().is_empty());
13275    if hover.contents.is_empty() {
13276        None
13277    } else {
13278        Some(hover)
13279    }
13280}
13281
13282async fn populate_labels_for_completions(
13283    new_completions: Vec<CoreCompletion>,
13284    language: Option<Arc<Language>>,
13285    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13286) -> Vec<Completion> {
13287    let lsp_completions = new_completions
13288        .iter()
13289        .filter_map(|new_completion| {
13290            new_completion
13291                .source
13292                .lsp_completion(true)
13293                .map(|lsp_completion| lsp_completion.into_owned())
13294        })
13295        .collect::<Vec<_>>();
13296
13297    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13298        lsp_adapter
13299            .labels_for_completions(&lsp_completions, language)
13300            .await
13301            .log_err()
13302            .unwrap_or_default()
13303    } else {
13304        Vec::new()
13305    }
13306    .into_iter()
13307    .fuse();
13308
13309    let mut completions = Vec::new();
13310    for completion in new_completions {
13311        match completion.source.lsp_completion(true) {
13312            Some(lsp_completion) => {
13313                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13314
13315                let mut label = labels.next().flatten().unwrap_or_else(|| {
13316                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13317                });
13318                ensure_uniform_list_compatible_label(&mut label);
13319                completions.push(Completion {
13320                    label,
13321                    documentation,
13322                    replace_range: completion.replace_range,
13323                    new_text: completion.new_text,
13324                    insert_text_mode: lsp_completion.insert_text_mode,
13325                    source: completion.source,
13326                    icon_path: None,
13327                    confirm: None,
13328                    match_start: None,
13329                    snippet_deduplication_key: None,
13330                });
13331            }
13332            None => {
13333                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13334                ensure_uniform_list_compatible_label(&mut label);
13335                completions.push(Completion {
13336                    label,
13337                    documentation: None,
13338                    replace_range: completion.replace_range,
13339                    new_text: completion.new_text,
13340                    source: completion.source,
13341                    insert_text_mode: None,
13342                    icon_path: None,
13343                    confirm: None,
13344                    match_start: None,
13345                    snippet_deduplication_key: None,
13346                });
13347            }
13348        }
13349    }
13350    completions
13351}
13352
13353#[derive(Debug)]
13354pub enum LanguageServerToQuery {
13355    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13356    FirstCapable,
13357    /// Query a specific language server.
13358    Other(LanguageServerId),
13359}
13360
13361#[derive(Default)]
13362struct RenamePathsWatchedForServer {
13363    did_rename: Vec<RenameActionPredicate>,
13364    will_rename: Vec<RenameActionPredicate>,
13365}
13366
13367impl RenamePathsWatchedForServer {
13368    fn with_did_rename_patterns(
13369        mut self,
13370        did_rename: Option<&FileOperationRegistrationOptions>,
13371    ) -> Self {
13372        if let Some(did_rename) = did_rename {
13373            self.did_rename = did_rename
13374                .filters
13375                .iter()
13376                .filter_map(|filter| filter.try_into().log_err())
13377                .collect();
13378        }
13379        self
13380    }
13381    fn with_will_rename_patterns(
13382        mut self,
13383        will_rename: Option<&FileOperationRegistrationOptions>,
13384    ) -> Self {
13385        if let Some(will_rename) = will_rename {
13386            self.will_rename = will_rename
13387                .filters
13388                .iter()
13389                .filter_map(|filter| filter.try_into().log_err())
13390                .collect();
13391        }
13392        self
13393    }
13394
13395    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13396        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13397    }
13398    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13399        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13400    }
13401}
13402
13403impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13404    type Error = globset::Error;
13405    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13406        Ok(Self {
13407            kind: ops.pattern.matches.clone(),
13408            glob: GlobBuilder::new(&ops.pattern.glob)
13409                .case_insensitive(
13410                    ops.pattern
13411                        .options
13412                        .as_ref()
13413                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13414                )
13415                .build()?
13416                .compile_matcher(),
13417        })
13418    }
13419}
13420struct RenameActionPredicate {
13421    glob: GlobMatcher,
13422    kind: Option<FileOperationPatternKind>,
13423}
13424
13425impl RenameActionPredicate {
13426    // Returns true if language server should be notified
13427    fn eval(&self, path: &str, is_dir: bool) -> bool {
13428        self.kind.as_ref().is_none_or(|kind| {
13429            let expected_kind = if is_dir {
13430                FileOperationPatternKind::Folder
13431            } else {
13432                FileOperationPatternKind::File
13433            };
13434            kind == &expected_kind
13435        }) && self.glob.is_match(path)
13436    }
13437}
13438
13439#[derive(Default)]
13440struct LanguageServerWatchedPaths {
13441    worktree_paths: HashMap<WorktreeId, GlobSet>,
13442    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13443}
13444
13445#[derive(Default)]
13446struct LanguageServerWatchedPathsBuilder {
13447    worktree_paths: HashMap<WorktreeId, GlobSet>,
13448    abs_paths: HashMap<Arc<Path>, GlobSet>,
13449}
13450
13451impl LanguageServerWatchedPathsBuilder {
13452    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13453        self.worktree_paths.insert(worktree_id, glob_set);
13454    }
13455    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13456        self.abs_paths.insert(path, glob_set);
13457    }
13458    fn build(
13459        self,
13460        fs: Arc<dyn Fs>,
13461        language_server_id: LanguageServerId,
13462        cx: &mut Context<LspStore>,
13463    ) -> LanguageServerWatchedPaths {
13464        let lsp_store = cx.weak_entity();
13465
13466        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13467        let abs_paths = self
13468            .abs_paths
13469            .into_iter()
13470            .map(|(abs_path, globset)| {
13471                let task = cx.spawn({
13472                    let abs_path = abs_path.clone();
13473                    let fs = fs.clone();
13474
13475                    let lsp_store = lsp_store.clone();
13476                    async move |_, cx| {
13477                        maybe!(async move {
13478                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13479                            while let Some(update) = push_updates.0.next().await {
13480                                let action = lsp_store
13481                                    .update(cx, |this, _| {
13482                                        let Some(local) = this.as_local() else {
13483                                            return ControlFlow::Break(());
13484                                        };
13485                                        let Some(watcher) = local
13486                                            .language_server_watched_paths
13487                                            .get(&language_server_id)
13488                                        else {
13489                                            return ControlFlow::Break(());
13490                                        };
13491                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13492                                            "Watched abs path is not registered with a watcher",
13493                                        );
13494                                        let matching_entries = update
13495                                            .into_iter()
13496                                            .filter(|event| globs.is_match(&event.path))
13497                                            .collect::<Vec<_>>();
13498                                        this.lsp_notify_abs_paths_changed(
13499                                            language_server_id,
13500                                            matching_entries,
13501                                        );
13502                                        ControlFlow::Continue(())
13503                                    })
13504                                    .ok()?;
13505
13506                                if action.is_break() {
13507                                    break;
13508                                }
13509                            }
13510                            Some(())
13511                        })
13512                        .await;
13513                    }
13514                });
13515                (abs_path, (globset, task))
13516            })
13517            .collect();
13518        LanguageServerWatchedPaths {
13519            worktree_paths: self.worktree_paths,
13520            abs_paths,
13521        }
13522    }
13523}
13524
13525struct LspBufferSnapshot {
13526    version: i32,
13527    snapshot: TextBufferSnapshot,
13528}
13529
13530/// A prompt requested by LSP server.
13531#[derive(Clone, Debug)]
13532pub struct LanguageServerPromptRequest {
13533    pub level: PromptLevel,
13534    pub message: String,
13535    pub actions: Vec<MessageActionItem>,
13536    pub lsp_name: String,
13537    pub(crate) response_channel: Sender<MessageActionItem>,
13538}
13539
13540impl LanguageServerPromptRequest {
13541    pub async fn respond(self, index: usize) -> Option<()> {
13542        if let Some(response) = self.actions.into_iter().nth(index) {
13543            self.response_channel.send(response).await.ok()
13544        } else {
13545            None
13546        }
13547    }
13548}
13549impl PartialEq for LanguageServerPromptRequest {
13550    fn eq(&self, other: &Self) -> bool {
13551        self.message == other.message && self.actions == other.actions
13552    }
13553}
13554
13555#[derive(Clone, Debug, PartialEq)]
13556pub enum LanguageServerLogType {
13557    Log(MessageType),
13558    Trace { verbose_info: Option<String> },
13559    Rpc { received: bool },
13560}
13561
13562impl LanguageServerLogType {
13563    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13564        match self {
13565            Self::Log(log_type) => {
13566                use proto::log_message::LogLevel;
13567                let level = match *log_type {
13568                    MessageType::ERROR => LogLevel::Error,
13569                    MessageType::WARNING => LogLevel::Warning,
13570                    MessageType::INFO => LogLevel::Info,
13571                    MessageType::LOG => LogLevel::Log,
13572                    other => {
13573                        log::warn!("Unknown lsp log message type: {other:?}");
13574                        LogLevel::Log
13575                    }
13576                };
13577                proto::language_server_log::LogType::Log(proto::LogMessage {
13578                    level: level as i32,
13579                })
13580            }
13581            Self::Trace { verbose_info } => {
13582                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13583                    verbose_info: verbose_info.to_owned(),
13584                })
13585            }
13586            Self::Rpc { received } => {
13587                let kind = if *received {
13588                    proto::rpc_message::Kind::Received
13589                } else {
13590                    proto::rpc_message::Kind::Sent
13591                };
13592                let kind = kind as i32;
13593                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13594            }
13595        }
13596    }
13597
13598    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13599        use proto::log_message::LogLevel;
13600        use proto::rpc_message;
13601        match log_type {
13602            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13603                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13604                    LogLevel::Error => MessageType::ERROR,
13605                    LogLevel::Warning => MessageType::WARNING,
13606                    LogLevel::Info => MessageType::INFO,
13607                    LogLevel::Log => MessageType::LOG,
13608                },
13609            ),
13610            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13611                verbose_info: trace_message.verbose_info,
13612            },
13613            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13614                received: match rpc_message::Kind::from_i32(message.kind)
13615                    .unwrap_or(rpc_message::Kind::Received)
13616                {
13617                    rpc_message::Kind::Received => true,
13618                    rpc_message::Kind::Sent => false,
13619                },
13620            },
13621        }
13622    }
13623}
13624
13625pub struct WorkspaceRefreshTask {
13626    refresh_tx: mpsc::Sender<()>,
13627    progress_tx: mpsc::Sender<()>,
13628    #[allow(dead_code)]
13629    task: Task<()>,
13630}
13631
13632pub enum LanguageServerState {
13633    Starting {
13634        startup: Task<Option<Arc<LanguageServer>>>,
13635        /// List of language servers that will be added to the workspace once it's initialization completes.
13636        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13637    },
13638
13639    Running {
13640        adapter: Arc<CachedLspAdapter>,
13641        server: Arc<LanguageServer>,
13642        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13643        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13644    },
13645}
13646
13647impl LanguageServerState {
13648    fn add_workspace_folder(&self, uri: Uri) {
13649        match self {
13650            LanguageServerState::Starting {
13651                pending_workspace_folders,
13652                ..
13653            } => {
13654                pending_workspace_folders.lock().insert(uri);
13655            }
13656            LanguageServerState::Running { server, .. } => {
13657                server.add_workspace_folder(uri);
13658            }
13659        }
13660    }
13661    fn _remove_workspace_folder(&self, uri: Uri) {
13662        match self {
13663            LanguageServerState::Starting {
13664                pending_workspace_folders,
13665                ..
13666            } => {
13667                pending_workspace_folders.lock().remove(&uri);
13668            }
13669            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13670        }
13671    }
13672}
13673
13674impl std::fmt::Debug for LanguageServerState {
13675    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13676        match self {
13677            LanguageServerState::Starting { .. } => {
13678                f.debug_struct("LanguageServerState::Starting").finish()
13679            }
13680            LanguageServerState::Running { .. } => {
13681                f.debug_struct("LanguageServerState::Running").finish()
13682            }
13683        }
13684    }
13685}
13686
13687#[derive(Clone, Debug, Serialize)]
13688pub struct LanguageServerProgress {
13689    pub is_disk_based_diagnostics_progress: bool,
13690    pub is_cancellable: bool,
13691    pub title: Option<String>,
13692    pub message: Option<String>,
13693    pub percentage: Option<usize>,
13694    #[serde(skip_serializing)]
13695    pub last_update_at: Instant,
13696}
13697
13698#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13699pub struct DiagnosticSummary {
13700    pub error_count: usize,
13701    pub warning_count: usize,
13702}
13703
13704impl DiagnosticSummary {
13705    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13706        let mut this = Self {
13707            error_count: 0,
13708            warning_count: 0,
13709        };
13710
13711        for entry in diagnostics {
13712            if entry.diagnostic.is_primary {
13713                match entry.diagnostic.severity {
13714                    DiagnosticSeverity::ERROR => this.error_count += 1,
13715                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13716                    _ => {}
13717                }
13718            }
13719        }
13720
13721        this
13722    }
13723
13724    pub fn is_empty(&self) -> bool {
13725        self.error_count == 0 && self.warning_count == 0
13726    }
13727
13728    pub fn to_proto(
13729        self,
13730        language_server_id: LanguageServerId,
13731        path: &RelPath,
13732    ) -> proto::DiagnosticSummary {
13733        proto::DiagnosticSummary {
13734            path: path.to_proto(),
13735            language_server_id: language_server_id.0 as u64,
13736            error_count: self.error_count as u32,
13737            warning_count: self.warning_count as u32,
13738        }
13739    }
13740}
13741
13742#[derive(Clone, Debug)]
13743pub enum CompletionDocumentation {
13744    /// There is no documentation for this completion.
13745    Undocumented,
13746    /// A single line of documentation.
13747    SingleLine(SharedString),
13748    /// Multiple lines of plain text documentation.
13749    MultiLinePlainText(SharedString),
13750    /// Markdown documentation.
13751    MultiLineMarkdown(SharedString),
13752    /// Both single line and multiple lines of plain text documentation.
13753    SingleLineAndMultiLinePlainText {
13754        single_line: SharedString,
13755        plain_text: Option<SharedString>,
13756    },
13757}
13758
13759impl CompletionDocumentation {
13760    #[cfg(any(test, feature = "test-support"))]
13761    pub fn text(&self) -> SharedString {
13762        match self {
13763            CompletionDocumentation::Undocumented => "".into(),
13764            CompletionDocumentation::SingleLine(s) => s.clone(),
13765            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13766            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13767            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13768                single_line.clone()
13769            }
13770        }
13771    }
13772}
13773
13774impl From<lsp::Documentation> for CompletionDocumentation {
13775    fn from(docs: lsp::Documentation) -> Self {
13776        match docs {
13777            lsp::Documentation::String(text) => {
13778                if text.lines().count() <= 1 {
13779                    CompletionDocumentation::SingleLine(text.into())
13780                } else {
13781                    CompletionDocumentation::MultiLinePlainText(text.into())
13782                }
13783            }
13784
13785            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13786                lsp::MarkupKind::PlainText => {
13787                    if value.lines().count() <= 1 {
13788                        CompletionDocumentation::SingleLine(value.into())
13789                    } else {
13790                        CompletionDocumentation::MultiLinePlainText(value.into())
13791                    }
13792                }
13793
13794                lsp::MarkupKind::Markdown => {
13795                    CompletionDocumentation::MultiLineMarkdown(value.into())
13796                }
13797            },
13798        }
13799    }
13800}
13801
13802pub enum ResolvedHint {
13803    Resolved(InlayHint),
13804    Resolving(Shared<Task<()>>),
13805}
13806
13807fn glob_literal_prefix(glob: &Path) -> PathBuf {
13808    glob.components()
13809        .take_while(|component| match component {
13810            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13811            _ => true,
13812        })
13813        .collect()
13814}
13815
13816pub struct SshLspAdapter {
13817    name: LanguageServerName,
13818    binary: LanguageServerBinary,
13819    initialization_options: Option<String>,
13820    code_action_kinds: Option<Vec<CodeActionKind>>,
13821}
13822
13823impl SshLspAdapter {
13824    pub fn new(
13825        name: LanguageServerName,
13826        binary: LanguageServerBinary,
13827        initialization_options: Option<String>,
13828        code_action_kinds: Option<String>,
13829    ) -> Self {
13830        Self {
13831            name,
13832            binary,
13833            initialization_options,
13834            code_action_kinds: code_action_kinds
13835                .as_ref()
13836                .and_then(|c| serde_json::from_str(c).ok()),
13837        }
13838    }
13839}
13840
13841impl LspInstaller for SshLspAdapter {
13842    type BinaryVersion = ();
13843    async fn check_if_user_installed(
13844        &self,
13845        _: &dyn LspAdapterDelegate,
13846        _: Option<Toolchain>,
13847        _: &AsyncApp,
13848    ) -> Option<LanguageServerBinary> {
13849        Some(self.binary.clone())
13850    }
13851
13852    async fn cached_server_binary(
13853        &self,
13854        _: PathBuf,
13855        _: &dyn LspAdapterDelegate,
13856    ) -> Option<LanguageServerBinary> {
13857        None
13858    }
13859
13860    async fn fetch_latest_server_version(
13861        &self,
13862        _: &dyn LspAdapterDelegate,
13863        _: bool,
13864        _: &mut AsyncApp,
13865    ) -> Result<()> {
13866        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13867    }
13868
13869    async fn fetch_server_binary(
13870        &self,
13871        _: (),
13872        _: PathBuf,
13873        _: &dyn LspAdapterDelegate,
13874    ) -> Result<LanguageServerBinary> {
13875        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13876    }
13877}
13878
13879#[async_trait(?Send)]
13880impl LspAdapter for SshLspAdapter {
13881    fn name(&self) -> LanguageServerName {
13882        self.name.clone()
13883    }
13884
13885    async fn initialization_options(
13886        self: Arc<Self>,
13887        _: &Arc<dyn LspAdapterDelegate>,
13888    ) -> Result<Option<serde_json::Value>> {
13889        let Some(options) = &self.initialization_options else {
13890            return Ok(None);
13891        };
13892        let result = serde_json::from_str(options)?;
13893        Ok(result)
13894    }
13895
13896    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13897        self.code_action_kinds.clone()
13898    }
13899}
13900
13901pub fn language_server_settings<'a>(
13902    delegate: &'a dyn LspAdapterDelegate,
13903    language: &LanguageServerName,
13904    cx: &'a App,
13905) -> Option<&'a LspSettings> {
13906    language_server_settings_for(
13907        SettingsLocation {
13908            worktree_id: delegate.worktree_id(),
13909            path: RelPath::empty(),
13910        },
13911        language,
13912        cx,
13913    )
13914}
13915
13916pub fn language_server_settings_for<'a>(
13917    location: SettingsLocation<'a>,
13918    language: &LanguageServerName,
13919    cx: &'a App,
13920) -> Option<&'a LspSettings> {
13921    ProjectSettings::get(Some(location), cx).lsp.get(language)
13922}
13923
13924pub struct LocalLspAdapterDelegate {
13925    lsp_store: WeakEntity<LspStore>,
13926    worktree: worktree::Snapshot,
13927    fs: Arc<dyn Fs>,
13928    http_client: Arc<dyn HttpClient>,
13929    language_registry: Arc<LanguageRegistry>,
13930    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13931}
13932
13933impl LocalLspAdapterDelegate {
13934    pub fn new(
13935        language_registry: Arc<LanguageRegistry>,
13936        environment: &Entity<ProjectEnvironment>,
13937        lsp_store: WeakEntity<LspStore>,
13938        worktree: &Entity<Worktree>,
13939        http_client: Arc<dyn HttpClient>,
13940        fs: Arc<dyn Fs>,
13941        cx: &mut App,
13942    ) -> Arc<Self> {
13943        let load_shell_env_task =
13944            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13945
13946        Arc::new(Self {
13947            lsp_store,
13948            worktree: worktree.read(cx).snapshot(),
13949            fs,
13950            http_client,
13951            language_registry,
13952            load_shell_env_task,
13953        })
13954    }
13955
13956    fn from_local_lsp(
13957        local: &LocalLspStore,
13958        worktree: &Entity<Worktree>,
13959        cx: &mut App,
13960    ) -> Arc<Self> {
13961        Self::new(
13962            local.languages.clone(),
13963            &local.environment,
13964            local.weak.clone(),
13965            worktree,
13966            local.http_client.clone(),
13967            local.fs.clone(),
13968            cx,
13969        )
13970    }
13971}
13972
13973#[async_trait]
13974impl LspAdapterDelegate for LocalLspAdapterDelegate {
13975    fn show_notification(&self, message: &str, cx: &mut App) {
13976        self.lsp_store
13977            .update(cx, |_, cx| {
13978                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13979            })
13980            .ok();
13981    }
13982
13983    fn http_client(&self) -> Arc<dyn HttpClient> {
13984        self.http_client.clone()
13985    }
13986
13987    fn worktree_id(&self) -> WorktreeId {
13988        self.worktree.id()
13989    }
13990
13991    fn worktree_root_path(&self) -> &Path {
13992        self.worktree.abs_path().as_ref()
13993    }
13994
13995    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13996        self.worktree.resolve_executable_path(path)
13997    }
13998
13999    async fn shell_env(&self) -> HashMap<String, String> {
14000        let task = self.load_shell_env_task.clone();
14001        task.await.unwrap_or_default()
14002    }
14003
14004    async fn npm_package_installed_version(
14005        &self,
14006        package_name: &str,
14007    ) -> Result<Option<(PathBuf, Version)>> {
14008        let local_package_directory = self.worktree_root_path();
14009        let node_modules_directory = local_package_directory.join("node_modules");
14010
14011        if let Some(version) =
14012            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14013        {
14014            return Ok(Some((node_modules_directory, version)));
14015        }
14016        let Some(npm) = self.which("npm".as_ref()).await else {
14017            log::warn!(
14018                "Failed to find npm executable for {:?}",
14019                local_package_directory
14020            );
14021            return Ok(None);
14022        };
14023
14024        let env = self.shell_env().await;
14025        let output = util::command::new_smol_command(&npm)
14026            .args(["root", "-g"])
14027            .envs(env)
14028            .current_dir(local_package_directory)
14029            .output()
14030            .await?;
14031        let global_node_modules =
14032            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14033
14034        if let Some(version) =
14035            read_package_installed_version(global_node_modules.clone(), package_name).await?
14036        {
14037            return Ok(Some((global_node_modules, version)));
14038        }
14039        return Ok(None);
14040    }
14041
14042    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14043        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14044        if self.fs.is_file(&worktree_abs_path).await {
14045            worktree_abs_path.pop();
14046        }
14047
14048        let env = self.shell_env().await;
14049
14050        let shell_path = env.get("PATH").cloned();
14051
14052        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14053    }
14054
14055    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14056        let mut working_dir = self.worktree_root_path().to_path_buf();
14057        if self.fs.is_file(&working_dir).await {
14058            working_dir.pop();
14059        }
14060        let output = util::command::new_smol_command(&command.path)
14061            .args(command.arguments)
14062            .envs(command.env.clone().unwrap_or_default())
14063            .current_dir(working_dir)
14064            .output()
14065            .await?;
14066
14067        anyhow::ensure!(
14068            output.status.success(),
14069            "{}, stdout: {:?}, stderr: {:?}",
14070            output.status,
14071            String::from_utf8_lossy(&output.stdout),
14072            String::from_utf8_lossy(&output.stderr)
14073        );
14074        Ok(())
14075    }
14076
14077    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14078        self.language_registry
14079            .update_lsp_binary_status(server_name, status);
14080    }
14081
14082    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14083        self.language_registry
14084            .all_lsp_adapters()
14085            .into_iter()
14086            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14087            .collect()
14088    }
14089
14090    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14091        let dir = self.language_registry.language_server_download_dir(name)?;
14092
14093        if !dir.exists() {
14094            smol::fs::create_dir_all(&dir)
14095                .await
14096                .context("failed to create container directory")
14097                .log_err()?;
14098        }
14099
14100        Some(dir)
14101    }
14102
14103    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14104        let entry = self
14105            .worktree
14106            .entry_for_path(path)
14107            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14108        let abs_path = self.worktree.absolutize(&entry.path);
14109        self.fs.load(&abs_path).await
14110    }
14111}
14112
14113async fn populate_labels_for_symbols(
14114    symbols: Vec<CoreSymbol>,
14115    language_registry: &Arc<LanguageRegistry>,
14116    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14117    output: &mut Vec<Symbol>,
14118) {
14119    #[allow(clippy::mutable_key_type)]
14120    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14121
14122    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14123    for symbol in symbols {
14124        let Some(file_name) = symbol.path.file_name() else {
14125            continue;
14126        };
14127        let language = language_registry
14128            .load_language_for_file_path(Path::new(file_name))
14129            .await
14130            .ok()
14131            .or_else(|| {
14132                unknown_paths.insert(file_name.into());
14133                None
14134            });
14135        symbols_by_language
14136            .entry(language)
14137            .or_default()
14138            .push(symbol);
14139    }
14140
14141    for unknown_path in unknown_paths {
14142        log::info!("no language found for symbol in file {unknown_path:?}");
14143    }
14144
14145    let mut label_params = Vec::new();
14146    for (language, mut symbols) in symbols_by_language {
14147        label_params.clear();
14148        label_params.extend(
14149            symbols
14150                .iter_mut()
14151                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14152        );
14153
14154        let mut labels = Vec::new();
14155        if let Some(language) = language {
14156            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14157                language_registry
14158                    .lsp_adapters(&language.name())
14159                    .first()
14160                    .cloned()
14161            });
14162            if let Some(lsp_adapter) = lsp_adapter {
14163                labels = lsp_adapter
14164                    .labels_for_symbols(&label_params, &language)
14165                    .await
14166                    .log_err()
14167                    .unwrap_or_default();
14168            }
14169        }
14170
14171        for ((symbol, (name, _)), label) in symbols
14172            .into_iter()
14173            .zip(label_params.drain(..))
14174            .zip(labels.into_iter().chain(iter::repeat(None)))
14175        {
14176            output.push(Symbol {
14177                language_server_name: symbol.language_server_name,
14178                source_worktree_id: symbol.source_worktree_id,
14179                source_language_server_id: symbol.source_language_server_id,
14180                path: symbol.path,
14181                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14182                name,
14183                kind: symbol.kind,
14184                range: symbol.range,
14185            });
14186        }
14187    }
14188}
14189
14190fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14191    match server.capabilities().text_document_sync.as_ref()? {
14192        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14193            // Server wants didSave but didn't specify includeText.
14194            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14195            // Server doesn't want didSave at all.
14196            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14197            // Server provided SaveOptions.
14198            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14199                Some(save_options.include_text.unwrap_or(false))
14200            }
14201        },
14202        // We do not have any save info. Kind affects didChange only.
14203        lsp::TextDocumentSyncCapability::Kind(_) => None,
14204    }
14205}
14206
14207/// Completion items are displayed in a `UniformList`.
14208/// Usually, those items are single-line strings, but in LSP responses,
14209/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14210/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14211/// 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,
14212/// breaking the completions menu presentation.
14213///
14214/// 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.
14215fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14216    let mut new_text = String::with_capacity(label.text.len());
14217    let mut offset_map = vec![0; label.text.len() + 1];
14218    let mut last_char_was_space = false;
14219    let mut new_idx = 0;
14220    let chars = label.text.char_indices().fuse();
14221    let mut newlines_removed = false;
14222
14223    for (idx, c) in chars {
14224        offset_map[idx] = new_idx;
14225
14226        match c {
14227            '\n' if last_char_was_space => {
14228                newlines_removed = true;
14229            }
14230            '\t' | ' ' if last_char_was_space => {}
14231            '\n' if !last_char_was_space => {
14232                new_text.push(' ');
14233                new_idx += 1;
14234                last_char_was_space = true;
14235                newlines_removed = true;
14236            }
14237            ' ' | '\t' => {
14238                new_text.push(' ');
14239                new_idx += 1;
14240                last_char_was_space = true;
14241            }
14242            _ => {
14243                new_text.push(c);
14244                new_idx += c.len_utf8();
14245                last_char_was_space = false;
14246            }
14247        }
14248    }
14249    offset_map[label.text.len()] = new_idx;
14250
14251    // Only modify the label if newlines were removed.
14252    if !newlines_removed {
14253        return;
14254    }
14255
14256    let last_index = new_idx;
14257    let mut run_ranges_errors = Vec::new();
14258    label.runs.retain_mut(|(range, _)| {
14259        match offset_map.get(range.start) {
14260            Some(&start) => range.start = start,
14261            None => {
14262                run_ranges_errors.push(range.clone());
14263                return false;
14264            }
14265        }
14266
14267        match offset_map.get(range.end) {
14268            Some(&end) => range.end = end,
14269            None => {
14270                run_ranges_errors.push(range.clone());
14271                range.end = last_index;
14272            }
14273        }
14274        true
14275    });
14276    if !run_ranges_errors.is_empty() {
14277        log::error!(
14278            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14279            label.text
14280        );
14281    }
14282
14283    let mut wrong_filter_range = None;
14284    if label.filter_range == (0..label.text.len()) {
14285        label.filter_range = 0..new_text.len();
14286    } else {
14287        let mut original_filter_range = Some(label.filter_range.clone());
14288        match offset_map.get(label.filter_range.start) {
14289            Some(&start) => label.filter_range.start = start,
14290            None => {
14291                wrong_filter_range = original_filter_range.take();
14292                label.filter_range.start = last_index;
14293            }
14294        }
14295
14296        match offset_map.get(label.filter_range.end) {
14297            Some(&end) => label.filter_range.end = end,
14298            None => {
14299                wrong_filter_range = original_filter_range.take();
14300                label.filter_range.end = last_index;
14301            }
14302        }
14303    }
14304    if let Some(wrong_filter_range) = wrong_filter_range {
14305        log::error!(
14306            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14307            label.text
14308        );
14309    }
14310
14311    label.text = new_text;
14312}
14313
14314#[cfg(test)]
14315mod tests {
14316    use language::HighlightId;
14317
14318    use super::*;
14319
14320    #[test]
14321    fn test_glob_literal_prefix() {
14322        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14323        assert_eq!(
14324            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14325            Path::new("node_modules")
14326        );
14327        assert_eq!(
14328            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14329            Path::new("foo")
14330        );
14331        assert_eq!(
14332            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14333            Path::new("foo/bar/baz.js")
14334        );
14335
14336        #[cfg(target_os = "windows")]
14337        {
14338            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14339            assert_eq!(
14340                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14341                Path::new("node_modules")
14342            );
14343            assert_eq!(
14344                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14345                Path::new("foo")
14346            );
14347            assert_eq!(
14348                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14349                Path::new("foo/bar/baz.js")
14350            );
14351        }
14352    }
14353
14354    #[test]
14355    fn test_multi_len_chars_normalization() {
14356        let mut label = CodeLabel::new(
14357            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14358            0..6,
14359            vec![(0..6, HighlightId(1))],
14360        );
14361        ensure_uniform_list_compatible_label(&mut label);
14362        assert_eq!(
14363            label,
14364            CodeLabel::new(
14365                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14366                0..6,
14367                vec![(0..6, HighlightId(1))],
14368            )
14369        );
14370    }
14371}