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, Capability, CodeLabel,
   65    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   66    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   67    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   68    Toolchain, 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 = lsp_store.update(cx, |lsp_store, cx| {
 8694                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8695                    worktree_store.find_worktree(&worktree_root_target, cx)
 8696                })
 8697            })?;
 8698            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8699                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8700                (result.0, relative_path, None)
 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                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8710                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8711                    lsp_store
 8712                        .update(cx, |lsp_store, cx| {
 8713                            if let Some(local) = lsp_store.as_local_mut() {
 8714                                local.register_language_server_for_invisible_worktree(
 8715                                    &worktree,
 8716                                    language_server_id,
 8717                                    cx,
 8718                                )
 8719                            }
 8720                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8721                                Some(status) => status.worktree,
 8722                                None => None,
 8723                            }
 8724                        })
 8725                        .ok()
 8726                        .flatten()
 8727                        .zip(Some(worktree_root.clone()))
 8728                } else {
 8729                    None
 8730                };
 8731                let relative_path = if let Some(known_path) = known_relative_path {
 8732                    known_path
 8733                } else {
 8734                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8735                        .into_arc()
 8736                };
 8737                (worktree, relative_path, source_ws)
 8738            };
 8739            let project_path = ProjectPath {
 8740                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8741                path: relative_path,
 8742            };
 8743            let buffer = lsp_store
 8744                .update(cx, |lsp_store, cx| {
 8745                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8746                        buffer_store.open_buffer(project_path, cx)
 8747                    })
 8748                })?
 8749                .await?;
 8750            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8751            if let Some((source_ws, worktree_root)) = source_ws {
 8752                buffer.update(cx, |buffer, cx| {
 8753                    let settings = WorktreeSettings::get(
 8754                        Some(
 8755                            (&ProjectPath {
 8756                                worktree_id: source_ws,
 8757                                path: Arc::from(RelPath::empty()),
 8758                            })
 8759                                .into(),
 8760                        ),
 8761                        cx,
 8762                    );
 8763                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8764                    if is_read_only {
 8765                        buffer.set_capability(Capability::ReadOnly, cx);
 8766                    }
 8767                })?;
 8768            }
 8769            Ok(buffer)
 8770        })
 8771    }
 8772
 8773    fn request_multiple_lsp_locally<P, R>(
 8774        &mut self,
 8775        buffer: &Entity<Buffer>,
 8776        position: Option<P>,
 8777        request: R,
 8778        cx: &mut Context<Self>,
 8779    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8780    where
 8781        P: ToOffset,
 8782        R: LspCommand + Clone,
 8783        <R::LspRequest as lsp::request::Request>::Result: Send,
 8784        <R::LspRequest as lsp::request::Request>::Params: Send,
 8785    {
 8786        let Some(local) = self.as_local() else {
 8787            return Task::ready(Vec::new());
 8788        };
 8789
 8790        let snapshot = buffer.read(cx).snapshot();
 8791        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8792
 8793        let server_ids = buffer.update(cx, |buffer, cx| {
 8794            local
 8795                .language_servers_for_buffer(buffer, cx)
 8796                .filter(|(adapter, _)| {
 8797                    scope
 8798                        .as_ref()
 8799                        .map(|scope| scope.language_allowed(&adapter.name))
 8800                        .unwrap_or(true)
 8801                })
 8802                .map(|(_, server)| server.server_id())
 8803                .filter(|server_id| {
 8804                    self.as_local().is_none_or(|local| {
 8805                        local
 8806                            .buffers_opened_in_servers
 8807                            .get(&snapshot.remote_id())
 8808                            .is_some_and(|servers| servers.contains(server_id))
 8809                    })
 8810                })
 8811                .collect::<Vec<_>>()
 8812        });
 8813
 8814        let mut response_results = server_ids
 8815            .into_iter()
 8816            .map(|server_id| {
 8817                let task = self.request_lsp(
 8818                    buffer.clone(),
 8819                    LanguageServerToQuery::Other(server_id),
 8820                    request.clone(),
 8821                    cx,
 8822                );
 8823                async move { (server_id, task.await) }
 8824            })
 8825            .collect::<FuturesUnordered<_>>();
 8826
 8827        cx.background_spawn(async move {
 8828            let mut responses = Vec::with_capacity(response_results.len());
 8829            while let Some((server_id, response_result)) = response_results.next().await {
 8830                match response_result {
 8831                    Ok(response) => responses.push((server_id, response)),
 8832                    // rust-analyzer likes to error with this when its still loading up
 8833                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8834                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8835                }
 8836            }
 8837            responses
 8838        })
 8839    }
 8840
 8841    async fn handle_lsp_get_completions(
 8842        this: Entity<Self>,
 8843        envelope: TypedEnvelope<proto::GetCompletions>,
 8844        mut cx: AsyncApp,
 8845    ) -> Result<proto::GetCompletionsResponse> {
 8846        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8847
 8848        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8849        let buffer_handle = this.update(&mut cx, |this, cx| {
 8850            this.buffer_store.read(cx).get_existing(buffer_id)
 8851        })??;
 8852        let request = GetCompletions::from_proto(
 8853            envelope.payload,
 8854            this.clone(),
 8855            buffer_handle.clone(),
 8856            cx.clone(),
 8857        )
 8858        .await?;
 8859
 8860        let server_to_query = match request.server_id {
 8861            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8862            None => LanguageServerToQuery::FirstCapable,
 8863        };
 8864
 8865        let response = this
 8866            .update(&mut cx, |this, cx| {
 8867                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8868            })?
 8869            .await?;
 8870        this.update(&mut cx, |this, cx| {
 8871            Ok(GetCompletions::response_to_proto(
 8872                response,
 8873                this,
 8874                sender_id,
 8875                &buffer_handle.read(cx).version(),
 8876                cx,
 8877            ))
 8878        })?
 8879    }
 8880
 8881    async fn handle_lsp_command<T: LspCommand>(
 8882        this: Entity<Self>,
 8883        envelope: TypedEnvelope<T::ProtoRequest>,
 8884        mut cx: AsyncApp,
 8885    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8886    where
 8887        <T::LspRequest as lsp::request::Request>::Params: Send,
 8888        <T::LspRequest as lsp::request::Request>::Result: Send,
 8889    {
 8890        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8891        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8892        let buffer_handle = this.update(&mut cx, |this, cx| {
 8893            this.buffer_store.read(cx).get_existing(buffer_id)
 8894        })??;
 8895        let request = T::from_proto(
 8896            envelope.payload,
 8897            this.clone(),
 8898            buffer_handle.clone(),
 8899            cx.clone(),
 8900        )
 8901        .await?;
 8902        let response = this
 8903            .update(&mut cx, |this, cx| {
 8904                this.request_lsp(
 8905                    buffer_handle.clone(),
 8906                    LanguageServerToQuery::FirstCapable,
 8907                    request,
 8908                    cx,
 8909                )
 8910            })?
 8911            .await?;
 8912        this.update(&mut cx, |this, cx| {
 8913            Ok(T::response_to_proto(
 8914                response,
 8915                this,
 8916                sender_id,
 8917                &buffer_handle.read(cx).version(),
 8918                cx,
 8919            ))
 8920        })?
 8921    }
 8922
 8923    async fn handle_lsp_query(
 8924        lsp_store: Entity<Self>,
 8925        envelope: TypedEnvelope<proto::LspQuery>,
 8926        mut cx: AsyncApp,
 8927    ) -> Result<proto::Ack> {
 8928        use proto::lsp_query::Request;
 8929        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8930        let lsp_query = envelope.payload;
 8931        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8932        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8933        match lsp_query.request.context("invalid LSP query request")? {
 8934            Request::GetReferences(get_references) => {
 8935                let position = get_references.position.clone().and_then(deserialize_anchor);
 8936                Self::query_lsp_locally::<GetReferences>(
 8937                    lsp_store,
 8938                    server_id,
 8939                    sender_id,
 8940                    lsp_request_id,
 8941                    get_references,
 8942                    position,
 8943                    &mut cx,
 8944                )
 8945                .await?;
 8946            }
 8947            Request::GetDocumentColor(get_document_color) => {
 8948                Self::query_lsp_locally::<GetDocumentColor>(
 8949                    lsp_store,
 8950                    server_id,
 8951                    sender_id,
 8952                    lsp_request_id,
 8953                    get_document_color,
 8954                    None,
 8955                    &mut cx,
 8956                )
 8957                .await?;
 8958            }
 8959            Request::GetHover(get_hover) => {
 8960                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8961                Self::query_lsp_locally::<GetHover>(
 8962                    lsp_store,
 8963                    server_id,
 8964                    sender_id,
 8965                    lsp_request_id,
 8966                    get_hover,
 8967                    position,
 8968                    &mut cx,
 8969                )
 8970                .await?;
 8971            }
 8972            Request::GetCodeActions(get_code_actions) => {
 8973                Self::query_lsp_locally::<GetCodeActions>(
 8974                    lsp_store,
 8975                    server_id,
 8976                    sender_id,
 8977                    lsp_request_id,
 8978                    get_code_actions,
 8979                    None,
 8980                    &mut cx,
 8981                )
 8982                .await?;
 8983            }
 8984            Request::GetSignatureHelp(get_signature_help) => {
 8985                let position = get_signature_help
 8986                    .position
 8987                    .clone()
 8988                    .and_then(deserialize_anchor);
 8989                Self::query_lsp_locally::<GetSignatureHelp>(
 8990                    lsp_store,
 8991                    server_id,
 8992                    sender_id,
 8993                    lsp_request_id,
 8994                    get_signature_help,
 8995                    position,
 8996                    &mut cx,
 8997                )
 8998                .await?;
 8999            }
 9000            Request::GetCodeLens(get_code_lens) => {
 9001                Self::query_lsp_locally::<GetCodeLens>(
 9002                    lsp_store,
 9003                    server_id,
 9004                    sender_id,
 9005                    lsp_request_id,
 9006                    get_code_lens,
 9007                    None,
 9008                    &mut cx,
 9009                )
 9010                .await?;
 9011            }
 9012            Request::GetDefinition(get_definition) => {
 9013                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9014                Self::query_lsp_locally::<GetDefinitions>(
 9015                    lsp_store,
 9016                    server_id,
 9017                    sender_id,
 9018                    lsp_request_id,
 9019                    get_definition,
 9020                    position,
 9021                    &mut cx,
 9022                )
 9023                .await?;
 9024            }
 9025            Request::GetDeclaration(get_declaration) => {
 9026                let position = get_declaration
 9027                    .position
 9028                    .clone()
 9029                    .and_then(deserialize_anchor);
 9030                Self::query_lsp_locally::<GetDeclarations>(
 9031                    lsp_store,
 9032                    server_id,
 9033                    sender_id,
 9034                    lsp_request_id,
 9035                    get_declaration,
 9036                    position,
 9037                    &mut cx,
 9038                )
 9039                .await?;
 9040            }
 9041            Request::GetTypeDefinition(get_type_definition) => {
 9042                let position = get_type_definition
 9043                    .position
 9044                    .clone()
 9045                    .and_then(deserialize_anchor);
 9046                Self::query_lsp_locally::<GetTypeDefinitions>(
 9047                    lsp_store,
 9048                    server_id,
 9049                    sender_id,
 9050                    lsp_request_id,
 9051                    get_type_definition,
 9052                    position,
 9053                    &mut cx,
 9054                )
 9055                .await?;
 9056            }
 9057            Request::GetImplementation(get_implementation) => {
 9058                let position = get_implementation
 9059                    .position
 9060                    .clone()
 9061                    .and_then(deserialize_anchor);
 9062                Self::query_lsp_locally::<GetImplementations>(
 9063                    lsp_store,
 9064                    server_id,
 9065                    sender_id,
 9066                    lsp_request_id,
 9067                    get_implementation,
 9068                    position,
 9069                    &mut cx,
 9070                )
 9071                .await?;
 9072            }
 9073            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9074                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9075                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9076                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9077                    this.buffer_store.read(cx).get_existing(buffer_id)
 9078                })??;
 9079                buffer
 9080                    .update(&mut cx, |buffer, _| {
 9081                        buffer.wait_for_version(version.clone())
 9082                    })?
 9083                    .await?;
 9084                lsp_store.update(&mut cx, |lsp_store, cx| {
 9085                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9086                    let key = LspKey {
 9087                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9088                        server_queried: server_id,
 9089                    };
 9090                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9091                    ) {
 9092                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9093                            lsp_requests.clear();
 9094                        };
 9095                    }
 9096
 9097                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9098                    existing_queries.insert(
 9099                        lsp_request_id,
 9100                        cx.spawn(async move |lsp_store, cx| {
 9101                            let diagnostics_pull = lsp_store
 9102                                .update(cx, |lsp_store, cx| {
 9103                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9104                                })
 9105                                .ok();
 9106                            if let Some(diagnostics_pull) = diagnostics_pull {
 9107                                match diagnostics_pull.await {
 9108                                    Ok(()) => {}
 9109                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9110                                };
 9111                            }
 9112                        }),
 9113                    );
 9114                })?;
 9115            }
 9116            Request::InlayHints(inlay_hints) => {
 9117                let query_start = inlay_hints
 9118                    .start
 9119                    .clone()
 9120                    .and_then(deserialize_anchor)
 9121                    .context("invalid inlay hints range start")?;
 9122                let query_end = inlay_hints
 9123                    .end
 9124                    .clone()
 9125                    .and_then(deserialize_anchor)
 9126                    .context("invalid inlay hints range end")?;
 9127                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9128                    &lsp_store,
 9129                    server_id,
 9130                    lsp_request_id,
 9131                    &inlay_hints,
 9132                    query_start..query_end,
 9133                    &mut cx,
 9134                )
 9135                .await
 9136                .context("preparing inlay hints request")?;
 9137                Self::query_lsp_locally::<InlayHints>(
 9138                    lsp_store,
 9139                    server_id,
 9140                    sender_id,
 9141                    lsp_request_id,
 9142                    inlay_hints,
 9143                    None,
 9144                    &mut cx,
 9145                )
 9146                .await
 9147                .context("querying for inlay hints")?
 9148            }
 9149        }
 9150        Ok(proto::Ack {})
 9151    }
 9152
 9153    async fn handle_lsp_query_response(
 9154        lsp_store: Entity<Self>,
 9155        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9156        cx: AsyncApp,
 9157    ) -> Result<()> {
 9158        lsp_store.read_with(&cx, |lsp_store, _| {
 9159            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9160                upstream_client.handle_lsp_response(envelope.clone());
 9161            }
 9162        })?;
 9163        Ok(())
 9164    }
 9165
 9166    async fn handle_apply_code_action(
 9167        this: Entity<Self>,
 9168        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9169        mut cx: AsyncApp,
 9170    ) -> Result<proto::ApplyCodeActionResponse> {
 9171        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9172        let action =
 9173            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9174        let apply_code_action = this.update(&mut cx, |this, cx| {
 9175            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9176            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9177            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9178        })??;
 9179
 9180        let project_transaction = apply_code_action.await?;
 9181        let project_transaction = this.update(&mut cx, |this, cx| {
 9182            this.buffer_store.update(cx, |buffer_store, cx| {
 9183                buffer_store.serialize_project_transaction_for_peer(
 9184                    project_transaction,
 9185                    sender_id,
 9186                    cx,
 9187                )
 9188            })
 9189        })?;
 9190        Ok(proto::ApplyCodeActionResponse {
 9191            transaction: Some(project_transaction),
 9192        })
 9193    }
 9194
 9195    async fn handle_register_buffer_with_language_servers(
 9196        this: Entity<Self>,
 9197        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9198        mut cx: AsyncApp,
 9199    ) -> Result<proto::Ack> {
 9200        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9201        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9202        this.update(&mut cx, |this, cx| {
 9203            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9204                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9205                    project_id: upstream_project_id,
 9206                    buffer_id: buffer_id.to_proto(),
 9207                    only_servers: envelope.payload.only_servers,
 9208                });
 9209            }
 9210
 9211            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9212                anyhow::bail!("buffer is not open");
 9213            };
 9214
 9215            let handle = this.register_buffer_with_language_servers(
 9216                &buffer,
 9217                envelope
 9218                    .payload
 9219                    .only_servers
 9220                    .into_iter()
 9221                    .filter_map(|selector| {
 9222                        Some(match selector.selector? {
 9223                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9224                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9225                            }
 9226                            proto::language_server_selector::Selector::Name(name) => {
 9227                                LanguageServerSelector::Name(LanguageServerName(
 9228                                    SharedString::from(name),
 9229                                ))
 9230                            }
 9231                        })
 9232                    })
 9233                    .collect(),
 9234                false,
 9235                cx,
 9236            );
 9237            this.buffer_store().update(cx, |buffer_store, _| {
 9238                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9239            });
 9240
 9241            Ok(())
 9242        })??;
 9243        Ok(proto::Ack {})
 9244    }
 9245
 9246    async fn handle_rename_project_entry(
 9247        this: Entity<Self>,
 9248        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9249        mut cx: AsyncApp,
 9250    ) -> Result<proto::ProjectEntryResponse> {
 9251        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9252        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9253        let new_path =
 9254            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9255
 9256        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9257            .update(&mut cx, |this, cx| {
 9258                let (worktree, entry) = this
 9259                    .worktree_store
 9260                    .read(cx)
 9261                    .worktree_and_entry_for_id(entry_id, cx)?;
 9262                let new_worktree = this
 9263                    .worktree_store
 9264                    .read(cx)
 9265                    .worktree_for_id(new_worktree_id, cx)?;
 9266                Some((
 9267                    this.worktree_store.clone(),
 9268                    worktree,
 9269                    new_worktree,
 9270                    entry.clone(),
 9271                ))
 9272            })?
 9273            .context("worktree not found")?;
 9274        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9275            (worktree.absolutize(&old_entry.path), worktree.id())
 9276        })?;
 9277        let new_abs_path =
 9278            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9279
 9280        let _transaction = Self::will_rename_entry(
 9281            this.downgrade(),
 9282            old_worktree_id,
 9283            &old_abs_path,
 9284            &new_abs_path,
 9285            old_entry.is_dir(),
 9286            cx.clone(),
 9287        )
 9288        .await;
 9289        let response = WorktreeStore::handle_rename_project_entry(
 9290            worktree_store,
 9291            envelope.payload,
 9292            cx.clone(),
 9293        )
 9294        .await;
 9295        this.read_with(&cx, |this, _| {
 9296            this.did_rename_entry(
 9297                old_worktree_id,
 9298                &old_abs_path,
 9299                &new_abs_path,
 9300                old_entry.is_dir(),
 9301            );
 9302        })
 9303        .ok();
 9304        response
 9305    }
 9306
 9307    async fn handle_update_diagnostic_summary(
 9308        this: Entity<Self>,
 9309        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9310        mut cx: AsyncApp,
 9311    ) -> Result<()> {
 9312        this.update(&mut cx, |lsp_store, cx| {
 9313            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9314            let mut updated_diagnostics_paths = HashMap::default();
 9315            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9316            for message_summary in envelope
 9317                .payload
 9318                .summary
 9319                .into_iter()
 9320                .chain(envelope.payload.more_summaries)
 9321            {
 9322                let project_path = ProjectPath {
 9323                    worktree_id,
 9324                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9325                };
 9326                let path = project_path.path.clone();
 9327                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9328                let summary = DiagnosticSummary {
 9329                    error_count: message_summary.error_count as usize,
 9330                    warning_count: message_summary.warning_count as usize,
 9331                };
 9332
 9333                if summary.is_empty() {
 9334                    if let Some(worktree_summaries) =
 9335                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9336                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9337                    {
 9338                        summaries.remove(&server_id);
 9339                        if summaries.is_empty() {
 9340                            worktree_summaries.remove(&path);
 9341                        }
 9342                    }
 9343                } else {
 9344                    lsp_store
 9345                        .diagnostic_summaries
 9346                        .entry(worktree_id)
 9347                        .or_default()
 9348                        .entry(path)
 9349                        .or_default()
 9350                        .insert(server_id, summary);
 9351                }
 9352
 9353                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9354                    match &mut diagnostics_summary {
 9355                        Some(diagnostics_summary) => {
 9356                            diagnostics_summary
 9357                                .more_summaries
 9358                                .push(proto::DiagnosticSummary {
 9359                                    path: project_path.path.as_ref().to_proto(),
 9360                                    language_server_id: server_id.0 as u64,
 9361                                    error_count: summary.error_count as u32,
 9362                                    warning_count: summary.warning_count as u32,
 9363                                })
 9364                        }
 9365                        None => {
 9366                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9367                                project_id: *project_id,
 9368                                worktree_id: worktree_id.to_proto(),
 9369                                summary: Some(proto::DiagnosticSummary {
 9370                                    path: project_path.path.as_ref().to_proto(),
 9371                                    language_server_id: server_id.0 as u64,
 9372                                    error_count: summary.error_count as u32,
 9373                                    warning_count: summary.warning_count as u32,
 9374                                }),
 9375                                more_summaries: Vec::new(),
 9376                            })
 9377                        }
 9378                    }
 9379                }
 9380                updated_diagnostics_paths
 9381                    .entry(server_id)
 9382                    .or_insert_with(Vec::new)
 9383                    .push(project_path);
 9384            }
 9385
 9386            if let Some((diagnostics_summary, (downstream_client, _))) =
 9387                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9388            {
 9389                downstream_client.send(diagnostics_summary).log_err();
 9390            }
 9391            for (server_id, paths) in updated_diagnostics_paths {
 9392                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9393            }
 9394            Ok(())
 9395        })?
 9396    }
 9397
 9398    async fn handle_start_language_server(
 9399        lsp_store: Entity<Self>,
 9400        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9401        mut cx: AsyncApp,
 9402    ) -> Result<()> {
 9403        let server = envelope.payload.server.context("invalid server")?;
 9404        let server_capabilities =
 9405            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9406                .with_context(|| {
 9407                    format!(
 9408                        "incorrect server capabilities {}",
 9409                        envelope.payload.capabilities
 9410                    )
 9411                })?;
 9412        lsp_store.update(&mut cx, |lsp_store, cx| {
 9413            let server_id = LanguageServerId(server.id as usize);
 9414            let server_name = LanguageServerName::from_proto(server.name.clone());
 9415            lsp_store
 9416                .lsp_server_capabilities
 9417                .insert(server_id, server_capabilities);
 9418            lsp_store.language_server_statuses.insert(
 9419                server_id,
 9420                LanguageServerStatus {
 9421                    name: server_name.clone(),
 9422                    server_version: None,
 9423                    pending_work: Default::default(),
 9424                    has_pending_diagnostic_updates: false,
 9425                    progress_tokens: Default::default(),
 9426                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9427                    binary: None,
 9428                    configuration: None,
 9429                    workspace_folders: BTreeSet::new(),
 9430                },
 9431            );
 9432            cx.emit(LspStoreEvent::LanguageServerAdded(
 9433                server_id,
 9434                server_name,
 9435                server.worktree_id.map(WorktreeId::from_proto),
 9436            ));
 9437            cx.notify();
 9438        })?;
 9439        Ok(())
 9440    }
 9441
 9442    async fn handle_update_language_server(
 9443        lsp_store: Entity<Self>,
 9444        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9445        mut cx: AsyncApp,
 9446    ) -> Result<()> {
 9447        lsp_store.update(&mut cx, |lsp_store, cx| {
 9448            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9449
 9450            match envelope.payload.variant.context("invalid variant")? {
 9451                proto::update_language_server::Variant::WorkStart(payload) => {
 9452                    lsp_store.on_lsp_work_start(
 9453                        language_server_id,
 9454                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9455                            .context("invalid progress token value")?,
 9456                        LanguageServerProgress {
 9457                            title: payload.title,
 9458                            is_disk_based_diagnostics_progress: false,
 9459                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9460                            message: payload.message,
 9461                            percentage: payload.percentage.map(|p| p as usize),
 9462                            last_update_at: cx.background_executor().now(),
 9463                        },
 9464                        cx,
 9465                    );
 9466                }
 9467                proto::update_language_server::Variant::WorkProgress(payload) => {
 9468                    lsp_store.on_lsp_work_progress(
 9469                        language_server_id,
 9470                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9471                            .context("invalid progress token value")?,
 9472                        LanguageServerProgress {
 9473                            title: None,
 9474                            is_disk_based_diagnostics_progress: false,
 9475                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9476                            message: payload.message,
 9477                            percentage: payload.percentage.map(|p| p as usize),
 9478                            last_update_at: cx.background_executor().now(),
 9479                        },
 9480                        cx,
 9481                    );
 9482                }
 9483
 9484                proto::update_language_server::Variant::WorkEnd(payload) => {
 9485                    lsp_store.on_lsp_work_end(
 9486                        language_server_id,
 9487                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9488                            .context("invalid progress token value")?,
 9489                        cx,
 9490                    );
 9491                }
 9492
 9493                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9494                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9495                }
 9496
 9497                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9498                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9499                }
 9500
 9501                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9502                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9503                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9504                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9505                        language_server_id,
 9506                        name: envelope
 9507                            .payload
 9508                            .server_name
 9509                            .map(SharedString::new)
 9510                            .map(LanguageServerName),
 9511                        message: non_lsp,
 9512                    });
 9513                }
 9514            }
 9515
 9516            Ok(())
 9517        })?
 9518    }
 9519
 9520    async fn handle_language_server_log(
 9521        this: Entity<Self>,
 9522        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9523        mut cx: AsyncApp,
 9524    ) -> Result<()> {
 9525        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9526        let log_type = envelope
 9527            .payload
 9528            .log_type
 9529            .map(LanguageServerLogType::from_proto)
 9530            .context("invalid language server log type")?;
 9531
 9532        let message = envelope.payload.message;
 9533
 9534        this.update(&mut cx, |_, cx| {
 9535            cx.emit(LspStoreEvent::LanguageServerLog(
 9536                language_server_id,
 9537                log_type,
 9538                message,
 9539            ));
 9540        })
 9541    }
 9542
 9543    async fn handle_lsp_ext_cancel_flycheck(
 9544        lsp_store: Entity<Self>,
 9545        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9546        cx: AsyncApp,
 9547    ) -> Result<proto::Ack> {
 9548        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9549        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9550            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9551                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9552            } else {
 9553                None
 9554            }
 9555        })?;
 9556        if let Some(task) = task {
 9557            task.context("handling lsp ext cancel flycheck")?;
 9558        }
 9559
 9560        Ok(proto::Ack {})
 9561    }
 9562
 9563    async fn handle_lsp_ext_run_flycheck(
 9564        lsp_store: Entity<Self>,
 9565        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9566        mut cx: AsyncApp,
 9567    ) -> Result<proto::Ack> {
 9568        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9569        lsp_store.update(&mut cx, |lsp_store, cx| {
 9570            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9571                let text_document = if envelope.payload.current_file_only {
 9572                    let buffer_id = envelope
 9573                        .payload
 9574                        .buffer_id
 9575                        .map(|id| BufferId::new(id))
 9576                        .transpose()?;
 9577                    buffer_id
 9578                        .and_then(|buffer_id| {
 9579                            lsp_store
 9580                                .buffer_store()
 9581                                .read(cx)
 9582                                .get(buffer_id)
 9583                                .and_then(|buffer| {
 9584                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9585                                })
 9586                                .map(|path| make_text_document_identifier(&path))
 9587                        })
 9588                        .transpose()?
 9589                } else {
 9590                    None
 9591                };
 9592                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9593                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9594                )?;
 9595            }
 9596            anyhow::Ok(())
 9597        })??;
 9598
 9599        Ok(proto::Ack {})
 9600    }
 9601
 9602    async fn handle_lsp_ext_clear_flycheck(
 9603        lsp_store: Entity<Self>,
 9604        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9605        cx: AsyncApp,
 9606    ) -> Result<proto::Ack> {
 9607        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9608        lsp_store
 9609            .read_with(&cx, |lsp_store, _| {
 9610                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9611                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9612                } else {
 9613                    None
 9614                }
 9615            })
 9616            .context("handling lsp ext clear flycheck")?;
 9617
 9618        Ok(proto::Ack {})
 9619    }
 9620
 9621    pub fn disk_based_diagnostics_started(
 9622        &mut self,
 9623        language_server_id: LanguageServerId,
 9624        cx: &mut Context<Self>,
 9625    ) {
 9626        if let Some(language_server_status) =
 9627            self.language_server_statuses.get_mut(&language_server_id)
 9628        {
 9629            language_server_status.has_pending_diagnostic_updates = true;
 9630        }
 9631
 9632        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9633        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9634            language_server_id,
 9635            name: self
 9636                .language_server_adapter_for_id(language_server_id)
 9637                .map(|adapter| adapter.name()),
 9638            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9639                Default::default(),
 9640            ),
 9641        })
 9642    }
 9643
 9644    pub fn disk_based_diagnostics_finished(
 9645        &mut self,
 9646        language_server_id: LanguageServerId,
 9647        cx: &mut Context<Self>,
 9648    ) {
 9649        if let Some(language_server_status) =
 9650            self.language_server_statuses.get_mut(&language_server_id)
 9651        {
 9652            language_server_status.has_pending_diagnostic_updates = false;
 9653        }
 9654
 9655        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9656        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9657            language_server_id,
 9658            name: self
 9659                .language_server_adapter_for_id(language_server_id)
 9660                .map(|adapter| adapter.name()),
 9661            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9662                Default::default(),
 9663            ),
 9664        })
 9665    }
 9666
 9667    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9668    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9669    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9670    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9671    // the language server might take some time to publish diagnostics.
 9672    fn simulate_disk_based_diagnostics_events_if_needed(
 9673        &mut self,
 9674        language_server_id: LanguageServerId,
 9675        cx: &mut Context<Self>,
 9676    ) {
 9677        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9678
 9679        let Some(LanguageServerState::Running {
 9680            simulate_disk_based_diagnostics_completion,
 9681            adapter,
 9682            ..
 9683        }) = self
 9684            .as_local_mut()
 9685            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9686        else {
 9687            return;
 9688        };
 9689
 9690        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9691            return;
 9692        }
 9693
 9694        let prev_task =
 9695            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9696                cx.background_executor()
 9697                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9698                    .await;
 9699
 9700                this.update(cx, |this, cx| {
 9701                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9702
 9703                    if let Some(LanguageServerState::Running {
 9704                        simulate_disk_based_diagnostics_completion,
 9705                        ..
 9706                    }) = this.as_local_mut().and_then(|local_store| {
 9707                        local_store.language_servers.get_mut(&language_server_id)
 9708                    }) {
 9709                        *simulate_disk_based_diagnostics_completion = None;
 9710                    }
 9711                })
 9712                .ok();
 9713            }));
 9714
 9715        if prev_task.is_none() {
 9716            self.disk_based_diagnostics_started(language_server_id, cx);
 9717        }
 9718    }
 9719
 9720    pub fn language_server_statuses(
 9721        &self,
 9722    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9723        self.language_server_statuses
 9724            .iter()
 9725            .map(|(key, value)| (*key, value))
 9726    }
 9727
 9728    pub(super) fn did_rename_entry(
 9729        &self,
 9730        worktree_id: WorktreeId,
 9731        old_path: &Path,
 9732        new_path: &Path,
 9733        is_dir: bool,
 9734    ) {
 9735        maybe!({
 9736            let local_store = self.as_local()?;
 9737
 9738            let old_uri = lsp::Uri::from_file_path(old_path)
 9739                .ok()
 9740                .map(|uri| uri.to_string())?;
 9741            let new_uri = lsp::Uri::from_file_path(new_path)
 9742                .ok()
 9743                .map(|uri| uri.to_string())?;
 9744
 9745            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9746                let Some(filter) = local_store
 9747                    .language_server_paths_watched_for_rename
 9748                    .get(&language_server.server_id())
 9749                else {
 9750                    continue;
 9751                };
 9752
 9753                if filter.should_send_did_rename(&old_uri, is_dir) {
 9754                    language_server
 9755                        .notify::<DidRenameFiles>(RenameFilesParams {
 9756                            files: vec![FileRename {
 9757                                old_uri: old_uri.clone(),
 9758                                new_uri: new_uri.clone(),
 9759                            }],
 9760                        })
 9761                        .ok();
 9762                }
 9763            }
 9764            Some(())
 9765        });
 9766    }
 9767
 9768    pub(super) fn will_rename_entry(
 9769        this: WeakEntity<Self>,
 9770        worktree_id: WorktreeId,
 9771        old_path: &Path,
 9772        new_path: &Path,
 9773        is_dir: bool,
 9774        cx: AsyncApp,
 9775    ) -> Task<ProjectTransaction> {
 9776        let old_uri = lsp::Uri::from_file_path(old_path)
 9777            .ok()
 9778            .map(|uri| uri.to_string());
 9779        let new_uri = lsp::Uri::from_file_path(new_path)
 9780            .ok()
 9781            .map(|uri| uri.to_string());
 9782        cx.spawn(async move |cx| {
 9783            let mut tasks = vec![];
 9784            this.update(cx, |this, cx| {
 9785                let local_store = this.as_local()?;
 9786                let old_uri = old_uri?;
 9787                let new_uri = new_uri?;
 9788                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9789                    let Some(filter) = local_store
 9790                        .language_server_paths_watched_for_rename
 9791                        .get(&language_server.server_id())
 9792                    else {
 9793                        continue;
 9794                    };
 9795
 9796                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9797                        let apply_edit = cx.spawn({
 9798                            let old_uri = old_uri.clone();
 9799                            let new_uri = new_uri.clone();
 9800                            let language_server = language_server.clone();
 9801                            async move |this, cx| {
 9802                                let edit = language_server
 9803                                    .request::<WillRenameFiles>(RenameFilesParams {
 9804                                        files: vec![FileRename { old_uri, new_uri }],
 9805                                    })
 9806                                    .await
 9807                                    .into_response()
 9808                                    .context("will rename files")
 9809                                    .log_err()
 9810                                    .flatten()?;
 9811
 9812                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9813                                    this.upgrade()?,
 9814                                    edit,
 9815                                    false,
 9816                                    language_server.clone(),
 9817                                    cx,
 9818                                )
 9819                                .await
 9820                                .ok()?;
 9821                                Some(transaction)
 9822                            }
 9823                        });
 9824                        tasks.push(apply_edit);
 9825                    }
 9826                }
 9827                Some(())
 9828            })
 9829            .ok()
 9830            .flatten();
 9831            let mut merged_transaction = ProjectTransaction::default();
 9832            for task in tasks {
 9833                // Await on tasks sequentially so that the order of application of edits is deterministic
 9834                // (at least with regards to the order of registration of language servers)
 9835                if let Some(transaction) = task.await {
 9836                    for (buffer, buffer_transaction) in transaction.0 {
 9837                        merged_transaction.0.insert(buffer, buffer_transaction);
 9838                    }
 9839                }
 9840            }
 9841            merged_transaction
 9842        })
 9843    }
 9844
 9845    fn lsp_notify_abs_paths_changed(
 9846        &mut self,
 9847        server_id: LanguageServerId,
 9848        changes: Vec<PathEvent>,
 9849    ) {
 9850        maybe!({
 9851            let server = self.language_server_for_id(server_id)?;
 9852            let changes = changes
 9853                .into_iter()
 9854                .filter_map(|event| {
 9855                    let typ = match event.kind? {
 9856                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9857                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9858                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9859                    };
 9860                    Some(lsp::FileEvent {
 9861                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9862                        typ,
 9863                    })
 9864                })
 9865                .collect::<Vec<_>>();
 9866            if !changes.is_empty() {
 9867                server
 9868                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9869                        lsp::DidChangeWatchedFilesParams { changes },
 9870                    )
 9871                    .ok();
 9872            }
 9873            Some(())
 9874        });
 9875    }
 9876
 9877    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9878        self.as_local()?.language_server_for_id(id)
 9879    }
 9880
 9881    fn on_lsp_progress(
 9882        &mut self,
 9883        progress_params: lsp::ProgressParams,
 9884        language_server_id: LanguageServerId,
 9885        disk_based_diagnostics_progress_token: Option<String>,
 9886        cx: &mut Context<Self>,
 9887    ) {
 9888        match progress_params.value {
 9889            lsp::ProgressParamsValue::WorkDone(progress) => {
 9890                self.handle_work_done_progress(
 9891                    progress,
 9892                    language_server_id,
 9893                    disk_based_diagnostics_progress_token,
 9894                    ProgressToken::from_lsp(progress_params.token),
 9895                    cx,
 9896                );
 9897            }
 9898            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9899                let registration_id = match progress_params.token {
 9900                    lsp::NumberOrString::Number(_) => None,
 9901                    lsp::NumberOrString::String(token) => token
 9902                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9903                        .map(|(_, id)| id.to_owned()),
 9904                };
 9905                if let Some(LanguageServerState::Running {
 9906                    workspace_diagnostics_refresh_tasks,
 9907                    ..
 9908                }) = self
 9909                    .as_local_mut()
 9910                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9911                    && let Some(workspace_diagnostics) =
 9912                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9913                {
 9914                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9915                    self.apply_workspace_diagnostic_report(
 9916                        language_server_id,
 9917                        report,
 9918                        registration_id.map(SharedString::from),
 9919                        cx,
 9920                    )
 9921                }
 9922            }
 9923        }
 9924    }
 9925
 9926    fn handle_work_done_progress(
 9927        &mut self,
 9928        progress: lsp::WorkDoneProgress,
 9929        language_server_id: LanguageServerId,
 9930        disk_based_diagnostics_progress_token: Option<String>,
 9931        token: ProgressToken,
 9932        cx: &mut Context<Self>,
 9933    ) {
 9934        let language_server_status =
 9935            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9936                status
 9937            } else {
 9938                return;
 9939            };
 9940
 9941        if !language_server_status.progress_tokens.contains(&token) {
 9942            return;
 9943        }
 9944
 9945        let is_disk_based_diagnostics_progress =
 9946            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9947                (&disk_based_diagnostics_progress_token, &token)
 9948            {
 9949                token.starts_with(disk_based_token)
 9950            } else {
 9951                false
 9952            };
 9953
 9954        match progress {
 9955            lsp::WorkDoneProgress::Begin(report) => {
 9956                if is_disk_based_diagnostics_progress {
 9957                    self.disk_based_diagnostics_started(language_server_id, cx);
 9958                }
 9959                self.on_lsp_work_start(
 9960                    language_server_id,
 9961                    token.clone(),
 9962                    LanguageServerProgress {
 9963                        title: Some(report.title),
 9964                        is_disk_based_diagnostics_progress,
 9965                        is_cancellable: report.cancellable.unwrap_or(false),
 9966                        message: report.message.clone(),
 9967                        percentage: report.percentage.map(|p| p as usize),
 9968                        last_update_at: cx.background_executor().now(),
 9969                    },
 9970                    cx,
 9971                );
 9972            }
 9973            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9974                language_server_id,
 9975                token,
 9976                LanguageServerProgress {
 9977                    title: None,
 9978                    is_disk_based_diagnostics_progress,
 9979                    is_cancellable: report.cancellable.unwrap_or(false),
 9980                    message: report.message,
 9981                    percentage: report.percentage.map(|p| p as usize),
 9982                    last_update_at: cx.background_executor().now(),
 9983                },
 9984                cx,
 9985            ),
 9986            lsp::WorkDoneProgress::End(_) => {
 9987                language_server_status.progress_tokens.remove(&token);
 9988                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9989                if is_disk_based_diagnostics_progress {
 9990                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9991                }
 9992            }
 9993        }
 9994    }
 9995
 9996    fn on_lsp_work_start(
 9997        &mut self,
 9998        language_server_id: LanguageServerId,
 9999        token: ProgressToken,
10000        progress: LanguageServerProgress,
10001        cx: &mut Context<Self>,
10002    ) {
10003        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10004            status.pending_work.insert(token.clone(), progress.clone());
10005            cx.notify();
10006        }
10007        cx.emit(LspStoreEvent::LanguageServerUpdate {
10008            language_server_id,
10009            name: self
10010                .language_server_adapter_for_id(language_server_id)
10011                .map(|adapter| adapter.name()),
10012            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10013                token: Some(token.to_proto()),
10014                title: progress.title,
10015                message: progress.message,
10016                percentage: progress.percentage.map(|p| p as u32),
10017                is_cancellable: Some(progress.is_cancellable),
10018            }),
10019        })
10020    }
10021
10022    fn on_lsp_work_progress(
10023        &mut self,
10024        language_server_id: LanguageServerId,
10025        token: ProgressToken,
10026        progress: LanguageServerProgress,
10027        cx: &mut Context<Self>,
10028    ) {
10029        let mut did_update = false;
10030        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10031            match status.pending_work.entry(token.clone()) {
10032                btree_map::Entry::Vacant(entry) => {
10033                    entry.insert(progress.clone());
10034                    did_update = true;
10035                }
10036                btree_map::Entry::Occupied(mut entry) => {
10037                    let entry = entry.get_mut();
10038                    if (progress.last_update_at - entry.last_update_at)
10039                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10040                    {
10041                        entry.last_update_at = progress.last_update_at;
10042                        if progress.message.is_some() {
10043                            entry.message = progress.message.clone();
10044                        }
10045                        if progress.percentage.is_some() {
10046                            entry.percentage = progress.percentage;
10047                        }
10048                        if progress.is_cancellable != entry.is_cancellable {
10049                            entry.is_cancellable = progress.is_cancellable;
10050                        }
10051                        did_update = true;
10052                    }
10053                }
10054            }
10055        }
10056
10057        if did_update {
10058            cx.emit(LspStoreEvent::LanguageServerUpdate {
10059                language_server_id,
10060                name: self
10061                    .language_server_adapter_for_id(language_server_id)
10062                    .map(|adapter| adapter.name()),
10063                message: proto::update_language_server::Variant::WorkProgress(
10064                    proto::LspWorkProgress {
10065                        token: Some(token.to_proto()),
10066                        message: progress.message,
10067                        percentage: progress.percentage.map(|p| p as u32),
10068                        is_cancellable: Some(progress.is_cancellable),
10069                    },
10070                ),
10071            })
10072        }
10073    }
10074
10075    fn on_lsp_work_end(
10076        &mut self,
10077        language_server_id: LanguageServerId,
10078        token: ProgressToken,
10079        cx: &mut Context<Self>,
10080    ) {
10081        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10082            if let Some(work) = status.pending_work.remove(&token)
10083                && !work.is_disk_based_diagnostics_progress
10084            {
10085                cx.emit(LspStoreEvent::RefreshInlayHints {
10086                    server_id: language_server_id,
10087                    request_id: None,
10088                });
10089            }
10090            cx.notify();
10091        }
10092
10093        cx.emit(LspStoreEvent::LanguageServerUpdate {
10094            language_server_id,
10095            name: self
10096                .language_server_adapter_for_id(language_server_id)
10097                .map(|adapter| adapter.name()),
10098            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10099                token: Some(token.to_proto()),
10100            }),
10101        })
10102    }
10103
10104    pub async fn handle_resolve_completion_documentation(
10105        this: Entity<Self>,
10106        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10107        mut cx: AsyncApp,
10108    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10109        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10110
10111        let completion = this
10112            .read_with(&cx, |this, cx| {
10113                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10114                let server = this
10115                    .language_server_for_id(id)
10116                    .with_context(|| format!("No language server {id}"))?;
10117
10118                anyhow::Ok(cx.background_spawn(async move {
10119                    let can_resolve = server
10120                        .capabilities()
10121                        .completion_provider
10122                        .as_ref()
10123                        .and_then(|options| options.resolve_provider)
10124                        .unwrap_or(false);
10125                    if can_resolve {
10126                        server
10127                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10128                            .await
10129                            .into_response()
10130                            .context("resolve completion item")
10131                    } else {
10132                        anyhow::Ok(lsp_completion)
10133                    }
10134                }))
10135            })??
10136            .await?;
10137
10138        let mut documentation_is_markdown = false;
10139        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10140        let documentation = match completion.documentation {
10141            Some(lsp::Documentation::String(text)) => text,
10142
10143            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10144                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10145                value
10146            }
10147
10148            _ => String::new(),
10149        };
10150
10151        // If we have a new buffer_id, that means we're talking to a new client
10152        // and want to check for new text_edits in the completion too.
10153        let mut old_replace_start = None;
10154        let mut old_replace_end = None;
10155        let mut old_insert_start = None;
10156        let mut old_insert_end = None;
10157        let mut new_text = String::default();
10158        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10159            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10160                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10161                anyhow::Ok(buffer.read(cx).snapshot())
10162            })??;
10163
10164            if let Some(text_edit) = completion.text_edit.as_ref() {
10165                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10166
10167                if let Some(mut edit) = edit {
10168                    LineEnding::normalize(&mut edit.new_text);
10169
10170                    new_text = edit.new_text;
10171                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10172                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10173                    if let Some(insert_range) = edit.insert_range {
10174                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10175                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10176                    }
10177                }
10178            }
10179        }
10180
10181        Ok(proto::ResolveCompletionDocumentationResponse {
10182            documentation,
10183            documentation_is_markdown,
10184            old_replace_start,
10185            old_replace_end,
10186            new_text,
10187            lsp_completion,
10188            old_insert_start,
10189            old_insert_end,
10190        })
10191    }
10192
10193    async fn handle_on_type_formatting(
10194        this: Entity<Self>,
10195        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10196        mut cx: AsyncApp,
10197    ) -> Result<proto::OnTypeFormattingResponse> {
10198        let on_type_formatting = this.update(&mut cx, |this, cx| {
10199            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10200            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10201            let position = envelope
10202                .payload
10203                .position
10204                .and_then(deserialize_anchor)
10205                .context("invalid position")?;
10206            anyhow::Ok(this.apply_on_type_formatting(
10207                buffer,
10208                position,
10209                envelope.payload.trigger.clone(),
10210                cx,
10211            ))
10212        })??;
10213
10214        let transaction = on_type_formatting
10215            .await?
10216            .as_ref()
10217            .map(language::proto::serialize_transaction);
10218        Ok(proto::OnTypeFormattingResponse { transaction })
10219    }
10220
10221    async fn handle_refresh_inlay_hints(
10222        lsp_store: Entity<Self>,
10223        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10224        mut cx: AsyncApp,
10225    ) -> Result<proto::Ack> {
10226        lsp_store.update(&mut cx, |_, cx| {
10227            cx.emit(LspStoreEvent::RefreshInlayHints {
10228                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10229                request_id: envelope.payload.request_id.map(|id| id as usize),
10230            });
10231        })?;
10232        Ok(proto::Ack {})
10233    }
10234
10235    async fn handle_pull_workspace_diagnostics(
10236        lsp_store: Entity<Self>,
10237        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10238        mut cx: AsyncApp,
10239    ) -> Result<proto::Ack> {
10240        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10241        lsp_store.update(&mut cx, |lsp_store, _| {
10242            lsp_store.pull_workspace_diagnostics(server_id);
10243        })?;
10244        Ok(proto::Ack {})
10245    }
10246
10247    async fn handle_get_color_presentation(
10248        lsp_store: Entity<Self>,
10249        envelope: TypedEnvelope<proto::GetColorPresentation>,
10250        mut cx: AsyncApp,
10251    ) -> Result<proto::GetColorPresentationResponse> {
10252        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10253        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10254            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10255        })??;
10256
10257        let color = envelope
10258            .payload
10259            .color
10260            .context("invalid color resolve request")?;
10261        let start = color
10262            .lsp_range_start
10263            .context("invalid color resolve request")?;
10264        let end = color
10265            .lsp_range_end
10266            .context("invalid color resolve request")?;
10267
10268        let color = DocumentColor {
10269            lsp_range: lsp::Range {
10270                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10271                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10272            },
10273            color: lsp::Color {
10274                red: color.red,
10275                green: color.green,
10276                blue: color.blue,
10277                alpha: color.alpha,
10278            },
10279            resolved: false,
10280            color_presentations: Vec::new(),
10281        };
10282        let resolved_color = lsp_store
10283            .update(&mut cx, |lsp_store, cx| {
10284                lsp_store.resolve_color_presentation(
10285                    color,
10286                    buffer.clone(),
10287                    LanguageServerId(envelope.payload.server_id as usize),
10288                    cx,
10289                )
10290            })?
10291            .await
10292            .context("resolving color presentation")?;
10293
10294        Ok(proto::GetColorPresentationResponse {
10295            presentations: resolved_color
10296                .color_presentations
10297                .into_iter()
10298                .map(|presentation| proto::ColorPresentation {
10299                    label: presentation.label.to_string(),
10300                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10301                    additional_text_edits: presentation
10302                        .additional_text_edits
10303                        .into_iter()
10304                        .map(serialize_lsp_edit)
10305                        .collect(),
10306                })
10307                .collect(),
10308        })
10309    }
10310
10311    async fn handle_resolve_inlay_hint(
10312        lsp_store: Entity<Self>,
10313        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10314        mut cx: AsyncApp,
10315    ) -> Result<proto::ResolveInlayHintResponse> {
10316        let proto_hint = envelope
10317            .payload
10318            .hint
10319            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10320        let hint = InlayHints::proto_to_project_hint(proto_hint)
10321            .context("resolved proto inlay hint conversion")?;
10322        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10323            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10324            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10325        })??;
10326        let response_hint = lsp_store
10327            .update(&mut cx, |lsp_store, cx| {
10328                lsp_store.resolve_inlay_hint(
10329                    hint,
10330                    buffer,
10331                    LanguageServerId(envelope.payload.language_server_id as usize),
10332                    cx,
10333                )
10334            })?
10335            .await
10336            .context("inlay hints fetch")?;
10337        Ok(proto::ResolveInlayHintResponse {
10338            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10339        })
10340    }
10341
10342    async fn handle_refresh_code_lens(
10343        this: Entity<Self>,
10344        _: TypedEnvelope<proto::RefreshCodeLens>,
10345        mut cx: AsyncApp,
10346    ) -> Result<proto::Ack> {
10347        this.update(&mut cx, |_, cx| {
10348            cx.emit(LspStoreEvent::RefreshCodeLens);
10349        })?;
10350        Ok(proto::Ack {})
10351    }
10352
10353    async fn handle_open_buffer_for_symbol(
10354        this: Entity<Self>,
10355        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10356        mut cx: AsyncApp,
10357    ) -> Result<proto::OpenBufferForSymbolResponse> {
10358        let peer_id = envelope.original_sender_id().unwrap_or_default();
10359        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10360        let symbol = Self::deserialize_symbol(symbol)?;
10361        this.read_with(&cx, |this, _| {
10362            if let SymbolLocation::OutsideProject {
10363                abs_path,
10364                signature,
10365            } = &symbol.path
10366            {
10367                let new_signature = this.symbol_signature(&abs_path);
10368                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10369            }
10370            Ok(())
10371        })??;
10372        let buffer = this
10373            .update(&mut cx, |this, cx| {
10374                this.open_buffer_for_symbol(
10375                    &Symbol {
10376                        language_server_name: symbol.language_server_name,
10377                        source_worktree_id: symbol.source_worktree_id,
10378                        source_language_server_id: symbol.source_language_server_id,
10379                        path: symbol.path,
10380                        name: symbol.name,
10381                        kind: symbol.kind,
10382                        range: symbol.range,
10383                        label: CodeLabel::default(),
10384                    },
10385                    cx,
10386                )
10387            })?
10388            .await?;
10389
10390        this.update(&mut cx, |this, cx| {
10391            let is_private = buffer
10392                .read(cx)
10393                .file()
10394                .map(|f| f.is_private())
10395                .unwrap_or_default();
10396            if is_private {
10397                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10398            } else {
10399                this.buffer_store
10400                    .update(cx, |buffer_store, cx| {
10401                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10402                    })
10403                    .detach_and_log_err(cx);
10404                let buffer_id = buffer.read(cx).remote_id().to_proto();
10405                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10406            }
10407        })?
10408    }
10409
10410    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10411        let mut hasher = Sha256::new();
10412        hasher.update(abs_path.to_string_lossy().as_bytes());
10413        hasher.update(self.nonce.to_be_bytes());
10414        hasher.finalize().as_slice().try_into().unwrap()
10415    }
10416
10417    pub async fn handle_get_project_symbols(
10418        this: Entity<Self>,
10419        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10420        mut cx: AsyncApp,
10421    ) -> Result<proto::GetProjectSymbolsResponse> {
10422        let symbols = this
10423            .update(&mut cx, |this, cx| {
10424                this.symbols(&envelope.payload.query, cx)
10425            })?
10426            .await?;
10427
10428        Ok(proto::GetProjectSymbolsResponse {
10429            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10430        })
10431    }
10432
10433    pub async fn handle_restart_language_servers(
10434        this: Entity<Self>,
10435        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10436        mut cx: AsyncApp,
10437    ) -> Result<proto::Ack> {
10438        this.update(&mut cx, |lsp_store, cx| {
10439            let buffers =
10440                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10441            lsp_store.restart_language_servers_for_buffers(
10442                buffers,
10443                envelope
10444                    .payload
10445                    .only_servers
10446                    .into_iter()
10447                    .filter_map(|selector| {
10448                        Some(match selector.selector? {
10449                            proto::language_server_selector::Selector::ServerId(server_id) => {
10450                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10451                            }
10452                            proto::language_server_selector::Selector::Name(name) => {
10453                                LanguageServerSelector::Name(LanguageServerName(
10454                                    SharedString::from(name),
10455                                ))
10456                            }
10457                        })
10458                    })
10459                    .collect(),
10460                cx,
10461            );
10462        })?;
10463
10464        Ok(proto::Ack {})
10465    }
10466
10467    pub async fn handle_stop_language_servers(
10468        lsp_store: Entity<Self>,
10469        envelope: TypedEnvelope<proto::StopLanguageServers>,
10470        mut cx: AsyncApp,
10471    ) -> Result<proto::Ack> {
10472        lsp_store.update(&mut cx, |lsp_store, cx| {
10473            if envelope.payload.all
10474                && envelope.payload.also_servers.is_empty()
10475                && envelope.payload.buffer_ids.is_empty()
10476            {
10477                lsp_store.stop_all_language_servers(cx);
10478            } else {
10479                let buffers =
10480                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10481                lsp_store
10482                    .stop_language_servers_for_buffers(
10483                        buffers,
10484                        envelope
10485                            .payload
10486                            .also_servers
10487                            .into_iter()
10488                            .filter_map(|selector| {
10489                                Some(match selector.selector? {
10490                                    proto::language_server_selector::Selector::ServerId(
10491                                        server_id,
10492                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10493                                        server_id,
10494                                    )),
10495                                    proto::language_server_selector::Selector::Name(name) => {
10496                                        LanguageServerSelector::Name(LanguageServerName(
10497                                            SharedString::from(name),
10498                                        ))
10499                                    }
10500                                })
10501                            })
10502                            .collect(),
10503                        cx,
10504                    )
10505                    .detach_and_log_err(cx);
10506            }
10507        })?;
10508
10509        Ok(proto::Ack {})
10510    }
10511
10512    pub async fn handle_cancel_language_server_work(
10513        lsp_store: Entity<Self>,
10514        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10515        mut cx: AsyncApp,
10516    ) -> Result<proto::Ack> {
10517        lsp_store.update(&mut cx, |lsp_store, cx| {
10518            if let Some(work) = envelope.payload.work {
10519                match work {
10520                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10521                        let buffers =
10522                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10523                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10524                    }
10525                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10526                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10527                        let token = work
10528                            .token
10529                            .map(|token| {
10530                                ProgressToken::from_proto(token)
10531                                    .context("invalid work progress token")
10532                            })
10533                            .transpose()?;
10534                        lsp_store.cancel_language_server_work(server_id, token, cx);
10535                    }
10536                }
10537            }
10538            anyhow::Ok(())
10539        })??;
10540
10541        Ok(proto::Ack {})
10542    }
10543
10544    fn buffer_ids_to_buffers(
10545        &mut self,
10546        buffer_ids: impl Iterator<Item = u64>,
10547        cx: &mut Context<Self>,
10548    ) -> Vec<Entity<Buffer>> {
10549        buffer_ids
10550            .into_iter()
10551            .flat_map(|buffer_id| {
10552                self.buffer_store
10553                    .read(cx)
10554                    .get(BufferId::new(buffer_id).log_err()?)
10555            })
10556            .collect::<Vec<_>>()
10557    }
10558
10559    async fn handle_apply_additional_edits_for_completion(
10560        this: Entity<Self>,
10561        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10562        mut cx: AsyncApp,
10563    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10564        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10565            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10566            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10567            let completion = Self::deserialize_completion(
10568                envelope.payload.completion.context("invalid completion")?,
10569            )?;
10570            anyhow::Ok((buffer, completion))
10571        })??;
10572
10573        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10574            this.apply_additional_edits_for_completion(
10575                buffer,
10576                Rc::new(RefCell::new(Box::new([Completion {
10577                    replace_range: completion.replace_range,
10578                    new_text: completion.new_text,
10579                    source: completion.source,
10580                    documentation: None,
10581                    label: CodeLabel::default(),
10582                    match_start: None,
10583                    snippet_deduplication_key: None,
10584                    insert_text_mode: None,
10585                    icon_path: None,
10586                    confirm: None,
10587                }]))),
10588                0,
10589                false,
10590                cx,
10591            )
10592        })?;
10593
10594        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10595            transaction: apply_additional_edits
10596                .await?
10597                .as_ref()
10598                .map(language::proto::serialize_transaction),
10599        })
10600    }
10601
10602    pub fn last_formatting_failure(&self) -> Option<&str> {
10603        self.last_formatting_failure.as_deref()
10604    }
10605
10606    pub fn reset_last_formatting_failure(&mut self) {
10607        self.last_formatting_failure = None;
10608    }
10609
10610    pub fn environment_for_buffer(
10611        &self,
10612        buffer: &Entity<Buffer>,
10613        cx: &mut Context<Self>,
10614    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10615        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10616            environment.update(cx, |env, cx| {
10617                env.buffer_environment(buffer, &self.worktree_store, cx)
10618            })
10619        } else {
10620            Task::ready(None).shared()
10621        }
10622    }
10623
10624    pub fn format(
10625        &mut self,
10626        buffers: HashSet<Entity<Buffer>>,
10627        target: LspFormatTarget,
10628        push_to_history: bool,
10629        trigger: FormatTrigger,
10630        cx: &mut Context<Self>,
10631    ) -> Task<anyhow::Result<ProjectTransaction>> {
10632        let logger = zlog::scoped!("format");
10633        if self.as_local().is_some() {
10634            zlog::trace!(logger => "Formatting locally");
10635            let logger = zlog::scoped!(logger => "local");
10636            let buffers = buffers
10637                .into_iter()
10638                .map(|buffer_handle| {
10639                    let buffer = buffer_handle.read(cx);
10640                    let buffer_abs_path = File::from_dyn(buffer.file())
10641                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10642
10643                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10644                })
10645                .collect::<Vec<_>>();
10646
10647            cx.spawn(async move |lsp_store, cx| {
10648                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10649
10650                for (handle, abs_path, id) in buffers {
10651                    let env = lsp_store
10652                        .update(cx, |lsp_store, cx| {
10653                            lsp_store.environment_for_buffer(&handle, cx)
10654                        })?
10655                        .await;
10656
10657                    let ranges = match &target {
10658                        LspFormatTarget::Buffers => None,
10659                        LspFormatTarget::Ranges(ranges) => {
10660                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10661                        }
10662                    };
10663
10664                    formattable_buffers.push(FormattableBuffer {
10665                        handle,
10666                        abs_path,
10667                        env,
10668                        ranges,
10669                    });
10670                }
10671                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10672
10673                let format_timer = zlog::time!(logger => "Formatting buffers");
10674                let result = LocalLspStore::format_locally(
10675                    lsp_store.clone(),
10676                    formattable_buffers,
10677                    push_to_history,
10678                    trigger,
10679                    logger,
10680                    cx,
10681                )
10682                .await;
10683                format_timer.end();
10684
10685                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10686
10687                lsp_store.update(cx, |lsp_store, _| {
10688                    lsp_store.update_last_formatting_failure(&result);
10689                })?;
10690
10691                result
10692            })
10693        } else if let Some((client, project_id)) = self.upstream_client() {
10694            zlog::trace!(logger => "Formatting remotely");
10695            let logger = zlog::scoped!(logger => "remote");
10696            // Don't support formatting ranges via remote
10697            match target {
10698                LspFormatTarget::Buffers => {}
10699                LspFormatTarget::Ranges(_) => {
10700                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10701                    return Task::ready(Ok(ProjectTransaction::default()));
10702                }
10703            }
10704
10705            let buffer_store = self.buffer_store();
10706            cx.spawn(async move |lsp_store, cx| {
10707                zlog::trace!(logger => "Sending remote format request");
10708                let request_timer = zlog::time!(logger => "remote format request");
10709                let result = client
10710                    .request(proto::FormatBuffers {
10711                        project_id,
10712                        trigger: trigger as i32,
10713                        buffer_ids: buffers
10714                            .iter()
10715                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10716                            .collect::<Result<_>>()?,
10717                    })
10718                    .await
10719                    .and_then(|result| result.transaction.context("missing transaction"));
10720                request_timer.end();
10721
10722                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10723
10724                lsp_store.update(cx, |lsp_store, _| {
10725                    lsp_store.update_last_formatting_failure(&result);
10726                })?;
10727
10728                let transaction_response = result?;
10729                let _timer = zlog::time!(logger => "deserializing project transaction");
10730                buffer_store
10731                    .update(cx, |buffer_store, cx| {
10732                        buffer_store.deserialize_project_transaction(
10733                            transaction_response,
10734                            push_to_history,
10735                            cx,
10736                        )
10737                    })?
10738                    .await
10739            })
10740        } else {
10741            zlog::trace!(logger => "Not formatting");
10742            Task::ready(Ok(ProjectTransaction::default()))
10743        }
10744    }
10745
10746    async fn handle_format_buffers(
10747        this: Entity<Self>,
10748        envelope: TypedEnvelope<proto::FormatBuffers>,
10749        mut cx: AsyncApp,
10750    ) -> Result<proto::FormatBuffersResponse> {
10751        let sender_id = envelope.original_sender_id().unwrap_or_default();
10752        let format = this.update(&mut cx, |this, cx| {
10753            let mut buffers = HashSet::default();
10754            for buffer_id in &envelope.payload.buffer_ids {
10755                let buffer_id = BufferId::new(*buffer_id)?;
10756                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10757            }
10758            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10759            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10760        })??;
10761
10762        let project_transaction = format.await?;
10763        let project_transaction = this.update(&mut cx, |this, cx| {
10764            this.buffer_store.update(cx, |buffer_store, cx| {
10765                buffer_store.serialize_project_transaction_for_peer(
10766                    project_transaction,
10767                    sender_id,
10768                    cx,
10769                )
10770            })
10771        })?;
10772        Ok(proto::FormatBuffersResponse {
10773            transaction: Some(project_transaction),
10774        })
10775    }
10776
10777    async fn handle_apply_code_action_kind(
10778        this: Entity<Self>,
10779        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10780        mut cx: AsyncApp,
10781    ) -> Result<proto::ApplyCodeActionKindResponse> {
10782        let sender_id = envelope.original_sender_id().unwrap_or_default();
10783        let format = this.update(&mut cx, |this, cx| {
10784            let mut buffers = HashSet::default();
10785            for buffer_id in &envelope.payload.buffer_ids {
10786                let buffer_id = BufferId::new(*buffer_id)?;
10787                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10788            }
10789            let kind = match envelope.payload.kind.as_str() {
10790                "" => CodeActionKind::EMPTY,
10791                "quickfix" => CodeActionKind::QUICKFIX,
10792                "refactor" => CodeActionKind::REFACTOR,
10793                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10794                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10795                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10796                "source" => CodeActionKind::SOURCE,
10797                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10798                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10799                _ => anyhow::bail!(
10800                    "Invalid code action kind {}",
10801                    envelope.payload.kind.as_str()
10802                ),
10803            };
10804            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10805        })??;
10806
10807        let project_transaction = format.await?;
10808        let project_transaction = this.update(&mut cx, |this, cx| {
10809            this.buffer_store.update(cx, |buffer_store, cx| {
10810                buffer_store.serialize_project_transaction_for_peer(
10811                    project_transaction,
10812                    sender_id,
10813                    cx,
10814                )
10815            })
10816        })?;
10817        Ok(proto::ApplyCodeActionKindResponse {
10818            transaction: Some(project_transaction),
10819        })
10820    }
10821
10822    async fn shutdown_language_server(
10823        server_state: Option<LanguageServerState>,
10824        name: LanguageServerName,
10825        cx: &mut AsyncApp,
10826    ) {
10827        let server = match server_state {
10828            Some(LanguageServerState::Starting { startup, .. }) => {
10829                let mut timer = cx
10830                    .background_executor()
10831                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10832                    .fuse();
10833
10834                select! {
10835                    server = startup.fuse() => server,
10836                    () = timer => {
10837                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10838                        None
10839                    },
10840                }
10841            }
10842
10843            Some(LanguageServerState::Running { server, .. }) => Some(server),
10844
10845            None => None,
10846        };
10847
10848        if let Some(server) = server
10849            && let Some(shutdown) = server.shutdown()
10850        {
10851            shutdown.await;
10852        }
10853    }
10854
10855    // Returns a list of all of the worktrees which no longer have a language server and the root path
10856    // for the stopped server
10857    fn stop_local_language_server(
10858        &mut self,
10859        server_id: LanguageServerId,
10860        cx: &mut Context<Self>,
10861    ) -> Task<()> {
10862        let local = match &mut self.mode {
10863            LspStoreMode::Local(local) => local,
10864            _ => {
10865                return Task::ready(());
10866            }
10867        };
10868
10869        // Remove this server ID from all entries in the given worktree.
10870        local
10871            .language_server_ids
10872            .retain(|_, state| state.id != server_id);
10873        self.buffer_store.update(cx, |buffer_store, cx| {
10874            for buffer in buffer_store.buffers() {
10875                buffer.update(cx, |buffer, cx| {
10876                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10877                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10878                });
10879            }
10880        });
10881
10882        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10883            summaries.retain(|path, summaries_by_server_id| {
10884                if summaries_by_server_id.remove(&server_id).is_some() {
10885                    if let Some((client, project_id)) = self.downstream_client.clone() {
10886                        client
10887                            .send(proto::UpdateDiagnosticSummary {
10888                                project_id,
10889                                worktree_id: worktree_id.to_proto(),
10890                                summary: Some(proto::DiagnosticSummary {
10891                                    path: path.as_ref().to_proto(),
10892                                    language_server_id: server_id.0 as u64,
10893                                    error_count: 0,
10894                                    warning_count: 0,
10895                                }),
10896                                more_summaries: Vec::new(),
10897                            })
10898                            .log_err();
10899                    }
10900                    !summaries_by_server_id.is_empty()
10901                } else {
10902                    true
10903                }
10904            });
10905        }
10906
10907        let local = self.as_local_mut().unwrap();
10908        for diagnostics in local.diagnostics.values_mut() {
10909            diagnostics.retain(|_, diagnostics_by_server_id| {
10910                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10911                    diagnostics_by_server_id.remove(ix);
10912                    !diagnostics_by_server_id.is_empty()
10913                } else {
10914                    true
10915                }
10916            });
10917        }
10918        local.language_server_watched_paths.remove(&server_id);
10919
10920        let server_state = local.language_servers.remove(&server_id);
10921        self.cleanup_lsp_data(server_id);
10922        let name = self
10923            .language_server_statuses
10924            .remove(&server_id)
10925            .map(|status| status.name)
10926            .or_else(|| {
10927                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10928                    Some(adapter.name())
10929                } else {
10930                    None
10931                }
10932            });
10933
10934        if let Some(name) = name {
10935            log::info!("stopping language server {name}");
10936            self.languages
10937                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10938            cx.notify();
10939
10940            return cx.spawn(async move |lsp_store, cx| {
10941                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10942                lsp_store
10943                    .update(cx, |lsp_store, cx| {
10944                        lsp_store
10945                            .languages
10946                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10947                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10948                        cx.notify();
10949                    })
10950                    .ok();
10951            });
10952        }
10953
10954        if server_state.is_some() {
10955            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10956        }
10957        Task::ready(())
10958    }
10959
10960    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10961        if let Some((client, project_id)) = self.upstream_client() {
10962            let request = client.request(proto::StopLanguageServers {
10963                project_id,
10964                buffer_ids: Vec::new(),
10965                also_servers: Vec::new(),
10966                all: true,
10967            });
10968            cx.background_spawn(request).detach_and_log_err(cx);
10969        } else {
10970            let Some(local) = self.as_local_mut() else {
10971                return;
10972            };
10973            let language_servers_to_stop = local
10974                .language_server_ids
10975                .values()
10976                .map(|state| state.id)
10977                .collect();
10978            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10979            let tasks = language_servers_to_stop
10980                .into_iter()
10981                .map(|server| self.stop_local_language_server(server, cx))
10982                .collect::<Vec<_>>();
10983            cx.background_spawn(async move {
10984                futures::future::join_all(tasks).await;
10985            })
10986            .detach();
10987        }
10988    }
10989
10990    pub fn restart_language_servers_for_buffers(
10991        &mut self,
10992        buffers: Vec<Entity<Buffer>>,
10993        only_restart_servers: HashSet<LanguageServerSelector>,
10994        cx: &mut Context<Self>,
10995    ) {
10996        if let Some((client, project_id)) = self.upstream_client() {
10997            let request = client.request(proto::RestartLanguageServers {
10998                project_id,
10999                buffer_ids: buffers
11000                    .into_iter()
11001                    .map(|b| b.read(cx).remote_id().to_proto())
11002                    .collect(),
11003                only_servers: only_restart_servers
11004                    .into_iter()
11005                    .map(|selector| {
11006                        let selector = match selector {
11007                            LanguageServerSelector::Id(language_server_id) => {
11008                                proto::language_server_selector::Selector::ServerId(
11009                                    language_server_id.to_proto(),
11010                                )
11011                            }
11012                            LanguageServerSelector::Name(language_server_name) => {
11013                                proto::language_server_selector::Selector::Name(
11014                                    language_server_name.to_string(),
11015                                )
11016                            }
11017                        };
11018                        proto::LanguageServerSelector {
11019                            selector: Some(selector),
11020                        }
11021                    })
11022                    .collect(),
11023                all: false,
11024            });
11025            cx.background_spawn(request).detach_and_log_err(cx);
11026        } else {
11027            let stop_task = if only_restart_servers.is_empty() {
11028                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11029            } else {
11030                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11031            };
11032            cx.spawn(async move |lsp_store, cx| {
11033                stop_task.await;
11034                lsp_store
11035                    .update(cx, |lsp_store, cx| {
11036                        for buffer in buffers {
11037                            lsp_store.register_buffer_with_language_servers(
11038                                &buffer,
11039                                only_restart_servers.clone(),
11040                                true,
11041                                cx,
11042                            );
11043                        }
11044                    })
11045                    .ok()
11046            })
11047            .detach();
11048        }
11049    }
11050
11051    pub fn stop_language_servers_for_buffers(
11052        &mut self,
11053        buffers: Vec<Entity<Buffer>>,
11054        also_stop_servers: HashSet<LanguageServerSelector>,
11055        cx: &mut Context<Self>,
11056    ) -> Task<Result<()>> {
11057        if let Some((client, project_id)) = self.upstream_client() {
11058            let request = client.request(proto::StopLanguageServers {
11059                project_id,
11060                buffer_ids: buffers
11061                    .into_iter()
11062                    .map(|b| b.read(cx).remote_id().to_proto())
11063                    .collect(),
11064                also_servers: also_stop_servers
11065                    .into_iter()
11066                    .map(|selector| {
11067                        let selector = match selector {
11068                            LanguageServerSelector::Id(language_server_id) => {
11069                                proto::language_server_selector::Selector::ServerId(
11070                                    language_server_id.to_proto(),
11071                                )
11072                            }
11073                            LanguageServerSelector::Name(language_server_name) => {
11074                                proto::language_server_selector::Selector::Name(
11075                                    language_server_name.to_string(),
11076                                )
11077                            }
11078                        };
11079                        proto::LanguageServerSelector {
11080                            selector: Some(selector),
11081                        }
11082                    })
11083                    .collect(),
11084                all: false,
11085            });
11086            cx.background_spawn(async move {
11087                let _ = request.await?;
11088                Ok(())
11089            })
11090        } else {
11091            let task =
11092                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11093            cx.background_spawn(async move {
11094                task.await;
11095                Ok(())
11096            })
11097        }
11098    }
11099
11100    fn stop_local_language_servers_for_buffers(
11101        &mut self,
11102        buffers: &[Entity<Buffer>],
11103        also_stop_servers: HashSet<LanguageServerSelector>,
11104        cx: &mut Context<Self>,
11105    ) -> Task<()> {
11106        let Some(local) = self.as_local_mut() else {
11107            return Task::ready(());
11108        };
11109        let mut language_server_names_to_stop = BTreeSet::default();
11110        let mut language_servers_to_stop = also_stop_servers
11111            .into_iter()
11112            .flat_map(|selector| match selector {
11113                LanguageServerSelector::Id(id) => Some(id),
11114                LanguageServerSelector::Name(name) => {
11115                    language_server_names_to_stop.insert(name);
11116                    None
11117                }
11118            })
11119            .collect::<BTreeSet<_>>();
11120
11121        let mut covered_worktrees = HashSet::default();
11122        for buffer in buffers {
11123            buffer.update(cx, |buffer, cx| {
11124                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11125                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11126                    && covered_worktrees.insert(worktree_id)
11127                {
11128                    language_server_names_to_stop.retain(|name| {
11129                        let old_ids_count = language_servers_to_stop.len();
11130                        let all_language_servers_with_this_name = local
11131                            .language_server_ids
11132                            .iter()
11133                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11134                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11135                        old_ids_count == language_servers_to_stop.len()
11136                    });
11137                }
11138            });
11139        }
11140        for name in language_server_names_to_stop {
11141            language_servers_to_stop.extend(
11142                local
11143                    .language_server_ids
11144                    .iter()
11145                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11146            );
11147        }
11148
11149        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11150        let tasks = language_servers_to_stop
11151            .into_iter()
11152            .map(|server| self.stop_local_language_server(server, cx))
11153            .collect::<Vec<_>>();
11154
11155        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11156    }
11157
11158    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11159        let (worktree, relative_path) =
11160            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11161
11162        let project_path = ProjectPath {
11163            worktree_id: worktree.read(cx).id(),
11164            path: relative_path,
11165        };
11166
11167        Some(
11168            self.buffer_store()
11169                .read(cx)
11170                .get_by_path(&project_path)?
11171                .read(cx),
11172        )
11173    }
11174
11175    #[cfg(any(test, feature = "test-support"))]
11176    pub fn update_diagnostics(
11177        &mut self,
11178        server_id: LanguageServerId,
11179        diagnostics: lsp::PublishDiagnosticsParams,
11180        result_id: Option<SharedString>,
11181        source_kind: DiagnosticSourceKind,
11182        disk_based_sources: &[String],
11183        cx: &mut Context<Self>,
11184    ) -> Result<()> {
11185        self.merge_lsp_diagnostics(
11186            source_kind,
11187            vec![DocumentDiagnosticsUpdate {
11188                diagnostics,
11189                result_id,
11190                server_id,
11191                disk_based_sources: Cow::Borrowed(disk_based_sources),
11192                registration_id: None,
11193            }],
11194            |_, _, _| false,
11195            cx,
11196        )
11197    }
11198
11199    pub fn merge_lsp_diagnostics(
11200        &mut self,
11201        source_kind: DiagnosticSourceKind,
11202        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11203        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11204        cx: &mut Context<Self>,
11205    ) -> Result<()> {
11206        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11207        let updates = lsp_diagnostics
11208            .into_iter()
11209            .filter_map(|update| {
11210                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11211                Some(DocumentDiagnosticsUpdate {
11212                    diagnostics: self.lsp_to_document_diagnostics(
11213                        abs_path,
11214                        source_kind,
11215                        update.server_id,
11216                        update.diagnostics,
11217                        &update.disk_based_sources,
11218                        update.registration_id.clone(),
11219                    ),
11220                    result_id: update.result_id,
11221                    server_id: update.server_id,
11222                    disk_based_sources: update.disk_based_sources,
11223                    registration_id: update.registration_id,
11224                })
11225            })
11226            .collect();
11227        self.merge_diagnostic_entries(updates, merge, cx)?;
11228        Ok(())
11229    }
11230
11231    fn lsp_to_document_diagnostics(
11232        &mut self,
11233        document_abs_path: PathBuf,
11234        source_kind: DiagnosticSourceKind,
11235        server_id: LanguageServerId,
11236        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11237        disk_based_sources: &[String],
11238        registration_id: Option<SharedString>,
11239    ) -> DocumentDiagnostics {
11240        let mut diagnostics = Vec::default();
11241        let mut primary_diagnostic_group_ids = HashMap::default();
11242        let mut sources_by_group_id = HashMap::default();
11243        let mut supporting_diagnostics = HashMap::default();
11244
11245        let adapter = self.language_server_adapter_for_id(server_id);
11246
11247        // Ensure that primary diagnostics are always the most severe
11248        lsp_diagnostics
11249            .diagnostics
11250            .sort_by_key(|item| item.severity);
11251
11252        for diagnostic in &lsp_diagnostics.diagnostics {
11253            let source = diagnostic.source.as_ref();
11254            let range = range_from_lsp(diagnostic.range);
11255            let is_supporting = diagnostic
11256                .related_information
11257                .as_ref()
11258                .is_some_and(|infos| {
11259                    infos.iter().any(|info| {
11260                        primary_diagnostic_group_ids.contains_key(&(
11261                            source,
11262                            diagnostic.code.clone(),
11263                            range_from_lsp(info.location.range),
11264                        ))
11265                    })
11266                });
11267
11268            let is_unnecessary = diagnostic
11269                .tags
11270                .as_ref()
11271                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11272
11273            let underline = self
11274                .language_server_adapter_for_id(server_id)
11275                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11276
11277            if is_supporting {
11278                supporting_diagnostics.insert(
11279                    (source, diagnostic.code.clone(), range),
11280                    (diagnostic.severity, is_unnecessary),
11281                );
11282            } else {
11283                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11284                let is_disk_based =
11285                    source.is_some_and(|source| disk_based_sources.contains(source));
11286
11287                sources_by_group_id.insert(group_id, source);
11288                primary_diagnostic_group_ids
11289                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11290
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: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11302                        markdown: adapter.as_ref().and_then(|adapter| {
11303                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11304                        }),
11305                        message: diagnostic.message.trim().to_string(),
11306                        group_id,
11307                        is_primary: true,
11308                        is_disk_based,
11309                        is_unnecessary,
11310                        underline,
11311                        data: diagnostic.data.clone(),
11312                        registration_id: registration_id.clone(),
11313                    },
11314                });
11315                if let Some(infos) = &diagnostic.related_information {
11316                    for info in infos {
11317                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11318                            let range = range_from_lsp(info.location.range);
11319                            diagnostics.push(DiagnosticEntry {
11320                                range,
11321                                diagnostic: Diagnostic {
11322                                    source: diagnostic.source.clone(),
11323                                    source_kind,
11324                                    code: diagnostic.code.clone(),
11325                                    code_description: diagnostic
11326                                        .code_description
11327                                        .as_ref()
11328                                        .and_then(|d| d.href.clone()),
11329                                    severity: DiagnosticSeverity::INFORMATION,
11330                                    markdown: adapter.as_ref().and_then(|adapter| {
11331                                        adapter.diagnostic_message_to_markdown(&info.message)
11332                                    }),
11333                                    message: info.message.trim().to_string(),
11334                                    group_id,
11335                                    is_primary: false,
11336                                    is_disk_based,
11337                                    is_unnecessary: false,
11338                                    underline,
11339                                    data: diagnostic.data.clone(),
11340                                    registration_id: registration_id.clone(),
11341                                },
11342                            });
11343                        }
11344                    }
11345                }
11346            }
11347        }
11348
11349        for entry in &mut diagnostics {
11350            let diagnostic = &mut entry.diagnostic;
11351            if !diagnostic.is_primary {
11352                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11353                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11354                    source,
11355                    diagnostic.code.clone(),
11356                    entry.range.clone(),
11357                )) {
11358                    if let Some(severity) = severity {
11359                        diagnostic.severity = severity;
11360                    }
11361                    diagnostic.is_unnecessary = is_unnecessary;
11362                }
11363            }
11364        }
11365
11366        DocumentDiagnostics {
11367            diagnostics,
11368            document_abs_path,
11369            version: lsp_diagnostics.version,
11370        }
11371    }
11372
11373    fn insert_newly_running_language_server(
11374        &mut self,
11375        adapter: Arc<CachedLspAdapter>,
11376        language_server: Arc<LanguageServer>,
11377        server_id: LanguageServerId,
11378        key: LanguageServerSeed,
11379        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11380        cx: &mut Context<Self>,
11381    ) {
11382        let Some(local) = self.as_local_mut() else {
11383            return;
11384        };
11385        // If the language server for this key doesn't match the server id, don't store the
11386        // server. Which will cause it to be dropped, killing the process
11387        if local
11388            .language_server_ids
11389            .get(&key)
11390            .map(|state| state.id != server_id)
11391            .unwrap_or(false)
11392        {
11393            return;
11394        }
11395
11396        // Update language_servers collection with Running variant of LanguageServerState
11397        // indicating that the server is up and running and ready
11398        let workspace_folders = workspace_folders.lock().clone();
11399        language_server.set_workspace_folders(workspace_folders);
11400
11401        let workspace_diagnostics_refresh_tasks = language_server
11402            .capabilities()
11403            .diagnostic_provider
11404            .and_then(|provider| {
11405                local
11406                    .language_server_dynamic_registrations
11407                    .entry(server_id)
11408                    .or_default()
11409                    .diagnostics
11410                    .entry(None)
11411                    .or_insert(provider.clone());
11412                let workspace_refresher =
11413                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11414
11415                Some((None, workspace_refresher))
11416            })
11417            .into_iter()
11418            .collect();
11419        local.language_servers.insert(
11420            server_id,
11421            LanguageServerState::Running {
11422                workspace_diagnostics_refresh_tasks,
11423                adapter: adapter.clone(),
11424                server: language_server.clone(),
11425                simulate_disk_based_diagnostics_completion: None,
11426            },
11427        );
11428        local
11429            .languages
11430            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11431        if let Some(file_ops_caps) = language_server
11432            .capabilities()
11433            .workspace
11434            .as_ref()
11435            .and_then(|ws| ws.file_operations.as_ref())
11436        {
11437            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11438            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11439            if did_rename_caps.or(will_rename_caps).is_some() {
11440                let watcher = RenamePathsWatchedForServer::default()
11441                    .with_did_rename_patterns(did_rename_caps)
11442                    .with_will_rename_patterns(will_rename_caps);
11443                local
11444                    .language_server_paths_watched_for_rename
11445                    .insert(server_id, watcher);
11446            }
11447        }
11448
11449        self.language_server_statuses.insert(
11450            server_id,
11451            LanguageServerStatus {
11452                name: language_server.name(),
11453                server_version: language_server.version(),
11454                pending_work: Default::default(),
11455                has_pending_diagnostic_updates: false,
11456                progress_tokens: Default::default(),
11457                worktree: Some(key.worktree_id),
11458                binary: Some(language_server.binary().clone()),
11459                configuration: Some(language_server.configuration().clone()),
11460                workspace_folders: language_server.workspace_folders(),
11461            },
11462        );
11463
11464        cx.emit(LspStoreEvent::LanguageServerAdded(
11465            server_id,
11466            language_server.name(),
11467            Some(key.worktree_id),
11468        ));
11469
11470        let server_capabilities = language_server.capabilities();
11471        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11472            downstream_client
11473                .send(proto::StartLanguageServer {
11474                    project_id: *project_id,
11475                    server: Some(proto::LanguageServer {
11476                        id: server_id.to_proto(),
11477                        name: language_server.name().to_string(),
11478                        worktree_id: Some(key.worktree_id.to_proto()),
11479                    }),
11480                    capabilities: serde_json::to_string(&server_capabilities)
11481                        .expect("serializing server LSP capabilities"),
11482                })
11483                .log_err();
11484        }
11485        self.lsp_server_capabilities
11486            .insert(server_id, server_capabilities);
11487
11488        // Tell the language server about every open buffer in the worktree that matches the language.
11489        // Also check for buffers in worktrees that reused this server
11490        let mut worktrees_using_server = vec![key.worktree_id];
11491        if let Some(local) = self.as_local() {
11492            // Find all worktrees that have this server in their language server tree
11493            for (worktree_id, servers) in &local.lsp_tree.instances {
11494                if *worktree_id != key.worktree_id {
11495                    for server_map in servers.roots.values() {
11496                        if server_map
11497                            .values()
11498                            .any(|(node, _)| node.id() == Some(server_id))
11499                        {
11500                            worktrees_using_server.push(*worktree_id);
11501                        }
11502                    }
11503                }
11504            }
11505        }
11506
11507        let mut buffer_paths_registered = Vec::new();
11508        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11509            let mut lsp_adapters = HashMap::default();
11510            for buffer_handle in buffer_store.buffers() {
11511                let buffer = buffer_handle.read(cx);
11512                let file = match File::from_dyn(buffer.file()) {
11513                    Some(file) => file,
11514                    None => continue,
11515                };
11516                let language = match buffer.language() {
11517                    Some(language) => language,
11518                    None => continue,
11519                };
11520
11521                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11522                    || !lsp_adapters
11523                        .entry(language.name())
11524                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11525                        .iter()
11526                        .any(|a| a.name == key.name)
11527                {
11528                    continue;
11529                }
11530                // didOpen
11531                let file = match file.as_local() {
11532                    Some(file) => file,
11533                    None => continue,
11534                };
11535
11536                let local = self.as_local_mut().unwrap();
11537
11538                let buffer_id = buffer.remote_id();
11539                if local.registered_buffers.contains_key(&buffer_id) {
11540                    let versions = local
11541                        .buffer_snapshots
11542                        .entry(buffer_id)
11543                        .or_default()
11544                        .entry(server_id)
11545                        .and_modify(|_| {
11546                            assert!(
11547                            false,
11548                            "There should not be an existing snapshot for a newly inserted buffer"
11549                        )
11550                        })
11551                        .or_insert_with(|| {
11552                            vec![LspBufferSnapshot {
11553                                version: 0,
11554                                snapshot: buffer.text_snapshot(),
11555                            }]
11556                        });
11557
11558                    let snapshot = versions.last().unwrap();
11559                    let version = snapshot.version;
11560                    let initial_snapshot = &snapshot.snapshot;
11561                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11562                    language_server.register_buffer(
11563                        uri,
11564                        adapter.language_id(&language.name()),
11565                        version,
11566                        initial_snapshot.text(),
11567                    );
11568                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11569                    local
11570                        .buffers_opened_in_servers
11571                        .entry(buffer_id)
11572                        .or_default()
11573                        .insert(server_id);
11574                }
11575                buffer_handle.update(cx, |buffer, cx| {
11576                    buffer.set_completion_triggers(
11577                        server_id,
11578                        language_server
11579                            .capabilities()
11580                            .completion_provider
11581                            .as_ref()
11582                            .and_then(|provider| {
11583                                provider
11584                                    .trigger_characters
11585                                    .as_ref()
11586                                    .map(|characters| characters.iter().cloned().collect())
11587                            })
11588                            .unwrap_or_default(),
11589                        cx,
11590                    )
11591                });
11592            }
11593        });
11594
11595        for (buffer_id, abs_path) in buffer_paths_registered {
11596            cx.emit(LspStoreEvent::LanguageServerUpdate {
11597                language_server_id: server_id,
11598                name: Some(adapter.name()),
11599                message: proto::update_language_server::Variant::RegisteredForBuffer(
11600                    proto::RegisteredForBuffer {
11601                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11602                        buffer_id: buffer_id.to_proto(),
11603                    },
11604                ),
11605            });
11606        }
11607
11608        cx.notify();
11609    }
11610
11611    pub fn language_servers_running_disk_based_diagnostics(
11612        &self,
11613    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11614        self.language_server_statuses
11615            .iter()
11616            .filter_map(|(id, status)| {
11617                if status.has_pending_diagnostic_updates {
11618                    Some(*id)
11619                } else {
11620                    None
11621                }
11622            })
11623    }
11624
11625    pub(crate) fn cancel_language_server_work_for_buffers(
11626        &mut self,
11627        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11628        cx: &mut Context<Self>,
11629    ) {
11630        if let Some((client, project_id)) = self.upstream_client() {
11631            let request = client.request(proto::CancelLanguageServerWork {
11632                project_id,
11633                work: Some(proto::cancel_language_server_work::Work::Buffers(
11634                    proto::cancel_language_server_work::Buffers {
11635                        buffer_ids: buffers
11636                            .into_iter()
11637                            .map(|b| b.read(cx).remote_id().to_proto())
11638                            .collect(),
11639                    },
11640                )),
11641            });
11642            cx.background_spawn(request).detach_and_log_err(cx);
11643        } else if let Some(local) = self.as_local() {
11644            let servers = buffers
11645                .into_iter()
11646                .flat_map(|buffer| {
11647                    buffer.update(cx, |buffer, cx| {
11648                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11649                    })
11650                })
11651                .collect::<HashSet<_>>();
11652            for server_id in servers {
11653                self.cancel_language_server_work(server_id, None, cx);
11654            }
11655        }
11656    }
11657
11658    pub(crate) fn cancel_language_server_work(
11659        &mut self,
11660        server_id: LanguageServerId,
11661        token_to_cancel: Option<ProgressToken>,
11662        cx: &mut Context<Self>,
11663    ) {
11664        if let Some(local) = self.as_local() {
11665            let status = self.language_server_statuses.get(&server_id);
11666            let server = local.language_servers.get(&server_id);
11667            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11668            {
11669                for (token, progress) in &status.pending_work {
11670                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11671                        && token != token_to_cancel
11672                    {
11673                        continue;
11674                    }
11675                    if progress.is_cancellable {
11676                        server
11677                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11678                                WorkDoneProgressCancelParams {
11679                                    token: token.to_lsp(),
11680                                },
11681                            )
11682                            .ok();
11683                    }
11684                }
11685            }
11686        } else if let Some((client, project_id)) = self.upstream_client() {
11687            let request = client.request(proto::CancelLanguageServerWork {
11688                project_id,
11689                work: Some(
11690                    proto::cancel_language_server_work::Work::LanguageServerWork(
11691                        proto::cancel_language_server_work::LanguageServerWork {
11692                            language_server_id: server_id.to_proto(),
11693                            token: token_to_cancel.map(|token| token.to_proto()),
11694                        },
11695                    ),
11696                ),
11697            });
11698            cx.background_spawn(request).detach_and_log_err(cx);
11699        }
11700    }
11701
11702    fn register_supplementary_language_server(
11703        &mut self,
11704        id: LanguageServerId,
11705        name: LanguageServerName,
11706        server: Arc<LanguageServer>,
11707        cx: &mut Context<Self>,
11708    ) {
11709        if let Some(local) = self.as_local_mut() {
11710            local
11711                .supplementary_language_servers
11712                .insert(id, (name.clone(), server));
11713            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11714        }
11715    }
11716
11717    fn unregister_supplementary_language_server(
11718        &mut self,
11719        id: LanguageServerId,
11720        cx: &mut Context<Self>,
11721    ) {
11722        if let Some(local) = self.as_local_mut() {
11723            local.supplementary_language_servers.remove(&id);
11724            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11725        }
11726    }
11727
11728    pub(crate) fn supplementary_language_servers(
11729        &self,
11730    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11731        self.as_local().into_iter().flat_map(|local| {
11732            local
11733                .supplementary_language_servers
11734                .iter()
11735                .map(|(id, (name, _))| (*id, name.clone()))
11736        })
11737    }
11738
11739    pub fn language_server_adapter_for_id(
11740        &self,
11741        id: LanguageServerId,
11742    ) -> Option<Arc<CachedLspAdapter>> {
11743        self.as_local()
11744            .and_then(|local| local.language_servers.get(&id))
11745            .and_then(|language_server_state| match language_server_state {
11746                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11747                _ => None,
11748            })
11749    }
11750
11751    pub(super) fn update_local_worktree_language_servers(
11752        &mut self,
11753        worktree_handle: &Entity<Worktree>,
11754        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11755        cx: &mut Context<Self>,
11756    ) {
11757        if changes.is_empty() {
11758            return;
11759        }
11760
11761        let Some(local) = self.as_local() else { return };
11762
11763        local.prettier_store.update(cx, |prettier_store, cx| {
11764            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11765        });
11766
11767        let worktree_id = worktree_handle.read(cx).id();
11768        let mut language_server_ids = local
11769            .language_server_ids
11770            .iter()
11771            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11772            .collect::<Vec<_>>();
11773        language_server_ids.sort();
11774        language_server_ids.dedup();
11775
11776        // let abs_path = worktree_handle.read(cx).abs_path();
11777        for server_id in &language_server_ids {
11778            if let Some(LanguageServerState::Running { server, .. }) =
11779                local.language_servers.get(server_id)
11780                && let Some(watched_paths) = local
11781                    .language_server_watched_paths
11782                    .get(server_id)
11783                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11784            {
11785                let params = lsp::DidChangeWatchedFilesParams {
11786                    changes: changes
11787                        .iter()
11788                        .filter_map(|(path, _, change)| {
11789                            if !watched_paths.is_match(path.as_std_path()) {
11790                                return None;
11791                            }
11792                            let typ = match change {
11793                                PathChange::Loaded => return None,
11794                                PathChange::Added => lsp::FileChangeType::CREATED,
11795                                PathChange::Removed => lsp::FileChangeType::DELETED,
11796                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11797                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11798                            };
11799                            let uri = lsp::Uri::from_file_path(
11800                                worktree_handle.read(cx).absolutize(&path),
11801                            )
11802                            .ok()?;
11803                            Some(lsp::FileEvent { uri, typ })
11804                        })
11805                        .collect(),
11806                };
11807                if !params.changes.is_empty() {
11808                    server
11809                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11810                        .ok();
11811                }
11812            }
11813        }
11814        for (path, _, _) in changes {
11815            if let Some(file_name) = path.file_name()
11816                && local.watched_manifest_filenames.contains(file_name)
11817            {
11818                self.request_workspace_config_refresh();
11819                break;
11820            }
11821        }
11822    }
11823
11824    pub fn wait_for_remote_buffer(
11825        &mut self,
11826        id: BufferId,
11827        cx: &mut Context<Self>,
11828    ) -> Task<Result<Entity<Buffer>>> {
11829        self.buffer_store.update(cx, |buffer_store, cx| {
11830            buffer_store.wait_for_remote_buffer(id, cx)
11831        })
11832    }
11833
11834    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11835        let mut result = proto::Symbol {
11836            language_server_name: symbol.language_server_name.0.to_string(),
11837            source_worktree_id: symbol.source_worktree_id.to_proto(),
11838            language_server_id: symbol.source_language_server_id.to_proto(),
11839            name: symbol.name.clone(),
11840            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11841            start: Some(proto::PointUtf16 {
11842                row: symbol.range.start.0.row,
11843                column: symbol.range.start.0.column,
11844            }),
11845            end: Some(proto::PointUtf16 {
11846                row: symbol.range.end.0.row,
11847                column: symbol.range.end.0.column,
11848            }),
11849            worktree_id: Default::default(),
11850            path: Default::default(),
11851            signature: Default::default(),
11852        };
11853        match &symbol.path {
11854            SymbolLocation::InProject(path) => {
11855                result.worktree_id = path.worktree_id.to_proto();
11856                result.path = path.path.to_proto();
11857            }
11858            SymbolLocation::OutsideProject {
11859                abs_path,
11860                signature,
11861            } => {
11862                result.path = abs_path.to_string_lossy().into_owned();
11863                result.signature = signature.to_vec();
11864            }
11865        }
11866        result
11867    }
11868
11869    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11870        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11871        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11872        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11873
11874        let path = if serialized_symbol.signature.is_empty() {
11875            SymbolLocation::InProject(ProjectPath {
11876                worktree_id,
11877                path: RelPath::from_proto(&serialized_symbol.path)
11878                    .context("invalid symbol path")?,
11879            })
11880        } else {
11881            SymbolLocation::OutsideProject {
11882                abs_path: Path::new(&serialized_symbol.path).into(),
11883                signature: serialized_symbol
11884                    .signature
11885                    .try_into()
11886                    .map_err(|_| anyhow!("invalid signature"))?,
11887            }
11888        };
11889
11890        let start = serialized_symbol.start.context("invalid start")?;
11891        let end = serialized_symbol.end.context("invalid end")?;
11892        Ok(CoreSymbol {
11893            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11894            source_worktree_id,
11895            source_language_server_id: LanguageServerId::from_proto(
11896                serialized_symbol.language_server_id,
11897            ),
11898            path,
11899            name: serialized_symbol.name,
11900            range: Unclipped(PointUtf16::new(start.row, start.column))
11901                ..Unclipped(PointUtf16::new(end.row, end.column)),
11902            kind,
11903        })
11904    }
11905
11906    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11907        let mut serialized_completion = proto::Completion {
11908            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11909            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11910            new_text: completion.new_text.clone(),
11911            ..proto::Completion::default()
11912        };
11913        match &completion.source {
11914            CompletionSource::Lsp {
11915                insert_range,
11916                server_id,
11917                lsp_completion,
11918                lsp_defaults,
11919                resolved,
11920            } => {
11921                let (old_insert_start, old_insert_end) = insert_range
11922                    .as_ref()
11923                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11924                    .unzip();
11925
11926                serialized_completion.old_insert_start = old_insert_start;
11927                serialized_completion.old_insert_end = old_insert_end;
11928                serialized_completion.source = proto::completion::Source::Lsp as i32;
11929                serialized_completion.server_id = server_id.0 as u64;
11930                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11931                serialized_completion.lsp_defaults = lsp_defaults
11932                    .as_deref()
11933                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11934                serialized_completion.resolved = *resolved;
11935            }
11936            CompletionSource::BufferWord {
11937                word_range,
11938                resolved,
11939            } => {
11940                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11941                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11942                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11943                serialized_completion.resolved = *resolved;
11944            }
11945            CompletionSource::Custom => {
11946                serialized_completion.source = proto::completion::Source::Custom as i32;
11947                serialized_completion.resolved = true;
11948            }
11949            CompletionSource::Dap { sort_text } => {
11950                serialized_completion.source = proto::completion::Source::Dap as i32;
11951                serialized_completion.sort_text = Some(sort_text.clone());
11952            }
11953        }
11954
11955        serialized_completion
11956    }
11957
11958    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11959        let old_replace_start = completion
11960            .old_replace_start
11961            .and_then(deserialize_anchor)
11962            .context("invalid old start")?;
11963        let old_replace_end = completion
11964            .old_replace_end
11965            .and_then(deserialize_anchor)
11966            .context("invalid old end")?;
11967        let insert_range = {
11968            match completion.old_insert_start.zip(completion.old_insert_end) {
11969                Some((start, end)) => {
11970                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11971                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11972                    Some(start..end)
11973                }
11974                None => None,
11975            }
11976        };
11977        Ok(CoreCompletion {
11978            replace_range: old_replace_start..old_replace_end,
11979            new_text: completion.new_text,
11980            source: match proto::completion::Source::from_i32(completion.source) {
11981                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11982                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11983                    insert_range,
11984                    server_id: LanguageServerId::from_proto(completion.server_id),
11985                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11986                    lsp_defaults: completion
11987                        .lsp_defaults
11988                        .as_deref()
11989                        .map(serde_json::from_slice)
11990                        .transpose()?,
11991                    resolved: completion.resolved,
11992                },
11993                Some(proto::completion::Source::BufferWord) => {
11994                    let word_range = completion
11995                        .buffer_word_start
11996                        .and_then(deserialize_anchor)
11997                        .context("invalid buffer word start")?
11998                        ..completion
11999                            .buffer_word_end
12000                            .and_then(deserialize_anchor)
12001                            .context("invalid buffer word end")?;
12002                    CompletionSource::BufferWord {
12003                        word_range,
12004                        resolved: completion.resolved,
12005                    }
12006                }
12007                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12008                    sort_text: completion
12009                        .sort_text
12010                        .context("expected sort text to exist")?,
12011                },
12012                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12013            },
12014        })
12015    }
12016
12017    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12018        let (kind, lsp_action) = match &action.lsp_action {
12019            LspAction::Action(code_action) => (
12020                proto::code_action::Kind::Action as i32,
12021                serde_json::to_vec(code_action).unwrap(),
12022            ),
12023            LspAction::Command(command) => (
12024                proto::code_action::Kind::Command as i32,
12025                serde_json::to_vec(command).unwrap(),
12026            ),
12027            LspAction::CodeLens(code_lens) => (
12028                proto::code_action::Kind::CodeLens as i32,
12029                serde_json::to_vec(code_lens).unwrap(),
12030            ),
12031        };
12032
12033        proto::CodeAction {
12034            server_id: action.server_id.0 as u64,
12035            start: Some(serialize_anchor(&action.range.start)),
12036            end: Some(serialize_anchor(&action.range.end)),
12037            lsp_action,
12038            kind,
12039            resolved: action.resolved,
12040        }
12041    }
12042
12043    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12044        let start = action
12045            .start
12046            .and_then(deserialize_anchor)
12047            .context("invalid start")?;
12048        let end = action
12049            .end
12050            .and_then(deserialize_anchor)
12051            .context("invalid end")?;
12052        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12053            Some(proto::code_action::Kind::Action) => {
12054                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12055            }
12056            Some(proto::code_action::Kind::Command) => {
12057                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12058            }
12059            Some(proto::code_action::Kind::CodeLens) => {
12060                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12061            }
12062            None => anyhow::bail!("Unknown action kind {}", action.kind),
12063        };
12064        Ok(CodeAction {
12065            server_id: LanguageServerId(action.server_id as usize),
12066            range: start..end,
12067            resolved: action.resolved,
12068            lsp_action,
12069        })
12070    }
12071
12072    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12073        match &formatting_result {
12074            Ok(_) => self.last_formatting_failure = None,
12075            Err(error) => {
12076                let error_string = format!("{error:#}");
12077                log::error!("Formatting failed: {error_string}");
12078                self.last_formatting_failure
12079                    .replace(error_string.lines().join(" "));
12080            }
12081        }
12082    }
12083
12084    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12085        self.lsp_server_capabilities.remove(&for_server);
12086        for lsp_data in self.lsp_data.values_mut() {
12087            lsp_data.remove_server_data(for_server);
12088        }
12089        if let Some(local) = self.as_local_mut() {
12090            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12091            local
12092                .workspace_pull_diagnostics_result_ids
12093                .remove(&for_server);
12094            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12095                buffer_servers.remove(&for_server);
12096            }
12097        }
12098    }
12099
12100    pub fn result_id_for_buffer_pull(
12101        &self,
12102        server_id: LanguageServerId,
12103        buffer_id: BufferId,
12104        registration_id: &Option<SharedString>,
12105        cx: &App,
12106    ) -> Option<SharedString> {
12107        let abs_path = self
12108            .buffer_store
12109            .read(cx)
12110            .get(buffer_id)
12111            .and_then(|b| File::from_dyn(b.read(cx).file()))
12112            .map(|f| f.abs_path(cx))?;
12113        self.as_local()?
12114            .buffer_pull_diagnostics_result_ids
12115            .get(&server_id)?
12116            .get(registration_id)?
12117            .get(&abs_path)?
12118            .clone()
12119    }
12120
12121    /// Gets all result_ids for a workspace diagnostics pull request.
12122    /// 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.
12123    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12124    pub fn result_ids_for_workspace_refresh(
12125        &self,
12126        server_id: LanguageServerId,
12127        registration_id: &Option<SharedString>,
12128    ) -> HashMap<PathBuf, SharedString> {
12129        let Some(local) = self.as_local() else {
12130            return HashMap::default();
12131        };
12132        local
12133            .workspace_pull_diagnostics_result_ids
12134            .get(&server_id)
12135            .into_iter()
12136            .filter_map(|diagnostics| diagnostics.get(registration_id))
12137            .flatten()
12138            .filter_map(|(abs_path, result_id)| {
12139                let result_id = local
12140                    .buffer_pull_diagnostics_result_ids
12141                    .get(&server_id)
12142                    .and_then(|buffer_ids_result_ids| {
12143                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12144                    })
12145                    .cloned()
12146                    .flatten()
12147                    .or_else(|| result_id.clone())?;
12148                Some((abs_path.clone(), result_id))
12149            })
12150            .collect()
12151    }
12152
12153    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12154        if let Some(LanguageServerState::Running {
12155            workspace_diagnostics_refresh_tasks,
12156            ..
12157        }) = self
12158            .as_local_mut()
12159            .and_then(|local| local.language_servers.get_mut(&server_id))
12160        {
12161            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12162                diagnostics.refresh_tx.try_send(()).ok();
12163            }
12164        }
12165    }
12166
12167    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12168        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12169            return;
12170        };
12171        let Some(local) = self.as_local_mut() else {
12172            return;
12173        };
12174
12175        for server_id in buffer.update(cx, |buffer, cx| {
12176            local.language_server_ids_for_buffer(buffer, cx)
12177        }) {
12178            if let Some(LanguageServerState::Running {
12179                workspace_diagnostics_refresh_tasks,
12180                ..
12181            }) = local.language_servers.get_mut(&server_id)
12182            {
12183                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12184                    diagnostics.refresh_tx.try_send(()).ok();
12185                }
12186            }
12187        }
12188    }
12189
12190    fn apply_workspace_diagnostic_report(
12191        &mut self,
12192        server_id: LanguageServerId,
12193        report: lsp::WorkspaceDiagnosticReportResult,
12194        registration_id: Option<SharedString>,
12195        cx: &mut Context<Self>,
12196    ) {
12197        let workspace_diagnostics =
12198            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12199                report,
12200                server_id,
12201                registration_id,
12202            );
12203        let mut unchanged_buffers = HashMap::default();
12204        let workspace_diagnostics_updates = workspace_diagnostics
12205            .into_iter()
12206            .filter_map(
12207                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12208                    LspPullDiagnostics::Response {
12209                        server_id,
12210                        uri,
12211                        diagnostics,
12212                        registration_id,
12213                    } => Some((
12214                        server_id,
12215                        uri,
12216                        diagnostics,
12217                        workspace_diagnostics.version,
12218                        registration_id,
12219                    )),
12220                    LspPullDiagnostics::Default => None,
12221                },
12222            )
12223            .fold(
12224                HashMap::default(),
12225                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12226                    let (result_id, diagnostics) = match diagnostics {
12227                        PulledDiagnostics::Unchanged { result_id } => {
12228                            unchanged_buffers
12229                                .entry(new_registration_id.clone())
12230                                .or_insert_with(HashSet::default)
12231                                .insert(uri.clone());
12232                            (Some(result_id), Vec::new())
12233                        }
12234                        PulledDiagnostics::Changed {
12235                            result_id,
12236                            diagnostics,
12237                        } => (result_id, diagnostics),
12238                    };
12239                    let disk_based_sources = Cow::Owned(
12240                        self.language_server_adapter_for_id(server_id)
12241                            .as_ref()
12242                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12243                            .unwrap_or(&[])
12244                            .to_vec(),
12245                    );
12246
12247                    let Some(abs_path) = uri.to_file_path().ok() else {
12248                        return acc;
12249                    };
12250                    let Some((worktree, relative_path)) =
12251                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12252                    else {
12253                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12254                        return acc;
12255                    };
12256                    let worktree_id = worktree.read(cx).id();
12257                    let project_path = ProjectPath {
12258                        worktree_id,
12259                        path: relative_path,
12260                    };
12261                    if let Some(local_lsp_store) = self.as_local_mut() {
12262                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12263                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12264                    }
12265                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12266                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12267                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12268                        acc.entry(server_id)
12269                            .or_insert_with(HashMap::default)
12270                            .entry(new_registration_id.clone())
12271                            .or_insert_with(Vec::new)
12272                            .push(DocumentDiagnosticsUpdate {
12273                                server_id,
12274                                diagnostics: lsp::PublishDiagnosticsParams {
12275                                    uri,
12276                                    diagnostics,
12277                                    version,
12278                                },
12279                                result_id,
12280                                disk_based_sources,
12281                                registration_id: new_registration_id,
12282                            });
12283                    }
12284                    acc
12285                },
12286            );
12287
12288        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12289            for (registration_id, diagnostic_updates) in diagnostic_updates {
12290                self.merge_lsp_diagnostics(
12291                    DiagnosticSourceKind::Pulled,
12292                    diagnostic_updates,
12293                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12294                        DiagnosticSourceKind::Pulled => {
12295                            old_diagnostic.registration_id != registration_id
12296                                || unchanged_buffers
12297                                    .get(&old_diagnostic.registration_id)
12298                                    .is_some_and(|unchanged_buffers| {
12299                                        unchanged_buffers.contains(&document_uri)
12300                                    })
12301                        }
12302                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12303                    },
12304                    cx,
12305                )
12306                .log_err();
12307            }
12308        }
12309    }
12310
12311    fn register_server_capabilities(
12312        &mut self,
12313        server_id: LanguageServerId,
12314        params: lsp::RegistrationParams,
12315        cx: &mut Context<Self>,
12316    ) -> anyhow::Result<()> {
12317        let server = self
12318            .language_server_for_id(server_id)
12319            .with_context(|| format!("no server {server_id} found"))?;
12320        for reg in params.registrations {
12321            match reg.method.as_str() {
12322                "workspace/didChangeWatchedFiles" => {
12323                    if let Some(options) = reg.register_options {
12324                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12325                            let caps = serde_json::from_value(options)?;
12326                            local_lsp_store
12327                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12328                            true
12329                        } else {
12330                            false
12331                        };
12332                        if notify {
12333                            notify_server_capabilities_updated(&server, cx);
12334                        }
12335                    }
12336                }
12337                "workspace/didChangeConfiguration" => {
12338                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12339                }
12340                "workspace/didChangeWorkspaceFolders" => {
12341                    // In this case register options is an empty object, we can ignore it
12342                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12343                        supported: Some(true),
12344                        change_notifications: Some(OneOf::Right(reg.id)),
12345                    };
12346                    server.update_capabilities(|capabilities| {
12347                        capabilities
12348                            .workspace
12349                            .get_or_insert_default()
12350                            .workspace_folders = Some(caps);
12351                    });
12352                    notify_server_capabilities_updated(&server, cx);
12353                }
12354                "workspace/symbol" => {
12355                    let options = parse_register_capabilities(reg)?;
12356                    server.update_capabilities(|capabilities| {
12357                        capabilities.workspace_symbol_provider = Some(options);
12358                    });
12359                    notify_server_capabilities_updated(&server, cx);
12360                }
12361                "workspace/fileOperations" => {
12362                    if let Some(options) = reg.register_options {
12363                        let caps = serde_json::from_value(options)?;
12364                        server.update_capabilities(|capabilities| {
12365                            capabilities
12366                                .workspace
12367                                .get_or_insert_default()
12368                                .file_operations = Some(caps);
12369                        });
12370                        notify_server_capabilities_updated(&server, cx);
12371                    }
12372                }
12373                "workspace/executeCommand" => {
12374                    if let Some(options) = reg.register_options {
12375                        let options = serde_json::from_value(options)?;
12376                        server.update_capabilities(|capabilities| {
12377                            capabilities.execute_command_provider = Some(options);
12378                        });
12379                        notify_server_capabilities_updated(&server, cx);
12380                    }
12381                }
12382                "textDocument/rangeFormatting" => {
12383                    let options = parse_register_capabilities(reg)?;
12384                    server.update_capabilities(|capabilities| {
12385                        capabilities.document_range_formatting_provider = Some(options);
12386                    });
12387                    notify_server_capabilities_updated(&server, cx);
12388                }
12389                "textDocument/onTypeFormatting" => {
12390                    if let Some(options) = reg
12391                        .register_options
12392                        .map(serde_json::from_value)
12393                        .transpose()?
12394                    {
12395                        server.update_capabilities(|capabilities| {
12396                            capabilities.document_on_type_formatting_provider = Some(options);
12397                        });
12398                        notify_server_capabilities_updated(&server, cx);
12399                    }
12400                }
12401                "textDocument/formatting" => {
12402                    let options = parse_register_capabilities(reg)?;
12403                    server.update_capabilities(|capabilities| {
12404                        capabilities.document_formatting_provider = Some(options);
12405                    });
12406                    notify_server_capabilities_updated(&server, cx);
12407                }
12408                "textDocument/rename" => {
12409                    let options = parse_register_capabilities(reg)?;
12410                    server.update_capabilities(|capabilities| {
12411                        capabilities.rename_provider = Some(options);
12412                    });
12413                    notify_server_capabilities_updated(&server, cx);
12414                }
12415                "textDocument/inlayHint" => {
12416                    let options = parse_register_capabilities(reg)?;
12417                    server.update_capabilities(|capabilities| {
12418                        capabilities.inlay_hint_provider = Some(options);
12419                    });
12420                    notify_server_capabilities_updated(&server, cx);
12421                }
12422                "textDocument/documentSymbol" => {
12423                    let options = parse_register_capabilities(reg)?;
12424                    server.update_capabilities(|capabilities| {
12425                        capabilities.document_symbol_provider = Some(options);
12426                    });
12427                    notify_server_capabilities_updated(&server, cx);
12428                }
12429                "textDocument/codeAction" => {
12430                    let options = parse_register_capabilities(reg)?;
12431                    let provider = match options {
12432                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12433                        OneOf::Right(caps) => caps,
12434                    };
12435                    server.update_capabilities(|capabilities| {
12436                        capabilities.code_action_provider = Some(provider);
12437                    });
12438                    notify_server_capabilities_updated(&server, cx);
12439                }
12440                "textDocument/definition" => {
12441                    let options = parse_register_capabilities(reg)?;
12442                    server.update_capabilities(|capabilities| {
12443                        capabilities.definition_provider = Some(options);
12444                    });
12445                    notify_server_capabilities_updated(&server, cx);
12446                }
12447                "textDocument/completion" => {
12448                    if let Some(caps) = reg
12449                        .register_options
12450                        .map(serde_json::from_value::<CompletionOptions>)
12451                        .transpose()?
12452                    {
12453                        server.update_capabilities(|capabilities| {
12454                            capabilities.completion_provider = Some(caps.clone());
12455                        });
12456
12457                        if let Some(local) = self.as_local() {
12458                            let mut buffers_with_language_server = Vec::new();
12459                            for handle in self.buffer_store.read(cx).buffers() {
12460                                let buffer_id = handle.read(cx).remote_id();
12461                                if local
12462                                    .buffers_opened_in_servers
12463                                    .get(&buffer_id)
12464                                    .filter(|s| s.contains(&server_id))
12465                                    .is_some()
12466                                {
12467                                    buffers_with_language_server.push(handle);
12468                                }
12469                            }
12470                            let triggers = caps
12471                                .trigger_characters
12472                                .unwrap_or_default()
12473                                .into_iter()
12474                                .collect::<BTreeSet<_>>();
12475                            for handle in buffers_with_language_server {
12476                                let triggers = triggers.clone();
12477                                let _ = handle.update(cx, move |buffer, cx| {
12478                                    buffer.set_completion_triggers(server_id, triggers, cx);
12479                                });
12480                            }
12481                        }
12482                        notify_server_capabilities_updated(&server, cx);
12483                    }
12484                }
12485                "textDocument/hover" => {
12486                    let options = parse_register_capabilities(reg)?;
12487                    let provider = match options {
12488                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12489                        OneOf::Right(caps) => caps,
12490                    };
12491                    server.update_capabilities(|capabilities| {
12492                        capabilities.hover_provider = Some(provider);
12493                    });
12494                    notify_server_capabilities_updated(&server, cx);
12495                }
12496                "textDocument/signatureHelp" => {
12497                    if let Some(caps) = reg
12498                        .register_options
12499                        .map(serde_json::from_value)
12500                        .transpose()?
12501                    {
12502                        server.update_capabilities(|capabilities| {
12503                            capabilities.signature_help_provider = Some(caps);
12504                        });
12505                        notify_server_capabilities_updated(&server, cx);
12506                    }
12507                }
12508                "textDocument/didChange" => {
12509                    if let Some(sync_kind) = reg
12510                        .register_options
12511                        .and_then(|opts| opts.get("syncKind").cloned())
12512                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12513                        .transpose()?
12514                    {
12515                        server.update_capabilities(|capabilities| {
12516                            let mut sync_options =
12517                                Self::take_text_document_sync_options(capabilities);
12518                            sync_options.change = Some(sync_kind);
12519                            capabilities.text_document_sync =
12520                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12521                        });
12522                        notify_server_capabilities_updated(&server, cx);
12523                    }
12524                }
12525                "textDocument/didSave" => {
12526                    if let Some(include_text) = reg
12527                        .register_options
12528                        .map(|opts| {
12529                            let transpose = opts
12530                                .get("includeText")
12531                                .cloned()
12532                                .map(serde_json::from_value::<Option<bool>>)
12533                                .transpose();
12534                            match transpose {
12535                                Ok(value) => Ok(value.flatten()),
12536                                Err(e) => Err(e),
12537                            }
12538                        })
12539                        .transpose()?
12540                    {
12541                        server.update_capabilities(|capabilities| {
12542                            let mut sync_options =
12543                                Self::take_text_document_sync_options(capabilities);
12544                            sync_options.save =
12545                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12546                                    include_text,
12547                                }));
12548                            capabilities.text_document_sync =
12549                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12550                        });
12551                        notify_server_capabilities_updated(&server, cx);
12552                    }
12553                }
12554                "textDocument/codeLens" => {
12555                    if let Some(caps) = reg
12556                        .register_options
12557                        .map(serde_json::from_value)
12558                        .transpose()?
12559                    {
12560                        server.update_capabilities(|capabilities| {
12561                            capabilities.code_lens_provider = Some(caps);
12562                        });
12563                        notify_server_capabilities_updated(&server, cx);
12564                    }
12565                }
12566                "textDocument/diagnostic" => {
12567                    if let Some(caps) = reg
12568                        .register_options
12569                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12570                        .transpose()?
12571                    {
12572                        let local = self
12573                            .as_local_mut()
12574                            .context("Expected LSP Store to be local")?;
12575                        let state = local
12576                            .language_servers
12577                            .get_mut(&server_id)
12578                            .context("Could not obtain Language Servers state")?;
12579                        local
12580                            .language_server_dynamic_registrations
12581                            .entry(server_id)
12582                            .or_default()
12583                            .diagnostics
12584                            .insert(Some(reg.id.clone()), caps.clone());
12585
12586                        let supports_workspace_diagnostics =
12587                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12588                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12589                                    diagnostic_options.workspace_diagnostics
12590                                }
12591                                DiagnosticServerCapabilities::RegistrationOptions(
12592                                    diagnostic_registration_options,
12593                                ) => {
12594                                    diagnostic_registration_options
12595                                        .diagnostic_options
12596                                        .workspace_diagnostics
12597                                }
12598                            };
12599
12600                        if supports_workspace_diagnostics(&caps) {
12601                            if let LanguageServerState::Running {
12602                                workspace_diagnostics_refresh_tasks,
12603                                ..
12604                            } = state
12605                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12606                                    Some(reg.id.clone()),
12607                                    caps.clone(),
12608                                    server.clone(),
12609                                    cx,
12610                                )
12611                            {
12612                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12613                            }
12614                        }
12615
12616                        server.update_capabilities(|capabilities| {
12617                            capabilities.diagnostic_provider = Some(caps);
12618                        });
12619
12620                        notify_server_capabilities_updated(&server, cx);
12621                    }
12622                }
12623                "textDocument/documentColor" => {
12624                    let options = parse_register_capabilities(reg)?;
12625                    let provider = match options {
12626                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12627                        OneOf::Right(caps) => caps,
12628                    };
12629                    server.update_capabilities(|capabilities| {
12630                        capabilities.color_provider = Some(provider);
12631                    });
12632                    notify_server_capabilities_updated(&server, cx);
12633                }
12634                _ => log::warn!("unhandled capability registration: {reg:?}"),
12635            }
12636        }
12637
12638        Ok(())
12639    }
12640
12641    fn unregister_server_capabilities(
12642        &mut self,
12643        server_id: LanguageServerId,
12644        params: lsp::UnregistrationParams,
12645        cx: &mut Context<Self>,
12646    ) -> anyhow::Result<()> {
12647        let server = self
12648            .language_server_for_id(server_id)
12649            .with_context(|| format!("no server {server_id} found"))?;
12650        for unreg in params.unregisterations.iter() {
12651            match unreg.method.as_str() {
12652                "workspace/didChangeWatchedFiles" => {
12653                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12654                        local_lsp_store
12655                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12656                        true
12657                    } else {
12658                        false
12659                    };
12660                    if notify {
12661                        notify_server_capabilities_updated(&server, cx);
12662                    }
12663                }
12664                "workspace/didChangeConfiguration" => {
12665                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12666                }
12667                "workspace/didChangeWorkspaceFolders" => {
12668                    server.update_capabilities(|capabilities| {
12669                        capabilities
12670                            .workspace
12671                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12672                                workspace_folders: None,
12673                                file_operations: None,
12674                            })
12675                            .workspace_folders = None;
12676                    });
12677                    notify_server_capabilities_updated(&server, cx);
12678                }
12679                "workspace/symbol" => {
12680                    server.update_capabilities(|capabilities| {
12681                        capabilities.workspace_symbol_provider = None
12682                    });
12683                    notify_server_capabilities_updated(&server, cx);
12684                }
12685                "workspace/fileOperations" => {
12686                    server.update_capabilities(|capabilities| {
12687                        capabilities
12688                            .workspace
12689                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12690                                workspace_folders: None,
12691                                file_operations: None,
12692                            })
12693                            .file_operations = None;
12694                    });
12695                    notify_server_capabilities_updated(&server, cx);
12696                }
12697                "workspace/executeCommand" => {
12698                    server.update_capabilities(|capabilities| {
12699                        capabilities.execute_command_provider = None;
12700                    });
12701                    notify_server_capabilities_updated(&server, cx);
12702                }
12703                "textDocument/rangeFormatting" => {
12704                    server.update_capabilities(|capabilities| {
12705                        capabilities.document_range_formatting_provider = None
12706                    });
12707                    notify_server_capabilities_updated(&server, cx);
12708                }
12709                "textDocument/onTypeFormatting" => {
12710                    server.update_capabilities(|capabilities| {
12711                        capabilities.document_on_type_formatting_provider = None;
12712                    });
12713                    notify_server_capabilities_updated(&server, cx);
12714                }
12715                "textDocument/formatting" => {
12716                    server.update_capabilities(|capabilities| {
12717                        capabilities.document_formatting_provider = None;
12718                    });
12719                    notify_server_capabilities_updated(&server, cx);
12720                }
12721                "textDocument/rename" => {
12722                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12723                    notify_server_capabilities_updated(&server, cx);
12724                }
12725                "textDocument/codeAction" => {
12726                    server.update_capabilities(|capabilities| {
12727                        capabilities.code_action_provider = None;
12728                    });
12729                    notify_server_capabilities_updated(&server, cx);
12730                }
12731                "textDocument/definition" => {
12732                    server.update_capabilities(|capabilities| {
12733                        capabilities.definition_provider = None;
12734                    });
12735                    notify_server_capabilities_updated(&server, cx);
12736                }
12737                "textDocument/completion" => {
12738                    server.update_capabilities(|capabilities| {
12739                        capabilities.completion_provider = None;
12740                    });
12741                    notify_server_capabilities_updated(&server, cx);
12742                }
12743                "textDocument/hover" => {
12744                    server.update_capabilities(|capabilities| {
12745                        capabilities.hover_provider = None;
12746                    });
12747                    notify_server_capabilities_updated(&server, cx);
12748                }
12749                "textDocument/signatureHelp" => {
12750                    server.update_capabilities(|capabilities| {
12751                        capabilities.signature_help_provider = None;
12752                    });
12753                    notify_server_capabilities_updated(&server, cx);
12754                }
12755                "textDocument/didChange" => {
12756                    server.update_capabilities(|capabilities| {
12757                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12758                        sync_options.change = None;
12759                        capabilities.text_document_sync =
12760                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12761                    });
12762                    notify_server_capabilities_updated(&server, cx);
12763                }
12764                "textDocument/didSave" => {
12765                    server.update_capabilities(|capabilities| {
12766                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12767                        sync_options.save = None;
12768                        capabilities.text_document_sync =
12769                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12770                    });
12771                    notify_server_capabilities_updated(&server, cx);
12772                }
12773                "textDocument/codeLens" => {
12774                    server.update_capabilities(|capabilities| {
12775                        capabilities.code_lens_provider = None;
12776                    });
12777                    notify_server_capabilities_updated(&server, cx);
12778                }
12779                "textDocument/diagnostic" => {
12780                    let local = self
12781                        .as_local_mut()
12782                        .context("Expected LSP Store to be local")?;
12783
12784                    let state = local
12785                        .language_servers
12786                        .get_mut(&server_id)
12787                        .context("Could not obtain Language Servers state")?;
12788                    let registrations = local
12789                        .language_server_dynamic_registrations
12790                        .get_mut(&server_id)
12791                        .with_context(|| {
12792                            format!("Expected dynamic registration to exist for server {server_id}")
12793                        })?;
12794                    registrations.diagnostics
12795                        .remove(&Some(unreg.id.clone()))
12796                        .with_context(|| format!(
12797                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12798                            unreg.id)
12799                        )?;
12800                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12801
12802                    if let LanguageServerState::Running {
12803                        workspace_diagnostics_refresh_tasks,
12804                        ..
12805                    } = state
12806                    {
12807                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12808                    }
12809
12810                    if removed_last_diagnostic_provider {
12811                        server.update_capabilities(|capabilities| {
12812                            debug_assert!(capabilities.diagnostic_provider.is_some());
12813                            capabilities.diagnostic_provider = None;
12814                        });
12815                    }
12816
12817                    notify_server_capabilities_updated(&server, cx);
12818                }
12819                "textDocument/documentColor" => {
12820                    server.update_capabilities(|capabilities| {
12821                        capabilities.color_provider = None;
12822                    });
12823                    notify_server_capabilities_updated(&server, cx);
12824                }
12825                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12826            }
12827        }
12828
12829        Ok(())
12830    }
12831
12832    async fn deduplicate_range_based_lsp_requests<T>(
12833        lsp_store: &Entity<Self>,
12834        server_id: Option<LanguageServerId>,
12835        lsp_request_id: LspRequestId,
12836        proto_request: &T::ProtoRequest,
12837        range: Range<Anchor>,
12838        cx: &mut AsyncApp,
12839    ) -> Result<()>
12840    where
12841        T: LspCommand,
12842        T::ProtoRequest: proto::LspRequestMessage,
12843    {
12844        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12845        let version = deserialize_version(proto_request.buffer_version());
12846        let buffer = lsp_store.update(cx, |this, cx| {
12847            this.buffer_store.read(cx).get_existing(buffer_id)
12848        })??;
12849        buffer
12850            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12851            .await?;
12852        lsp_store.update(cx, |lsp_store, cx| {
12853            let buffer_snapshot = buffer.read(cx).snapshot();
12854            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12855            let chunks_queried_for = lsp_data
12856                .inlay_hints
12857                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12858                .collect::<Vec<_>>();
12859            match chunks_queried_for.as_slice() {
12860                &[chunk] => {
12861                    let key = LspKey {
12862                        request_type: TypeId::of::<T>(),
12863                        server_queried: server_id,
12864                    };
12865                    let previous_request = lsp_data
12866                        .chunk_lsp_requests
12867                        .entry(key)
12868                        .or_default()
12869                        .insert(chunk, lsp_request_id);
12870                    if let Some((previous_request, running_requests)) =
12871                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12872                    {
12873                        running_requests.remove(&previous_request);
12874                    }
12875                }
12876                _ambiguous_chunks => {
12877                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12878                    // there, a buffer version-based check will be performed and outdated requests discarded.
12879                }
12880            }
12881            anyhow::Ok(())
12882        })??;
12883
12884        Ok(())
12885    }
12886
12887    async fn query_lsp_locally<T>(
12888        lsp_store: Entity<Self>,
12889        for_server_id: Option<LanguageServerId>,
12890        sender_id: proto::PeerId,
12891        lsp_request_id: LspRequestId,
12892        proto_request: T::ProtoRequest,
12893        position: Option<Anchor>,
12894        cx: &mut AsyncApp,
12895    ) -> Result<()>
12896    where
12897        T: LspCommand + Clone,
12898        T::ProtoRequest: proto::LspRequestMessage,
12899        <T::ProtoRequest as proto::RequestMessage>::Response:
12900            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12901    {
12902        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12903        let version = deserialize_version(proto_request.buffer_version());
12904        let buffer = lsp_store.update(cx, |this, cx| {
12905            this.buffer_store.read(cx).get_existing(buffer_id)
12906        })??;
12907        buffer
12908            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12909            .await?;
12910        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12911        let request =
12912            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12913        let key = LspKey {
12914            request_type: TypeId::of::<T>(),
12915            server_queried: for_server_id,
12916        };
12917        lsp_store.update(cx, |lsp_store, cx| {
12918            let request_task = match for_server_id {
12919                Some(server_id) => {
12920                    let server_task = lsp_store.request_lsp(
12921                        buffer.clone(),
12922                        LanguageServerToQuery::Other(server_id),
12923                        request.clone(),
12924                        cx,
12925                    );
12926                    cx.background_spawn(async move {
12927                        let mut responses = Vec::new();
12928                        match server_task.await {
12929                            Ok(response) => responses.push((server_id, response)),
12930                            // rust-analyzer likes to error with this when its still loading up
12931                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12932                            Err(e) => log::error!(
12933                                "Error handling response for request {request:?}: {e:#}"
12934                            ),
12935                        }
12936                        responses
12937                    })
12938                }
12939                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12940            };
12941            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12942            if T::ProtoRequest::stop_previous_requests() {
12943                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12944                    lsp_requests.clear();
12945                }
12946            }
12947            lsp_data.lsp_requests.entry(key).or_default().insert(
12948                lsp_request_id,
12949                cx.spawn(async move |lsp_store, cx| {
12950                    let response = request_task.await;
12951                    lsp_store
12952                        .update(cx, |lsp_store, cx| {
12953                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12954                            {
12955                                let response = response
12956                                    .into_iter()
12957                                    .map(|(server_id, response)| {
12958                                        (
12959                                            server_id.to_proto(),
12960                                            T::response_to_proto(
12961                                                response,
12962                                                lsp_store,
12963                                                sender_id,
12964                                                &buffer_version,
12965                                                cx,
12966                                            )
12967                                            .into(),
12968                                        )
12969                                    })
12970                                    .collect::<HashMap<_, _>>();
12971                                match client.send_lsp_response::<T::ProtoRequest>(
12972                                    project_id,
12973                                    lsp_request_id,
12974                                    response,
12975                                ) {
12976                                    Ok(()) => {}
12977                                    Err(e) => {
12978                                        log::error!("Failed to send LSP response: {e:#}",)
12979                                    }
12980                                }
12981                            }
12982                        })
12983                        .ok();
12984                }),
12985            );
12986        })?;
12987        Ok(())
12988    }
12989
12990    fn take_text_document_sync_options(
12991        capabilities: &mut lsp::ServerCapabilities,
12992    ) -> lsp::TextDocumentSyncOptions {
12993        match capabilities.text_document_sync.take() {
12994            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12995            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12996                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12997                sync_options.change = Some(sync_kind);
12998                sync_options
12999            }
13000            None => lsp::TextDocumentSyncOptions::default(),
13001        }
13002    }
13003
13004    #[cfg(any(test, feature = "test-support"))]
13005    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13006        Some(
13007            self.lsp_data
13008                .get_mut(&buffer_id)?
13009                .code_lens
13010                .take()?
13011                .update
13012                .take()?
13013                .1,
13014        )
13015    }
13016
13017    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13018        self.downstream_client.clone()
13019    }
13020
13021    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13022        self.worktree_store.clone()
13023    }
13024
13025    /// Gets what's stored in the LSP data for the given buffer.
13026    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13027        self.lsp_data.get_mut(&buffer_id)
13028    }
13029
13030    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13031    /// new [`BufferLspData`] will be created to replace the previous state.
13032    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13033        let (buffer_id, buffer_version) =
13034            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13035        let lsp_data = self
13036            .lsp_data
13037            .entry(buffer_id)
13038            .or_insert_with(|| BufferLspData::new(buffer, cx));
13039        if buffer_version.changed_since(&lsp_data.buffer_version) {
13040            *lsp_data = BufferLspData::new(buffer, cx);
13041        }
13042        lsp_data
13043    }
13044}
13045
13046// Registration with registerOptions as null, should fallback to true.
13047// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13048fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13049    reg: lsp::Registration,
13050) -> Result<OneOf<bool, T>> {
13051    Ok(match reg.register_options {
13052        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13053        None => OneOf::Left(true),
13054    })
13055}
13056
13057fn subscribe_to_binary_statuses(
13058    languages: &Arc<LanguageRegistry>,
13059    cx: &mut Context<'_, LspStore>,
13060) -> Task<()> {
13061    let mut server_statuses = languages.language_server_binary_statuses();
13062    cx.spawn(async move |lsp_store, cx| {
13063        while let Some((server_name, binary_status)) = server_statuses.next().await {
13064            if lsp_store
13065                .update(cx, |_, cx| {
13066                    let mut message = None;
13067                    let binary_status = match binary_status {
13068                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13069                        BinaryStatus::CheckingForUpdate => {
13070                            proto::ServerBinaryStatus::CheckingForUpdate
13071                        }
13072                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13073                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13074                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13075                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13076                        BinaryStatus::Failed { error } => {
13077                            message = Some(error);
13078                            proto::ServerBinaryStatus::Failed
13079                        }
13080                    };
13081                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13082                        // Binary updates are about the binary that might not have any language server id at that point.
13083                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13084                        language_server_id: LanguageServerId(0),
13085                        name: Some(server_name),
13086                        message: proto::update_language_server::Variant::StatusUpdate(
13087                            proto::StatusUpdate {
13088                                message,
13089                                status: Some(proto::status_update::Status::Binary(
13090                                    binary_status as i32,
13091                                )),
13092                            },
13093                        ),
13094                    });
13095                })
13096                .is_err()
13097            {
13098                break;
13099            }
13100        }
13101    })
13102}
13103
13104fn lsp_workspace_diagnostics_refresh(
13105    registration_id: Option<String>,
13106    options: DiagnosticServerCapabilities,
13107    server: Arc<LanguageServer>,
13108    cx: &mut Context<'_, LspStore>,
13109) -> Option<WorkspaceRefreshTask> {
13110    let identifier = workspace_diagnostic_identifier(&options)?;
13111    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13112
13113    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13114    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13115    refresh_tx.try_send(()).ok();
13116
13117    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13118        let mut attempts = 0;
13119        let max_attempts = 50;
13120        let mut requests = 0;
13121
13122        loop {
13123            let Some(()) = refresh_rx.recv().await else {
13124                return;
13125            };
13126
13127            'request: loop {
13128                requests += 1;
13129                if attempts > max_attempts {
13130                    log::error!(
13131                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13132                    );
13133                    return;
13134                }
13135                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13136                cx.background_executor()
13137                    .timer(Duration::from_millis(backoff_millis))
13138                    .await;
13139                attempts += 1;
13140
13141                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13142                    lsp_store
13143                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13144                        .into_iter()
13145                        .filter_map(|(abs_path, result_id)| {
13146                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13147                            Some(lsp::PreviousResultId {
13148                                uri,
13149                                value: result_id.to_string(),
13150                            })
13151                        })
13152                        .collect()
13153                }) else {
13154                    return;
13155                };
13156
13157                let token = if let Some(registration_id) = &registration_id {
13158                    format!(
13159                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13160                        server.server_id(),
13161                    )
13162                } else {
13163                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13164                };
13165
13166                progress_rx.try_recv().ok();
13167                let timer =
13168                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13169                let progress = pin!(progress_rx.recv().fuse());
13170                let response_result = server
13171                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13172                        lsp::WorkspaceDiagnosticParams {
13173                            previous_result_ids,
13174                            identifier: identifier.clone(),
13175                            work_done_progress_params: Default::default(),
13176                            partial_result_params: lsp::PartialResultParams {
13177                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13178                            },
13179                        },
13180                        select(timer, progress).then(|either| match either {
13181                            Either::Left((message, ..)) => ready(message).left_future(),
13182                            Either::Right(..) => pending::<String>().right_future(),
13183                        }),
13184                    )
13185                    .await;
13186
13187                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13188                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13189                match response_result {
13190                    ConnectionResult::Timeout => {
13191                        log::error!("Timeout during workspace diagnostics pull");
13192                        continue 'request;
13193                    }
13194                    ConnectionResult::ConnectionReset => {
13195                        log::error!("Server closed a workspace diagnostics pull request");
13196                        continue 'request;
13197                    }
13198                    ConnectionResult::Result(Err(e)) => {
13199                        log::error!("Error during workspace diagnostics pull: {e:#}");
13200                        break 'request;
13201                    }
13202                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13203                        attempts = 0;
13204                        if lsp_store
13205                            .update(cx, |lsp_store, cx| {
13206                                lsp_store.apply_workspace_diagnostic_report(
13207                                    server.server_id(),
13208                                    pulled_diagnostics,
13209                                    registration_id_shared.clone(),
13210                                    cx,
13211                                )
13212                            })
13213                            .is_err()
13214                        {
13215                            return;
13216                        }
13217                        break 'request;
13218                    }
13219                }
13220            }
13221        }
13222    });
13223
13224    Some(WorkspaceRefreshTask {
13225        refresh_tx,
13226        progress_tx,
13227        task: workspace_query_language_server,
13228    })
13229}
13230
13231fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13232    match &options {
13233        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13234            diagnostic_options.identifier.clone()
13235        }
13236        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13237            let diagnostic_options = &registration_options.diagnostic_options;
13238            diagnostic_options.identifier.clone()
13239        }
13240    }
13241}
13242
13243fn workspace_diagnostic_identifier(
13244    options: &DiagnosticServerCapabilities,
13245) -> Option<Option<String>> {
13246    match &options {
13247        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13248            if !diagnostic_options.workspace_diagnostics {
13249                return None;
13250            }
13251            Some(diagnostic_options.identifier.clone())
13252        }
13253        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13254            let diagnostic_options = &registration_options.diagnostic_options;
13255            if !diagnostic_options.workspace_diagnostics {
13256                return None;
13257            }
13258            Some(diagnostic_options.identifier.clone())
13259        }
13260    }
13261}
13262
13263fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13264    let CompletionSource::BufferWord {
13265        word_range,
13266        resolved,
13267    } = &mut completion.source
13268    else {
13269        return;
13270    };
13271    if *resolved {
13272        return;
13273    }
13274
13275    if completion.new_text
13276        != snapshot
13277            .text_for_range(word_range.clone())
13278            .collect::<String>()
13279    {
13280        return;
13281    }
13282
13283    let mut offset = 0;
13284    for chunk in snapshot.chunks(word_range.clone(), true) {
13285        let end_offset = offset + chunk.text.len();
13286        if let Some(highlight_id) = chunk.syntax_highlight_id {
13287            completion
13288                .label
13289                .runs
13290                .push((offset..end_offset, highlight_id));
13291        }
13292        offset = end_offset;
13293    }
13294    *resolved = true;
13295}
13296
13297impl EventEmitter<LspStoreEvent> for LspStore {}
13298
13299fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13300    hover
13301        .contents
13302        .retain(|hover_block| !hover_block.text.trim().is_empty());
13303    if hover.contents.is_empty() {
13304        None
13305    } else {
13306        Some(hover)
13307    }
13308}
13309
13310async fn populate_labels_for_completions(
13311    new_completions: Vec<CoreCompletion>,
13312    language: Option<Arc<Language>>,
13313    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13314) -> Vec<Completion> {
13315    let lsp_completions = new_completions
13316        .iter()
13317        .filter_map(|new_completion| {
13318            new_completion
13319                .source
13320                .lsp_completion(true)
13321                .map(|lsp_completion| lsp_completion.into_owned())
13322        })
13323        .collect::<Vec<_>>();
13324
13325    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13326        lsp_adapter
13327            .labels_for_completions(&lsp_completions, language)
13328            .await
13329            .log_err()
13330            .unwrap_or_default()
13331    } else {
13332        Vec::new()
13333    }
13334    .into_iter()
13335    .fuse();
13336
13337    let mut completions = Vec::new();
13338    for completion in new_completions {
13339        match completion.source.lsp_completion(true) {
13340            Some(lsp_completion) => {
13341                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13342
13343                let mut label = labels.next().flatten().unwrap_or_else(|| {
13344                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13345                });
13346                ensure_uniform_list_compatible_label(&mut label);
13347                completions.push(Completion {
13348                    label,
13349                    documentation,
13350                    replace_range: completion.replace_range,
13351                    new_text: completion.new_text,
13352                    insert_text_mode: lsp_completion.insert_text_mode,
13353                    source: completion.source,
13354                    icon_path: None,
13355                    confirm: None,
13356                    match_start: None,
13357                    snippet_deduplication_key: None,
13358                });
13359            }
13360            None => {
13361                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13362                ensure_uniform_list_compatible_label(&mut label);
13363                completions.push(Completion {
13364                    label,
13365                    documentation: None,
13366                    replace_range: completion.replace_range,
13367                    new_text: completion.new_text,
13368                    source: completion.source,
13369                    insert_text_mode: None,
13370                    icon_path: None,
13371                    confirm: None,
13372                    match_start: None,
13373                    snippet_deduplication_key: None,
13374                });
13375            }
13376        }
13377    }
13378    completions
13379}
13380
13381#[derive(Debug)]
13382pub enum LanguageServerToQuery {
13383    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13384    FirstCapable,
13385    /// Query a specific language server.
13386    Other(LanguageServerId),
13387}
13388
13389#[derive(Default)]
13390struct RenamePathsWatchedForServer {
13391    did_rename: Vec<RenameActionPredicate>,
13392    will_rename: Vec<RenameActionPredicate>,
13393}
13394
13395impl RenamePathsWatchedForServer {
13396    fn with_did_rename_patterns(
13397        mut self,
13398        did_rename: Option<&FileOperationRegistrationOptions>,
13399    ) -> Self {
13400        if let Some(did_rename) = did_rename {
13401            self.did_rename = did_rename
13402                .filters
13403                .iter()
13404                .filter_map(|filter| filter.try_into().log_err())
13405                .collect();
13406        }
13407        self
13408    }
13409    fn with_will_rename_patterns(
13410        mut self,
13411        will_rename: Option<&FileOperationRegistrationOptions>,
13412    ) -> Self {
13413        if let Some(will_rename) = will_rename {
13414            self.will_rename = will_rename
13415                .filters
13416                .iter()
13417                .filter_map(|filter| filter.try_into().log_err())
13418                .collect();
13419        }
13420        self
13421    }
13422
13423    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13424        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13425    }
13426    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13427        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13428    }
13429}
13430
13431impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13432    type Error = globset::Error;
13433    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13434        Ok(Self {
13435            kind: ops.pattern.matches.clone(),
13436            glob: GlobBuilder::new(&ops.pattern.glob)
13437                .case_insensitive(
13438                    ops.pattern
13439                        .options
13440                        .as_ref()
13441                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13442                )
13443                .build()?
13444                .compile_matcher(),
13445        })
13446    }
13447}
13448struct RenameActionPredicate {
13449    glob: GlobMatcher,
13450    kind: Option<FileOperationPatternKind>,
13451}
13452
13453impl RenameActionPredicate {
13454    // Returns true if language server should be notified
13455    fn eval(&self, path: &str, is_dir: bool) -> bool {
13456        self.kind.as_ref().is_none_or(|kind| {
13457            let expected_kind = if is_dir {
13458                FileOperationPatternKind::Folder
13459            } else {
13460                FileOperationPatternKind::File
13461            };
13462            kind == &expected_kind
13463        }) && self.glob.is_match(path)
13464    }
13465}
13466
13467#[derive(Default)]
13468struct LanguageServerWatchedPaths {
13469    worktree_paths: HashMap<WorktreeId, GlobSet>,
13470    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13471}
13472
13473#[derive(Default)]
13474struct LanguageServerWatchedPathsBuilder {
13475    worktree_paths: HashMap<WorktreeId, GlobSet>,
13476    abs_paths: HashMap<Arc<Path>, GlobSet>,
13477}
13478
13479impl LanguageServerWatchedPathsBuilder {
13480    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13481        self.worktree_paths.insert(worktree_id, glob_set);
13482    }
13483    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13484        self.abs_paths.insert(path, glob_set);
13485    }
13486    fn build(
13487        self,
13488        fs: Arc<dyn Fs>,
13489        language_server_id: LanguageServerId,
13490        cx: &mut Context<LspStore>,
13491    ) -> LanguageServerWatchedPaths {
13492        let lsp_store = cx.weak_entity();
13493
13494        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13495        let abs_paths = self
13496            .abs_paths
13497            .into_iter()
13498            .map(|(abs_path, globset)| {
13499                let task = cx.spawn({
13500                    let abs_path = abs_path.clone();
13501                    let fs = fs.clone();
13502
13503                    let lsp_store = lsp_store.clone();
13504                    async move |_, cx| {
13505                        maybe!(async move {
13506                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13507                            while let Some(update) = push_updates.0.next().await {
13508                                let action = lsp_store
13509                                    .update(cx, |this, _| {
13510                                        let Some(local) = this.as_local() else {
13511                                            return ControlFlow::Break(());
13512                                        };
13513                                        let Some(watcher) = local
13514                                            .language_server_watched_paths
13515                                            .get(&language_server_id)
13516                                        else {
13517                                            return ControlFlow::Break(());
13518                                        };
13519                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13520                                            "Watched abs path is not registered with a watcher",
13521                                        );
13522                                        let matching_entries = update
13523                                            .into_iter()
13524                                            .filter(|event| globs.is_match(&event.path))
13525                                            .collect::<Vec<_>>();
13526                                        this.lsp_notify_abs_paths_changed(
13527                                            language_server_id,
13528                                            matching_entries,
13529                                        );
13530                                        ControlFlow::Continue(())
13531                                    })
13532                                    .ok()?;
13533
13534                                if action.is_break() {
13535                                    break;
13536                                }
13537                            }
13538                            Some(())
13539                        })
13540                        .await;
13541                    }
13542                });
13543                (abs_path, (globset, task))
13544            })
13545            .collect();
13546        LanguageServerWatchedPaths {
13547            worktree_paths: self.worktree_paths,
13548            abs_paths,
13549        }
13550    }
13551}
13552
13553struct LspBufferSnapshot {
13554    version: i32,
13555    snapshot: TextBufferSnapshot,
13556}
13557
13558/// A prompt requested by LSP server.
13559#[derive(Clone, Debug)]
13560pub struct LanguageServerPromptRequest {
13561    pub level: PromptLevel,
13562    pub message: String,
13563    pub actions: Vec<MessageActionItem>,
13564    pub lsp_name: String,
13565    pub(crate) response_channel: Sender<MessageActionItem>,
13566}
13567
13568impl LanguageServerPromptRequest {
13569    pub async fn respond(self, index: usize) -> Option<()> {
13570        if let Some(response) = self.actions.into_iter().nth(index) {
13571            self.response_channel.send(response).await.ok()
13572        } else {
13573            None
13574        }
13575    }
13576}
13577impl PartialEq for LanguageServerPromptRequest {
13578    fn eq(&self, other: &Self) -> bool {
13579        self.message == other.message && self.actions == other.actions
13580    }
13581}
13582
13583#[derive(Clone, Debug, PartialEq)]
13584pub enum LanguageServerLogType {
13585    Log(MessageType),
13586    Trace { verbose_info: Option<String> },
13587    Rpc { received: bool },
13588}
13589
13590impl LanguageServerLogType {
13591    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13592        match self {
13593            Self::Log(log_type) => {
13594                use proto::log_message::LogLevel;
13595                let level = match *log_type {
13596                    MessageType::ERROR => LogLevel::Error,
13597                    MessageType::WARNING => LogLevel::Warning,
13598                    MessageType::INFO => LogLevel::Info,
13599                    MessageType::LOG => LogLevel::Log,
13600                    other => {
13601                        log::warn!("Unknown lsp log message type: {other:?}");
13602                        LogLevel::Log
13603                    }
13604                };
13605                proto::language_server_log::LogType::Log(proto::LogMessage {
13606                    level: level as i32,
13607                })
13608            }
13609            Self::Trace { verbose_info } => {
13610                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13611                    verbose_info: verbose_info.to_owned(),
13612                })
13613            }
13614            Self::Rpc { received } => {
13615                let kind = if *received {
13616                    proto::rpc_message::Kind::Received
13617                } else {
13618                    proto::rpc_message::Kind::Sent
13619                };
13620                let kind = kind as i32;
13621                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13622            }
13623        }
13624    }
13625
13626    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13627        use proto::log_message::LogLevel;
13628        use proto::rpc_message;
13629        match log_type {
13630            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13631                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13632                    LogLevel::Error => MessageType::ERROR,
13633                    LogLevel::Warning => MessageType::WARNING,
13634                    LogLevel::Info => MessageType::INFO,
13635                    LogLevel::Log => MessageType::LOG,
13636                },
13637            ),
13638            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13639                verbose_info: trace_message.verbose_info,
13640            },
13641            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13642                received: match rpc_message::Kind::from_i32(message.kind)
13643                    .unwrap_or(rpc_message::Kind::Received)
13644                {
13645                    rpc_message::Kind::Received => true,
13646                    rpc_message::Kind::Sent => false,
13647                },
13648            },
13649        }
13650    }
13651}
13652
13653pub struct WorkspaceRefreshTask {
13654    refresh_tx: mpsc::Sender<()>,
13655    progress_tx: mpsc::Sender<()>,
13656    #[allow(dead_code)]
13657    task: Task<()>,
13658}
13659
13660pub enum LanguageServerState {
13661    Starting {
13662        startup: Task<Option<Arc<LanguageServer>>>,
13663        /// List of language servers that will be added to the workspace once it's initialization completes.
13664        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13665    },
13666
13667    Running {
13668        adapter: Arc<CachedLspAdapter>,
13669        server: Arc<LanguageServer>,
13670        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13671        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13672    },
13673}
13674
13675impl LanguageServerState {
13676    fn add_workspace_folder(&self, uri: Uri) {
13677        match self {
13678            LanguageServerState::Starting {
13679                pending_workspace_folders,
13680                ..
13681            } => {
13682                pending_workspace_folders.lock().insert(uri);
13683            }
13684            LanguageServerState::Running { server, .. } => {
13685                server.add_workspace_folder(uri);
13686            }
13687        }
13688    }
13689    fn _remove_workspace_folder(&self, uri: Uri) {
13690        match self {
13691            LanguageServerState::Starting {
13692                pending_workspace_folders,
13693                ..
13694            } => {
13695                pending_workspace_folders.lock().remove(&uri);
13696            }
13697            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13698        }
13699    }
13700}
13701
13702impl std::fmt::Debug for LanguageServerState {
13703    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13704        match self {
13705            LanguageServerState::Starting { .. } => {
13706                f.debug_struct("LanguageServerState::Starting").finish()
13707            }
13708            LanguageServerState::Running { .. } => {
13709                f.debug_struct("LanguageServerState::Running").finish()
13710            }
13711        }
13712    }
13713}
13714
13715#[derive(Clone, Debug, Serialize)]
13716pub struct LanguageServerProgress {
13717    pub is_disk_based_diagnostics_progress: bool,
13718    pub is_cancellable: bool,
13719    pub title: Option<String>,
13720    pub message: Option<String>,
13721    pub percentage: Option<usize>,
13722    #[serde(skip_serializing)]
13723    pub last_update_at: Instant,
13724}
13725
13726#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13727pub struct DiagnosticSummary {
13728    pub error_count: usize,
13729    pub warning_count: usize,
13730}
13731
13732impl DiagnosticSummary {
13733    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13734        let mut this = Self {
13735            error_count: 0,
13736            warning_count: 0,
13737        };
13738
13739        for entry in diagnostics {
13740            if entry.diagnostic.is_primary {
13741                match entry.diagnostic.severity {
13742                    DiagnosticSeverity::ERROR => this.error_count += 1,
13743                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13744                    _ => {}
13745                }
13746            }
13747        }
13748
13749        this
13750    }
13751
13752    pub fn is_empty(&self) -> bool {
13753        self.error_count == 0 && self.warning_count == 0
13754    }
13755
13756    pub fn to_proto(
13757        self,
13758        language_server_id: LanguageServerId,
13759        path: &RelPath,
13760    ) -> proto::DiagnosticSummary {
13761        proto::DiagnosticSummary {
13762            path: path.to_proto(),
13763            language_server_id: language_server_id.0 as u64,
13764            error_count: self.error_count as u32,
13765            warning_count: self.warning_count as u32,
13766        }
13767    }
13768}
13769
13770#[derive(Clone, Debug)]
13771pub enum CompletionDocumentation {
13772    /// There is no documentation for this completion.
13773    Undocumented,
13774    /// A single line of documentation.
13775    SingleLine(SharedString),
13776    /// Multiple lines of plain text documentation.
13777    MultiLinePlainText(SharedString),
13778    /// Markdown documentation.
13779    MultiLineMarkdown(SharedString),
13780    /// Both single line and multiple lines of plain text documentation.
13781    SingleLineAndMultiLinePlainText {
13782        single_line: SharedString,
13783        plain_text: Option<SharedString>,
13784    },
13785}
13786
13787impl CompletionDocumentation {
13788    #[cfg(any(test, feature = "test-support"))]
13789    pub fn text(&self) -> SharedString {
13790        match self {
13791            CompletionDocumentation::Undocumented => "".into(),
13792            CompletionDocumentation::SingleLine(s) => s.clone(),
13793            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13794            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13795            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13796                single_line.clone()
13797            }
13798        }
13799    }
13800}
13801
13802impl From<lsp::Documentation> for CompletionDocumentation {
13803    fn from(docs: lsp::Documentation) -> Self {
13804        match docs {
13805            lsp::Documentation::String(text) => {
13806                if text.lines().count() <= 1 {
13807                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13808                } else {
13809                    CompletionDocumentation::MultiLinePlainText(text.into())
13810                }
13811            }
13812
13813            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13814                lsp::MarkupKind::PlainText => {
13815                    if value.lines().count() <= 1 {
13816                        CompletionDocumentation::SingleLine(value.into())
13817                    } else {
13818                        CompletionDocumentation::MultiLinePlainText(value.into())
13819                    }
13820                }
13821
13822                lsp::MarkupKind::Markdown => {
13823                    CompletionDocumentation::MultiLineMarkdown(value.into())
13824                }
13825            },
13826        }
13827    }
13828}
13829
13830pub enum ResolvedHint {
13831    Resolved(InlayHint),
13832    Resolving(Shared<Task<()>>),
13833}
13834
13835fn glob_literal_prefix(glob: &Path) -> PathBuf {
13836    glob.components()
13837        .take_while(|component| match component {
13838            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13839            _ => true,
13840        })
13841        .collect()
13842}
13843
13844pub struct SshLspAdapter {
13845    name: LanguageServerName,
13846    binary: LanguageServerBinary,
13847    initialization_options: Option<String>,
13848    code_action_kinds: Option<Vec<CodeActionKind>>,
13849}
13850
13851impl SshLspAdapter {
13852    pub fn new(
13853        name: LanguageServerName,
13854        binary: LanguageServerBinary,
13855        initialization_options: Option<String>,
13856        code_action_kinds: Option<String>,
13857    ) -> Self {
13858        Self {
13859            name,
13860            binary,
13861            initialization_options,
13862            code_action_kinds: code_action_kinds
13863                .as_ref()
13864                .and_then(|c| serde_json::from_str(c).ok()),
13865        }
13866    }
13867}
13868
13869impl LspInstaller for SshLspAdapter {
13870    type BinaryVersion = ();
13871    async fn check_if_user_installed(
13872        &self,
13873        _: &dyn LspAdapterDelegate,
13874        _: Option<Toolchain>,
13875        _: &AsyncApp,
13876    ) -> Option<LanguageServerBinary> {
13877        Some(self.binary.clone())
13878    }
13879
13880    async fn cached_server_binary(
13881        &self,
13882        _: PathBuf,
13883        _: &dyn LspAdapterDelegate,
13884    ) -> Option<LanguageServerBinary> {
13885        None
13886    }
13887
13888    async fn fetch_latest_server_version(
13889        &self,
13890        _: &dyn LspAdapterDelegate,
13891        _: bool,
13892        _: &mut AsyncApp,
13893    ) -> Result<()> {
13894        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13895    }
13896
13897    async fn fetch_server_binary(
13898        &self,
13899        _: (),
13900        _: PathBuf,
13901        _: &dyn LspAdapterDelegate,
13902    ) -> Result<LanguageServerBinary> {
13903        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13904    }
13905}
13906
13907#[async_trait(?Send)]
13908impl LspAdapter for SshLspAdapter {
13909    fn name(&self) -> LanguageServerName {
13910        self.name.clone()
13911    }
13912
13913    async fn initialization_options(
13914        self: Arc<Self>,
13915        _: &Arc<dyn LspAdapterDelegate>,
13916    ) -> Result<Option<serde_json::Value>> {
13917        let Some(options) = &self.initialization_options else {
13918            return Ok(None);
13919        };
13920        let result = serde_json::from_str(options)?;
13921        Ok(result)
13922    }
13923
13924    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13925        self.code_action_kinds.clone()
13926    }
13927}
13928
13929pub fn language_server_settings<'a>(
13930    delegate: &'a dyn LspAdapterDelegate,
13931    language: &LanguageServerName,
13932    cx: &'a App,
13933) -> Option<&'a LspSettings> {
13934    language_server_settings_for(
13935        SettingsLocation {
13936            worktree_id: delegate.worktree_id(),
13937            path: RelPath::empty(),
13938        },
13939        language,
13940        cx,
13941    )
13942}
13943
13944pub fn language_server_settings_for<'a>(
13945    location: SettingsLocation<'a>,
13946    language: &LanguageServerName,
13947    cx: &'a App,
13948) -> Option<&'a LspSettings> {
13949    ProjectSettings::get(Some(location), cx).lsp.get(language)
13950}
13951
13952pub struct LocalLspAdapterDelegate {
13953    lsp_store: WeakEntity<LspStore>,
13954    worktree: worktree::Snapshot,
13955    fs: Arc<dyn Fs>,
13956    http_client: Arc<dyn HttpClient>,
13957    language_registry: Arc<LanguageRegistry>,
13958    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13959}
13960
13961impl LocalLspAdapterDelegate {
13962    pub fn new(
13963        language_registry: Arc<LanguageRegistry>,
13964        environment: &Entity<ProjectEnvironment>,
13965        lsp_store: WeakEntity<LspStore>,
13966        worktree: &Entity<Worktree>,
13967        http_client: Arc<dyn HttpClient>,
13968        fs: Arc<dyn Fs>,
13969        cx: &mut App,
13970    ) -> Arc<Self> {
13971        let load_shell_env_task =
13972            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13973
13974        Arc::new(Self {
13975            lsp_store,
13976            worktree: worktree.read(cx).snapshot(),
13977            fs,
13978            http_client,
13979            language_registry,
13980            load_shell_env_task,
13981        })
13982    }
13983
13984    fn from_local_lsp(
13985        local: &LocalLspStore,
13986        worktree: &Entity<Worktree>,
13987        cx: &mut App,
13988    ) -> Arc<Self> {
13989        Self::new(
13990            local.languages.clone(),
13991            &local.environment,
13992            local.weak.clone(),
13993            worktree,
13994            local.http_client.clone(),
13995            local.fs.clone(),
13996            cx,
13997        )
13998    }
13999}
14000
14001#[async_trait]
14002impl LspAdapterDelegate for LocalLspAdapterDelegate {
14003    fn show_notification(&self, message: &str, cx: &mut App) {
14004        self.lsp_store
14005            .update(cx, |_, cx| {
14006                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14007            })
14008            .ok();
14009    }
14010
14011    fn http_client(&self) -> Arc<dyn HttpClient> {
14012        self.http_client.clone()
14013    }
14014
14015    fn worktree_id(&self) -> WorktreeId {
14016        self.worktree.id()
14017    }
14018
14019    fn worktree_root_path(&self) -> &Path {
14020        self.worktree.abs_path().as_ref()
14021    }
14022
14023    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14024        self.worktree.resolve_executable_path(path)
14025    }
14026
14027    async fn shell_env(&self) -> HashMap<String, String> {
14028        let task = self.load_shell_env_task.clone();
14029        task.await.unwrap_or_default()
14030    }
14031
14032    async fn npm_package_installed_version(
14033        &self,
14034        package_name: &str,
14035    ) -> Result<Option<(PathBuf, Version)>> {
14036        let local_package_directory = self.worktree_root_path();
14037        let node_modules_directory = local_package_directory.join("node_modules");
14038
14039        if let Some(version) =
14040            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14041        {
14042            return Ok(Some((node_modules_directory, version)));
14043        }
14044        let Some(npm) = self.which("npm".as_ref()).await else {
14045            log::warn!(
14046                "Failed to find npm executable for {:?}",
14047                local_package_directory
14048            );
14049            return Ok(None);
14050        };
14051
14052        let env = self.shell_env().await;
14053        let output = util::command::new_smol_command(&npm)
14054            .args(["root", "-g"])
14055            .envs(env)
14056            .current_dir(local_package_directory)
14057            .output()
14058            .await?;
14059        let global_node_modules =
14060            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14061
14062        if let Some(version) =
14063            read_package_installed_version(global_node_modules.clone(), package_name).await?
14064        {
14065            return Ok(Some((global_node_modules, version)));
14066        }
14067        return Ok(None);
14068    }
14069
14070    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14071        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14072        if self.fs.is_file(&worktree_abs_path).await {
14073            worktree_abs_path.pop();
14074        }
14075
14076        let env = self.shell_env().await;
14077
14078        let shell_path = env.get("PATH").cloned();
14079
14080        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14081    }
14082
14083    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14084        let mut working_dir = self.worktree_root_path().to_path_buf();
14085        if self.fs.is_file(&working_dir).await {
14086            working_dir.pop();
14087        }
14088        let output = util::command::new_smol_command(&command.path)
14089            .args(command.arguments)
14090            .envs(command.env.clone().unwrap_or_default())
14091            .current_dir(working_dir)
14092            .output()
14093            .await?;
14094
14095        anyhow::ensure!(
14096            output.status.success(),
14097            "{}, stdout: {:?}, stderr: {:?}",
14098            output.status,
14099            String::from_utf8_lossy(&output.stdout),
14100            String::from_utf8_lossy(&output.stderr)
14101        );
14102        Ok(())
14103    }
14104
14105    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14106        self.language_registry
14107            .update_lsp_binary_status(server_name, status);
14108    }
14109
14110    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14111        self.language_registry
14112            .all_lsp_adapters()
14113            .into_iter()
14114            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14115            .collect()
14116    }
14117
14118    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14119        let dir = self.language_registry.language_server_download_dir(name)?;
14120
14121        if !dir.exists() {
14122            smol::fs::create_dir_all(&dir)
14123                .await
14124                .context("failed to create container directory")
14125                .log_err()?;
14126        }
14127
14128        Some(dir)
14129    }
14130
14131    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14132        let entry = self
14133            .worktree
14134            .entry_for_path(path)
14135            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14136        let abs_path = self.worktree.absolutize(&entry.path);
14137        self.fs.load(&abs_path).await
14138    }
14139}
14140
14141async fn populate_labels_for_symbols(
14142    symbols: Vec<CoreSymbol>,
14143    language_registry: &Arc<LanguageRegistry>,
14144    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14145    output: &mut Vec<Symbol>,
14146) {
14147    #[allow(clippy::mutable_key_type)]
14148    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14149
14150    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14151    for symbol in symbols {
14152        let Some(file_name) = symbol.path.file_name() else {
14153            continue;
14154        };
14155        let language = language_registry
14156            .load_language_for_file_path(Path::new(file_name))
14157            .await
14158            .ok()
14159            .or_else(|| {
14160                unknown_paths.insert(file_name.into());
14161                None
14162            });
14163        symbols_by_language
14164            .entry(language)
14165            .or_default()
14166            .push(symbol);
14167    }
14168
14169    for unknown_path in unknown_paths {
14170        log::info!("no language found for symbol in file {unknown_path:?}");
14171    }
14172
14173    let mut label_params = Vec::new();
14174    for (language, mut symbols) in symbols_by_language {
14175        label_params.clear();
14176        label_params.extend(
14177            symbols
14178                .iter_mut()
14179                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14180        );
14181
14182        let mut labels = Vec::new();
14183        if let Some(language) = language {
14184            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14185                language_registry
14186                    .lsp_adapters(&language.name())
14187                    .first()
14188                    .cloned()
14189            });
14190            if let Some(lsp_adapter) = lsp_adapter {
14191                labels = lsp_adapter
14192                    .labels_for_symbols(&label_params, &language)
14193                    .await
14194                    .log_err()
14195                    .unwrap_or_default();
14196            }
14197        }
14198
14199        for ((symbol, (name, _)), label) in symbols
14200            .into_iter()
14201            .zip(label_params.drain(..))
14202            .zip(labels.into_iter().chain(iter::repeat(None)))
14203        {
14204            output.push(Symbol {
14205                language_server_name: symbol.language_server_name,
14206                source_worktree_id: symbol.source_worktree_id,
14207                source_language_server_id: symbol.source_language_server_id,
14208                path: symbol.path,
14209                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14210                name,
14211                kind: symbol.kind,
14212                range: symbol.range,
14213            });
14214        }
14215    }
14216}
14217
14218fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14219    match server.capabilities().text_document_sync.as_ref()? {
14220        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14221            // Server wants didSave but didn't specify includeText.
14222            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14223            // Server doesn't want didSave at all.
14224            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14225            // Server provided SaveOptions.
14226            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14227                Some(save_options.include_text.unwrap_or(false))
14228            }
14229        },
14230        // We do not have any save info. Kind affects didChange only.
14231        lsp::TextDocumentSyncCapability::Kind(_) => None,
14232    }
14233}
14234
14235/// Completion items are displayed in a `UniformList`.
14236/// Usually, those items are single-line strings, but in LSP responses,
14237/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14238/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14239/// 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,
14240/// breaking the completions menu presentation.
14241///
14242/// 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.
14243fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14244    let mut new_text = String::with_capacity(label.text.len());
14245    let mut offset_map = vec![0; label.text.len() + 1];
14246    let mut last_char_was_space = false;
14247    let mut new_idx = 0;
14248    let chars = label.text.char_indices().fuse();
14249    let mut newlines_removed = false;
14250
14251    for (idx, c) in chars {
14252        offset_map[idx] = new_idx;
14253
14254        match c {
14255            '\n' if last_char_was_space => {
14256                newlines_removed = true;
14257            }
14258            '\t' | ' ' if last_char_was_space => {}
14259            '\n' if !last_char_was_space => {
14260                new_text.push(' ');
14261                new_idx += 1;
14262                last_char_was_space = true;
14263                newlines_removed = true;
14264            }
14265            ' ' | '\t' => {
14266                new_text.push(' ');
14267                new_idx += 1;
14268                last_char_was_space = true;
14269            }
14270            _ => {
14271                new_text.push(c);
14272                new_idx += c.len_utf8();
14273                last_char_was_space = false;
14274            }
14275        }
14276    }
14277    offset_map[label.text.len()] = new_idx;
14278
14279    // Only modify the label if newlines were removed.
14280    if !newlines_removed {
14281        return;
14282    }
14283
14284    let last_index = new_idx;
14285    let mut run_ranges_errors = Vec::new();
14286    label.runs.retain_mut(|(range, _)| {
14287        match offset_map.get(range.start) {
14288            Some(&start) => range.start = start,
14289            None => {
14290                run_ranges_errors.push(range.clone());
14291                return false;
14292            }
14293        }
14294
14295        match offset_map.get(range.end) {
14296            Some(&end) => range.end = end,
14297            None => {
14298                run_ranges_errors.push(range.clone());
14299                range.end = last_index;
14300            }
14301        }
14302        true
14303    });
14304    if !run_ranges_errors.is_empty() {
14305        log::error!(
14306            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14307            label.text
14308        );
14309    }
14310
14311    let mut wrong_filter_range = None;
14312    if label.filter_range == (0..label.text.len()) {
14313        label.filter_range = 0..new_text.len();
14314    } else {
14315        let mut original_filter_range = Some(label.filter_range.clone());
14316        match offset_map.get(label.filter_range.start) {
14317            Some(&start) => label.filter_range.start = start,
14318            None => {
14319                wrong_filter_range = original_filter_range.take();
14320                label.filter_range.start = last_index;
14321            }
14322        }
14323
14324        match offset_map.get(label.filter_range.end) {
14325            Some(&end) => label.filter_range.end = end,
14326            None => {
14327                wrong_filter_range = original_filter_range.take();
14328                label.filter_range.end = last_index;
14329            }
14330        }
14331    }
14332    if let Some(wrong_filter_range) = wrong_filter_range {
14333        log::error!(
14334            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14335            label.text
14336        );
14337    }
14338
14339    label.text = new_text;
14340}
14341
14342#[cfg(test)]
14343mod tests {
14344    use language::HighlightId;
14345
14346    use super::*;
14347
14348    #[test]
14349    fn test_glob_literal_prefix() {
14350        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14351        assert_eq!(
14352            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14353            Path::new("node_modules")
14354        );
14355        assert_eq!(
14356            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14357            Path::new("foo")
14358        );
14359        assert_eq!(
14360            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14361            Path::new("foo/bar/baz.js")
14362        );
14363
14364        #[cfg(target_os = "windows")]
14365        {
14366            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14367            assert_eq!(
14368                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14369                Path::new("node_modules")
14370            );
14371            assert_eq!(
14372                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14373                Path::new("foo")
14374            );
14375            assert_eq!(
14376                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14377                Path::new("foo/bar/baz.js")
14378            );
14379        }
14380    }
14381
14382    #[test]
14383    fn test_multi_len_chars_normalization() {
14384        let mut label = CodeLabel::new(
14385            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14386            0..6,
14387            vec![(0..6, HighlightId(1))],
14388        );
14389        ensure_uniform_list_compatible_label(&mut label);
14390        assert_eq!(
14391            label,
14392            CodeLabel::new(
14393                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14394                0..6,
14395                vec![(0..6, HighlightId(1))],
14396            )
14397        );
14398    }
14399
14400    #[test]
14401    fn test_trailing_newline_in_completion_documentation() {
14402        let doc = lsp::Documentation::String(
14403            "Inappropriate argument value (of correct type).\n".to_string(),
14404        );
14405        let completion_doc: CompletionDocumentation = doc.into();
14406        assert!(
14407            matches!(completion_doc, CompletionDocumentation::SingleLine(s) if s == "Inappropriate argument value (of correct type).")
14408        );
14409
14410        let doc = lsp::Documentation::String("  some value  \n".to_string());
14411        let completion_doc: CompletionDocumentation = doc.into();
14412        assert!(matches!(
14413            completion_doc,
14414            CompletionDocumentation::SingleLine(s) if s == "some value"
14415        ));
14416    }
14417}