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    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   42    yarn::YarnPathStore,
   43};
   44use anyhow::{Context as _, Result, anyhow};
   45use async_trait::async_trait;
   46use client::{TypedEnvelope, proto};
   47use clock::Global;
   48use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   49use futures::{
   50    AsyncWriteExt, Future, FutureExt, StreamExt,
   51    future::{Either, Shared, join_all, pending, select},
   52    select, select_biased,
   53    stream::FuturesUnordered,
   54};
   55use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   56use gpui::{
   57    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   58    WeakEntity,
   59};
   60use http_client::HttpClient;
   61use itertools::Itertools as _;
   62use language::{
   63    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   64    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   65    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   66    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   67    Transaction, Unclipped,
   68    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   69    point_to_lsp,
   70    proto::{
   71        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   72        serialize_lsp_edit, serialize_version,
   73    },
   74    range_from_lsp, range_to_lsp,
   75    row_chunk::RowChunk,
   76};
   77use lsp::{
   78    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   79    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   80    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   81    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   82    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   83    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   84    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   85    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   86};
   87use node_runtime::read_package_installed_version;
   88use parking_lot::Mutex;
   89use postage::{mpsc, sink::Sink, stream::Stream, watch};
   90use rand::prelude::*;
   91use rpc::{
   92    AnyProtoClient, ErrorCode, ErrorExt as _,
   93    proto::{LspRequestId, LspRequestMessage as _},
   94};
   95use serde::Serialize;
   96use serde_json::Value;
   97use settings::{Settings, SettingsLocation, SettingsStore};
   98use sha2::{Digest, Sha256};
   99use smol::channel::Sender;
  100use snippet::Snippet;
  101use std::{
  102    any::TypeId,
  103    borrow::Cow,
  104    cell::RefCell,
  105    cmp::{Ordering, Reverse},
  106    convert::TryInto,
  107    ffi::OsStr,
  108    future::ready,
  109    iter, mem,
  110    ops::{ControlFlow, Range},
  111    path::{self, Path, PathBuf},
  112    pin::pin,
  113    rc::Rc,
  114    sync::{
  115        Arc,
  116        atomic::{self, AtomicUsize},
  117    },
  118    time::{Duration, Instant},
  119    vec,
  120};
  121use sum_tree::Dimensions;
  122use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  123
  124use util::{
  125    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  126    paths::{PathStyle, SanitizedPath},
  127    post_inc,
  128    rel_path::RelPath,
  129};
  130
  131pub use fs::*;
  132pub use language::Location;
  133pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  134#[cfg(any(test, feature = "test-support"))]
  135pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  136pub use worktree::{
  137    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  138    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  139};
  140
  141const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  142pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  143const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  144const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  145
  146#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  147pub enum ProgressToken {
  148    Number(i32),
  149    String(SharedString),
  150}
  151
  152impl std::fmt::Display for ProgressToken {
  153    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  154        match self {
  155            Self::Number(number) => write!(f, "{number}"),
  156            Self::String(string) => write!(f, "{string}"),
  157        }
  158    }
  159}
  160
  161impl ProgressToken {
  162    fn from_lsp(value: lsp::NumberOrString) -> Self {
  163        match value {
  164            lsp::NumberOrString::Number(number) => Self::Number(number),
  165            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  166        }
  167    }
  168
  169    fn to_lsp(&self) -> lsp::NumberOrString {
  170        match self {
  171            Self::Number(number) => lsp::NumberOrString::Number(*number),
  172            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  173        }
  174    }
  175
  176    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  177        Some(match value.value? {
  178            proto::progress_token::Value::Number(number) => Self::Number(number),
  179            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  180        })
  181    }
  182
  183    fn to_proto(&self) -> proto::ProgressToken {
  184        proto::ProgressToken {
  185            value: Some(match self {
  186                Self::Number(number) => proto::progress_token::Value::Number(*number),
  187                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  188            }),
  189        }
  190    }
  191}
  192
  193#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  194pub enum FormatTrigger {
  195    Save,
  196    Manual,
  197}
  198
  199pub enum LspFormatTarget {
  200    Buffers,
  201    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  202}
  203
  204pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  205
  206impl FormatTrigger {
  207    fn from_proto(value: i32) -> FormatTrigger {
  208        match value {
  209            0 => FormatTrigger::Save,
  210            1 => FormatTrigger::Manual,
  211            _ => FormatTrigger::Save,
  212        }
  213    }
  214}
  215
  216#[derive(Clone)]
  217struct UnifiedLanguageServer {
  218    id: LanguageServerId,
  219    project_roots: HashSet<Arc<RelPath>>,
  220}
  221
  222#[derive(Clone, Hash, PartialEq, Eq)]
  223struct LanguageServerSeed {
  224    worktree_id: WorktreeId,
  225    name: LanguageServerName,
  226    toolchain: Option<Toolchain>,
  227    settings: Arc<LspSettings>,
  228}
  229
  230#[derive(Debug)]
  231pub struct DocumentDiagnosticsUpdate<'a, D> {
  232    pub diagnostics: D,
  233    pub result_id: Option<SharedString>,
  234    pub registration_id: Option<SharedString>,
  235    pub server_id: LanguageServerId,
  236    pub disk_based_sources: Cow<'a, [String]>,
  237}
  238
  239pub struct DocumentDiagnostics {
  240    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  241    document_abs_path: PathBuf,
  242    version: Option<i32>,
  243}
  244
  245#[derive(Default, Debug)]
  246struct DynamicRegistrations {
  247    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  248    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  249}
  250
  251pub struct LocalLspStore {
  252    weak: WeakEntity<LspStore>,
  253    worktree_store: Entity<WorktreeStore>,
  254    toolchain_store: Entity<LocalToolchainStore>,
  255    http_client: Arc<dyn HttpClient>,
  256    environment: Entity<ProjectEnvironment>,
  257    fs: Arc<dyn Fs>,
  258    languages: Arc<LanguageRegistry>,
  259    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  260    yarn: Entity<YarnPathStore>,
  261    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  262    buffers_being_formatted: HashSet<BufferId>,
  263    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  264    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  265    watched_manifest_filenames: HashSet<ManifestName>,
  266    language_server_paths_watched_for_rename:
  267        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  268    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  269    supplementary_language_servers:
  270        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  271    prettier_store: Entity<PrettierStore>,
  272    next_diagnostic_group_id: usize,
  273    diagnostics: HashMap<
  274        WorktreeId,
  275        HashMap<
  276            Arc<RelPath>,
  277            Vec<(
  278                LanguageServerId,
  279                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  280            )>,
  281        >,
  282    >,
  283    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  284    _subscription: gpui::Subscription,
  285    lsp_tree: LanguageServerTree,
  286    registered_buffers: HashMap<BufferId, usize>,
  287    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  288    buffer_pull_diagnostics_result_ids: HashMap<
  289        LanguageServerId,
  290        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  291    >,
  292    workspace_pull_diagnostics_result_ids: HashMap<
  293        LanguageServerId,
  294        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  295    >,
  296}
  297
  298impl LocalLspStore {
  299    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  300    pub fn running_language_server_for_id(
  301        &self,
  302        id: LanguageServerId,
  303    ) -> Option<&Arc<LanguageServer>> {
  304        let language_server_state = self.language_servers.get(&id)?;
  305
  306        match language_server_state {
  307            LanguageServerState::Running { server, .. } => Some(server),
  308            LanguageServerState::Starting { .. } => None,
  309        }
  310    }
  311
  312    fn get_or_insert_language_server(
  313        &mut self,
  314        worktree_handle: &Entity<Worktree>,
  315        delegate: Arc<LocalLspAdapterDelegate>,
  316        disposition: &Arc<LaunchDisposition>,
  317        language_name: &LanguageName,
  318        cx: &mut App,
  319    ) -> LanguageServerId {
  320        let key = LanguageServerSeed {
  321            worktree_id: worktree_handle.read(cx).id(),
  322            name: disposition.server_name.clone(),
  323            settings: disposition.settings.clone(),
  324            toolchain: disposition.toolchain.clone(),
  325        };
  326        if let Some(state) = self.language_server_ids.get_mut(&key) {
  327            state.project_roots.insert(disposition.path.path.clone());
  328            state.id
  329        } else {
  330            let adapter = self
  331                .languages
  332                .lsp_adapters(language_name)
  333                .into_iter()
  334                .find(|adapter| adapter.name() == disposition.server_name)
  335                .expect("To find LSP adapter");
  336            let new_language_server_id = self.start_language_server(
  337                worktree_handle,
  338                delegate,
  339                adapter,
  340                disposition.settings.clone(),
  341                key.clone(),
  342                cx,
  343            );
  344            if let Some(state) = self.language_server_ids.get_mut(&key) {
  345                state.project_roots.insert(disposition.path.path.clone());
  346            } else {
  347                debug_assert!(
  348                    false,
  349                    "Expected `start_language_server` to ensure that `key` exists in a map"
  350                );
  351            }
  352            new_language_server_id
  353        }
  354    }
  355
  356    fn start_language_server(
  357        &mut self,
  358        worktree_handle: &Entity<Worktree>,
  359        delegate: Arc<LocalLspAdapterDelegate>,
  360        adapter: Arc<CachedLspAdapter>,
  361        settings: Arc<LspSettings>,
  362        key: LanguageServerSeed,
  363        cx: &mut App,
  364    ) -> LanguageServerId {
  365        let worktree = worktree_handle.read(cx);
  366
  367        let root_path = worktree.abs_path();
  368        let toolchain = key.toolchain.clone();
  369        let override_options = settings.initialization_options.clone();
  370
  371        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  372
  373        let server_id = self.languages.next_language_server_id();
  374        log::trace!(
  375            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  376            adapter.name.0
  377        );
  378
  379        let binary = self.get_language_server_binary(
  380            adapter.clone(),
  381            settings,
  382            toolchain.clone(),
  383            delegate.clone(),
  384            true,
  385            cx,
  386        );
  387        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  388
  389        let pending_server = cx.spawn({
  390            let adapter = adapter.clone();
  391            let server_name = adapter.name.clone();
  392            let stderr_capture = stderr_capture.clone();
  393            #[cfg(any(test, feature = "test-support"))]
  394            let lsp_store = self.weak.clone();
  395            let pending_workspace_folders = pending_workspace_folders.clone();
  396            async move |cx| {
  397                let binary = binary.await?;
  398                #[cfg(any(test, feature = "test-support"))]
  399                if let Some(server) = lsp_store
  400                    .update(&mut cx.clone(), |this, cx| {
  401                        this.languages.create_fake_language_server(
  402                            server_id,
  403                            &server_name,
  404                            binary.clone(),
  405                            &mut cx.to_async(),
  406                        )
  407                    })
  408                    .ok()
  409                    .flatten()
  410                {
  411                    return Ok(server);
  412                }
  413
  414                let code_action_kinds = adapter.code_action_kinds();
  415                lsp::LanguageServer::new(
  416                    stderr_capture,
  417                    server_id,
  418                    server_name,
  419                    binary,
  420                    &root_path,
  421                    code_action_kinds,
  422                    Some(pending_workspace_folders),
  423                    cx,
  424                )
  425            }
  426        });
  427
  428        let startup = {
  429            let server_name = adapter.name.0.clone();
  430            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  431            let key = key.clone();
  432            let adapter = adapter.clone();
  433            let lsp_store = self.weak.clone();
  434            let pending_workspace_folders = pending_workspace_folders.clone();
  435
  436            let pull_diagnostics = ProjectSettings::get_global(cx)
  437                .diagnostics
  438                .lsp_pull_diagnostics
  439                .enabled;
  440            cx.spawn(async move |cx| {
  441                let result = async {
  442                    let language_server = pending_server.await?;
  443
  444                    let workspace_config = Self::workspace_configuration_for_adapter(
  445                        adapter.adapter.clone(),
  446                        &delegate,
  447                        toolchain,
  448                        None,
  449                        cx,
  450                    )
  451                    .await?;
  452
  453                    let mut initialization_options = Self::initialization_options_for_adapter(
  454                        adapter.adapter.clone(),
  455                        &delegate,
  456                    )
  457                    .await?;
  458
  459                    match (&mut initialization_options, override_options) {
  460                        (Some(initialization_options), Some(override_options)) => {
  461                            merge_json_value_into(override_options, initialization_options);
  462                        }
  463                        (None, override_options) => initialization_options = override_options,
  464                        _ => {}
  465                    }
  466
  467                    let initialization_params = cx.update(|cx| {
  468                        let mut params =
  469                            language_server.default_initialize_params(pull_diagnostics, cx);
  470                        params.initialization_options = initialization_options;
  471                        adapter.adapter.prepare_initialize_params(params, cx)
  472                    })??;
  473
  474                    Self::setup_lsp_messages(
  475                        lsp_store.clone(),
  476                        &language_server,
  477                        delegate.clone(),
  478                        adapter.clone(),
  479                    );
  480
  481                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  482                        settings: workspace_config,
  483                    };
  484                    let language_server = cx
  485                        .update(|cx| {
  486                            language_server.initialize(
  487                                initialization_params,
  488                                Arc::new(did_change_configuration_params.clone()),
  489                                cx,
  490                            )
  491                        })?
  492                        .await
  493                        .inspect_err(|_| {
  494                            if let Some(lsp_store) = lsp_store.upgrade() {
  495                                lsp_store
  496                                    .update(cx, |lsp_store, cx| {
  497                                        lsp_store.cleanup_lsp_data(server_id);
  498                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  499                                    })
  500                                    .ok();
  501                            }
  502                        })?;
  503
  504                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  505                        did_change_configuration_params,
  506                    )?;
  507
  508                    anyhow::Ok(language_server)
  509                }
  510                .await;
  511
  512                match result {
  513                    Ok(server) => {
  514                        lsp_store
  515                            .update(cx, |lsp_store, cx| {
  516                                lsp_store.insert_newly_running_language_server(
  517                                    adapter,
  518                                    server.clone(),
  519                                    server_id,
  520                                    key,
  521                                    pending_workspace_folders,
  522                                    cx,
  523                                );
  524                            })
  525                            .ok();
  526                        stderr_capture.lock().take();
  527                        Some(server)
  528                    }
  529
  530                    Err(err) => {
  531                        let log = stderr_capture.lock().take().unwrap_or_default();
  532                        delegate.update_status(
  533                            adapter.name(),
  534                            BinaryStatus::Failed {
  535                                error: if log.is_empty() {
  536                                    format!("{err:#}")
  537                                } else {
  538                                    format!("{err:#}\n-- stderr --\n{log}")
  539                                },
  540                            },
  541                        );
  542                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  543                        if !log.is_empty() {
  544                            log::error!("server stderr: {log}");
  545                        }
  546                        None
  547                    }
  548                }
  549            })
  550        };
  551        let state = LanguageServerState::Starting {
  552            startup,
  553            pending_workspace_folders,
  554        };
  555
  556        self.languages
  557            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  558
  559        self.language_servers.insert(server_id, state);
  560        self.language_server_ids
  561            .entry(key)
  562            .or_insert(UnifiedLanguageServer {
  563                id: server_id,
  564                project_roots: Default::default(),
  565            });
  566        server_id
  567    }
  568
  569    fn get_language_server_binary(
  570        &self,
  571        adapter: Arc<CachedLspAdapter>,
  572        settings: Arc<LspSettings>,
  573        toolchain: Option<Toolchain>,
  574        delegate: Arc<dyn LspAdapterDelegate>,
  575        allow_binary_download: bool,
  576        cx: &mut App,
  577    ) -> Task<Result<LanguageServerBinary>> {
  578        if let Some(settings) = &settings.binary
  579            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  580        {
  581            let settings = settings.clone();
  582
  583            return cx.background_spawn(async move {
  584                let mut env = delegate.shell_env().await;
  585                env.extend(settings.env.unwrap_or_default());
  586
  587                Ok(LanguageServerBinary {
  588                    path: delegate.resolve_executable_path(path),
  589                    env: Some(env),
  590                    arguments: settings
  591                        .arguments
  592                        .unwrap_or_default()
  593                        .iter()
  594                        .map(Into::into)
  595                        .collect(),
  596                })
  597            });
  598        }
  599        let lsp_binary_options = LanguageServerBinaryOptions {
  600            allow_path_lookup: !settings
  601                .binary
  602                .as_ref()
  603                .and_then(|b| b.ignore_system_version)
  604                .unwrap_or_default(),
  605            allow_binary_download,
  606            pre_release: settings
  607                .fetch
  608                .as_ref()
  609                .and_then(|f| f.pre_release)
  610                .unwrap_or(false),
  611        };
  612
  613        cx.spawn(async move |cx| {
  614            let (existing_binary, maybe_download_binary) = adapter
  615                .clone()
  616                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  617                .await
  618                .await;
  619
  620            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  621
  622            let mut binary = match (existing_binary, maybe_download_binary) {
  623                (binary, None) => binary?,
  624                (Err(_), Some(downloader)) => downloader.await?,
  625                (Ok(existing_binary), Some(downloader)) => {
  626                    let mut download_timeout = cx
  627                        .background_executor()
  628                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  629                        .fuse();
  630                    let mut downloader = downloader.fuse();
  631                    futures::select! {
  632                        _ = download_timeout => {
  633                            // Return existing binary and kick the existing work to the background.
  634                            cx.spawn(async move |_| downloader.await).detach();
  635                            Ok(existing_binary)
  636                        },
  637                        downloaded_or_existing_binary = downloader => {
  638                            // If download fails, this results in the existing binary.
  639                            downloaded_or_existing_binary
  640                        }
  641                    }?
  642                }
  643            };
  644            let mut shell_env = delegate.shell_env().await;
  645
  646            shell_env.extend(binary.env.unwrap_or_default());
  647
  648            if let Some(settings) = settings.binary.as_ref() {
  649                if let Some(arguments) = &settings.arguments {
  650                    binary.arguments = arguments.iter().map(Into::into).collect();
  651                }
  652                if let Some(env) = &settings.env {
  653                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  654                }
  655            }
  656
  657            binary.env = Some(shell_env);
  658            Ok(binary)
  659        })
  660    }
  661
  662    fn setup_lsp_messages(
  663        lsp_store: WeakEntity<LspStore>,
  664        language_server: &LanguageServer,
  665        delegate: Arc<dyn LspAdapterDelegate>,
  666        adapter: Arc<CachedLspAdapter>,
  667    ) {
  668        let name = language_server.name();
  669        let server_id = language_server.server_id();
  670        language_server
  671            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  672                let adapter = adapter.clone();
  673                let this = lsp_store.clone();
  674                move |mut params, cx| {
  675                    let adapter = adapter.clone();
  676                    if let Some(this) = this.upgrade() {
  677                        this.update(cx, |this, cx| {
  678                            {
  679                                let buffer = params
  680                                    .uri
  681                                    .to_file_path()
  682                                    .map(|file_path| this.get_buffer(&file_path, cx))
  683                                    .ok()
  684                                    .flatten();
  685                                adapter.process_diagnostics(&mut params, server_id, buffer);
  686                            }
  687
  688                            this.merge_lsp_diagnostics(
  689                                DiagnosticSourceKind::Pushed,
  690                                vec![DocumentDiagnosticsUpdate {
  691                                    server_id,
  692                                    diagnostics: params,
  693                                    result_id: None,
  694                                    disk_based_sources: Cow::Borrowed(
  695                                        &adapter.disk_based_diagnostic_sources,
  696                                    ),
  697                                    registration_id: None,
  698                                }],
  699                                |_, diagnostic, cx| match diagnostic.source_kind {
  700                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  701                                        adapter.retain_old_diagnostic(diagnostic, cx)
  702                                    }
  703                                    DiagnosticSourceKind::Pulled => true,
  704                                },
  705                                cx,
  706                            )
  707                            .log_err();
  708                        })
  709                        .ok();
  710                    }
  711                }
  712            })
  713            .detach();
  714        language_server
  715            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  716                let adapter = adapter.adapter.clone();
  717                let delegate = delegate.clone();
  718                let this = lsp_store.clone();
  719                move |params, cx| {
  720                    let adapter = adapter.clone();
  721                    let delegate = delegate.clone();
  722                    let this = this.clone();
  723                    let mut cx = cx.clone();
  724                    async move {
  725                        let toolchain_for_id = this
  726                            .update(&mut cx, |this, _| {
  727                                this.as_local()?.language_server_ids.iter().find_map(
  728                                    |(seed, value)| {
  729                                        (value.id == server_id).then(|| seed.toolchain.clone())
  730                                    },
  731                                )
  732                            })?
  733                            .context("Expected the LSP store to be in a local mode")?;
  734
  735                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  736                        for item in &params.items {
  737                            let scope_uri = item.scope_uri.clone();
  738                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  739                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  740                            else {
  741                                // We've already queried workspace configuration of this URI.
  742                                continue;
  743                            };
  744                            let workspace_config = Self::workspace_configuration_for_adapter(
  745                                adapter.clone(),
  746                                &delegate,
  747                                toolchain_for_id.clone(),
  748                                scope_uri,
  749                                &mut cx,
  750                            )
  751                            .await?;
  752                            new_scope_uri.insert(workspace_config);
  753                        }
  754
  755                        Ok(params
  756                            .items
  757                            .into_iter()
  758                            .filter_map(|item| {
  759                                let workspace_config =
  760                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  761                                if let Some(section) = &item.section {
  762                                    Some(
  763                                        workspace_config
  764                                            .get(section)
  765                                            .cloned()
  766                                            .unwrap_or(serde_json::Value::Null),
  767                                    )
  768                                } else {
  769                                    Some(workspace_config.clone())
  770                                }
  771                            })
  772                            .collect())
  773                    }
  774                }
  775            })
  776            .detach();
  777
  778        language_server
  779            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  780                let this = lsp_store.clone();
  781                move |_, cx| {
  782                    let this = this.clone();
  783                    let cx = cx.clone();
  784                    async move {
  785                        let Some(server) =
  786                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  787                        else {
  788                            return Ok(None);
  789                        };
  790                        let root = server.workspace_folders();
  791                        Ok(Some(
  792                            root.into_iter()
  793                                .map(|uri| WorkspaceFolder {
  794                                    uri,
  795                                    name: Default::default(),
  796                                })
  797                                .collect(),
  798                        ))
  799                    }
  800                }
  801            })
  802            .detach();
  803        // Even though we don't have handling for these requests, respond to them to
  804        // avoid stalling any language server like `gopls` which waits for a response
  805        // to these requests when initializing.
  806        language_server
  807            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  808                let this = lsp_store.clone();
  809                move |params, cx| {
  810                    let this = this.clone();
  811                    let mut cx = cx.clone();
  812                    async move {
  813                        this.update(&mut cx, |this, _| {
  814                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  815                            {
  816                                status
  817                                    .progress_tokens
  818                                    .insert(ProgressToken::from_lsp(params.token));
  819                            }
  820                        })?;
  821
  822                        Ok(())
  823                    }
  824                }
  825            })
  826            .detach();
  827
  828        language_server
  829            .on_request::<lsp::request::RegisterCapability, _, _>({
  830                let lsp_store = lsp_store.clone();
  831                move |params, cx| {
  832                    let lsp_store = lsp_store.clone();
  833                    let mut cx = cx.clone();
  834                    async move {
  835                        lsp_store
  836                            .update(&mut cx, |lsp_store, cx| {
  837                                if lsp_store.as_local().is_some() {
  838                                    match lsp_store
  839                                        .register_server_capabilities(server_id, params, cx)
  840                                    {
  841                                        Ok(()) => {}
  842                                        Err(e) => {
  843                                            log::error!(
  844                                                "Failed to register server capabilities: {e:#}"
  845                                            );
  846                                        }
  847                                    };
  848                                }
  849                            })
  850                            .ok();
  851                        Ok(())
  852                    }
  853                }
  854            })
  855            .detach();
  856
  857        language_server
  858            .on_request::<lsp::request::UnregisterCapability, _, _>({
  859                let lsp_store = lsp_store.clone();
  860                move |params, cx| {
  861                    let lsp_store = lsp_store.clone();
  862                    let mut cx = cx.clone();
  863                    async move {
  864                        lsp_store
  865                            .update(&mut cx, |lsp_store, cx| {
  866                                if lsp_store.as_local().is_some() {
  867                                    match lsp_store
  868                                        .unregister_server_capabilities(server_id, params, cx)
  869                                    {
  870                                        Ok(()) => {}
  871                                        Err(e) => {
  872                                            log::error!(
  873                                                "Failed to unregister server capabilities: {e:#}"
  874                                            );
  875                                        }
  876                                    }
  877                                }
  878                            })
  879                            .ok();
  880                        Ok(())
  881                    }
  882                }
  883            })
  884            .detach();
  885
  886        language_server
  887            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  888                let this = lsp_store.clone();
  889                move |params, cx| {
  890                    let mut cx = cx.clone();
  891                    let this = this.clone();
  892                    async move {
  893                        LocalLspStore::on_lsp_workspace_edit(
  894                            this.clone(),
  895                            params,
  896                            server_id,
  897                            &mut cx,
  898                        )
  899                        .await
  900                    }
  901                }
  902            })
  903            .detach();
  904
  905        language_server
  906            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  907                let lsp_store = lsp_store.clone();
  908                let request_id = Arc::new(AtomicUsize::new(0));
  909                move |(), cx| {
  910                    let lsp_store = lsp_store.clone();
  911                    let request_id = request_id.clone();
  912                    let mut cx = cx.clone();
  913                    async move {
  914                        lsp_store
  915                            .update(&mut cx, |lsp_store, cx| {
  916                                let request_id =
  917                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  918                                cx.emit(LspStoreEvent::RefreshInlayHints {
  919                                    server_id,
  920                                    request_id,
  921                                });
  922                                lsp_store
  923                                    .downstream_client
  924                                    .as_ref()
  925                                    .map(|(client, project_id)| {
  926                                        client.send(proto::RefreshInlayHints {
  927                                            project_id: *project_id,
  928                                            server_id: server_id.to_proto(),
  929                                            request_id: request_id.map(|id| id as u64),
  930                                        })
  931                                    })
  932                            })?
  933                            .transpose()?;
  934                        Ok(())
  935                    }
  936                }
  937            })
  938            .detach();
  939
  940        language_server
  941            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  942                let this = lsp_store.clone();
  943                move |(), cx| {
  944                    let this = this.clone();
  945                    let mut cx = cx.clone();
  946                    async move {
  947                        this.update(&mut cx, |this, cx| {
  948                            cx.emit(LspStoreEvent::RefreshCodeLens);
  949                            this.downstream_client.as_ref().map(|(client, project_id)| {
  950                                client.send(proto::RefreshCodeLens {
  951                                    project_id: *project_id,
  952                                })
  953                            })
  954                        })?
  955                        .transpose()?;
  956                        Ok(())
  957                    }
  958                }
  959            })
  960            .detach();
  961
  962        language_server
  963            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  964                let this = lsp_store.clone();
  965                move |(), cx| {
  966                    let this = this.clone();
  967                    let mut cx = cx.clone();
  968                    async move {
  969                        this.update(&mut cx, |lsp_store, _| {
  970                            lsp_store.pull_workspace_diagnostics(server_id);
  971                            lsp_store
  972                                .downstream_client
  973                                .as_ref()
  974                                .map(|(client, project_id)| {
  975                                    client.send(proto::PullWorkspaceDiagnostics {
  976                                        project_id: *project_id,
  977                                        server_id: server_id.to_proto(),
  978                                    })
  979                                })
  980                        })?
  981                        .transpose()?;
  982                        Ok(())
  983                    }
  984                }
  985            })
  986            .detach();
  987
  988        language_server
  989            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  990                let this = lsp_store.clone();
  991                let name = name.to_string();
  992                move |params, cx| {
  993                    let this = this.clone();
  994                    let name = name.to_string();
  995                    let mut cx = cx.clone();
  996                    async move {
  997                        let actions = params.actions.unwrap_or_default();
  998                        let (tx, rx) = smol::channel::bounded(1);
  999                        let request = LanguageServerPromptRequest {
 1000                            level: match params.typ {
 1001                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1002                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1003                                _ => PromptLevel::Info,
 1004                            },
 1005                            message: params.message,
 1006                            actions,
 1007                            response_channel: tx,
 1008                            lsp_name: name.clone(),
 1009                        };
 1010
 1011                        let did_update = this
 1012                            .update(&mut cx, |_, cx| {
 1013                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1014                            })
 1015                            .is_ok();
 1016                        if did_update {
 1017                            let response = rx.recv().await.ok();
 1018                            Ok(response)
 1019                        } else {
 1020                            Ok(None)
 1021                        }
 1022                    }
 1023                }
 1024            })
 1025            .detach();
 1026        language_server
 1027            .on_notification::<lsp::notification::ShowMessage, _>({
 1028                let this = lsp_store.clone();
 1029                let name = name.to_string();
 1030                move |params, cx| {
 1031                    let this = this.clone();
 1032                    let name = name.to_string();
 1033                    let mut cx = cx.clone();
 1034
 1035                    let (tx, _) = smol::channel::bounded(1);
 1036                    let request = LanguageServerPromptRequest {
 1037                        level: match params.typ {
 1038                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1039                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1040                            _ => PromptLevel::Info,
 1041                        },
 1042                        message: params.message,
 1043                        actions: vec![],
 1044                        response_channel: tx,
 1045                        lsp_name: name,
 1046                    };
 1047
 1048                    let _ = this.update(&mut cx, |_, cx| {
 1049                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1050                    });
 1051                }
 1052            })
 1053            .detach();
 1054
 1055        let disk_based_diagnostics_progress_token =
 1056            adapter.disk_based_diagnostics_progress_token.clone();
 1057
 1058        language_server
 1059            .on_notification::<lsp::notification::Progress, _>({
 1060                let this = lsp_store.clone();
 1061                move |params, cx| {
 1062                    if let Some(this) = this.upgrade() {
 1063                        this.update(cx, |this, cx| {
 1064                            this.on_lsp_progress(
 1065                                params,
 1066                                server_id,
 1067                                disk_based_diagnostics_progress_token.clone(),
 1068                                cx,
 1069                            );
 1070                        })
 1071                        .ok();
 1072                    }
 1073                }
 1074            })
 1075            .detach();
 1076
 1077        language_server
 1078            .on_notification::<lsp::notification::LogMessage, _>({
 1079                let this = lsp_store.clone();
 1080                move |params, cx| {
 1081                    if let Some(this) = this.upgrade() {
 1082                        this.update(cx, |_, cx| {
 1083                            cx.emit(LspStoreEvent::LanguageServerLog(
 1084                                server_id,
 1085                                LanguageServerLogType::Log(params.typ),
 1086                                params.message,
 1087                            ));
 1088                        })
 1089                        .ok();
 1090                    }
 1091                }
 1092            })
 1093            .detach();
 1094
 1095        language_server
 1096            .on_notification::<lsp::notification::LogTrace, _>({
 1097                let this = lsp_store.clone();
 1098                move |params, cx| {
 1099                    let mut cx = cx.clone();
 1100                    if let Some(this) = this.upgrade() {
 1101                        this.update(&mut cx, |_, cx| {
 1102                            cx.emit(LspStoreEvent::LanguageServerLog(
 1103                                server_id,
 1104                                LanguageServerLogType::Trace {
 1105                                    verbose_info: params.verbose,
 1106                                },
 1107                                params.message,
 1108                            ));
 1109                        })
 1110                        .ok();
 1111                    }
 1112                }
 1113            })
 1114            .detach();
 1115
 1116        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1117        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1118        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1119        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1120    }
 1121
 1122    fn shutdown_language_servers_on_quit(
 1123        &mut self,
 1124        _: &mut Context<LspStore>,
 1125    ) -> impl Future<Output = ()> + use<> {
 1126        let shutdown_futures = self
 1127            .language_servers
 1128            .drain()
 1129            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1130            .collect::<Vec<_>>();
 1131
 1132        async move {
 1133            join_all(shutdown_futures).await;
 1134        }
 1135    }
 1136
 1137    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1138        match server_state {
 1139            LanguageServerState::Running { server, .. } => {
 1140                if let Some(shutdown) = server.shutdown() {
 1141                    shutdown.await;
 1142                }
 1143            }
 1144            LanguageServerState::Starting { startup, .. } => {
 1145                if let Some(server) = startup.await
 1146                    && let Some(shutdown) = server.shutdown()
 1147                {
 1148                    shutdown.await;
 1149                }
 1150            }
 1151        }
 1152        Ok(())
 1153    }
 1154
 1155    fn language_servers_for_worktree(
 1156        &self,
 1157        worktree_id: WorktreeId,
 1158    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1159        self.language_server_ids
 1160            .iter()
 1161            .filter_map(move |(seed, state)| {
 1162                if seed.worktree_id != worktree_id {
 1163                    return None;
 1164                }
 1165
 1166                if let Some(LanguageServerState::Running { server, .. }) =
 1167                    self.language_servers.get(&state.id)
 1168                {
 1169                    Some(server)
 1170                } else {
 1171                    None
 1172                }
 1173            })
 1174    }
 1175
 1176    fn language_server_ids_for_project_path(
 1177        &self,
 1178        project_path: ProjectPath,
 1179        language: &Language,
 1180        cx: &mut App,
 1181    ) -> Vec<LanguageServerId> {
 1182        let Some(worktree) = self
 1183            .worktree_store
 1184            .read(cx)
 1185            .worktree_for_id(project_path.worktree_id, cx)
 1186        else {
 1187            return Vec::new();
 1188        };
 1189        let delegate: Arc<dyn ManifestDelegate> =
 1190            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1191
 1192        self.lsp_tree
 1193            .get(
 1194                project_path,
 1195                language.name(),
 1196                language.manifest(),
 1197                &delegate,
 1198                cx,
 1199            )
 1200            .collect::<Vec<_>>()
 1201    }
 1202
 1203    fn language_server_ids_for_buffer(
 1204        &self,
 1205        buffer: &Buffer,
 1206        cx: &mut App,
 1207    ) -> Vec<LanguageServerId> {
 1208        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1209            let worktree_id = file.worktree_id(cx);
 1210
 1211            let path: Arc<RelPath> = file
 1212                .path()
 1213                .parent()
 1214                .map(Arc::from)
 1215                .unwrap_or_else(|| file.path().clone());
 1216            let worktree_path = ProjectPath { worktree_id, path };
 1217            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1218        } else {
 1219            Vec::new()
 1220        }
 1221    }
 1222
 1223    fn language_servers_for_buffer<'a>(
 1224        &'a self,
 1225        buffer: &'a Buffer,
 1226        cx: &'a mut App,
 1227    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1228        self.language_server_ids_for_buffer(buffer, cx)
 1229            .into_iter()
 1230            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1231                LanguageServerState::Running {
 1232                    adapter, server, ..
 1233                } => Some((adapter, server)),
 1234                _ => None,
 1235            })
 1236    }
 1237
 1238    async fn execute_code_action_kind_locally(
 1239        lsp_store: WeakEntity<LspStore>,
 1240        mut buffers: Vec<Entity<Buffer>>,
 1241        kind: CodeActionKind,
 1242        push_to_history: bool,
 1243        cx: &mut AsyncApp,
 1244    ) -> anyhow::Result<ProjectTransaction> {
 1245        // Do not allow multiple concurrent code actions requests for the
 1246        // same buffer.
 1247        lsp_store.update(cx, |this, cx| {
 1248            let this = this.as_local_mut().unwrap();
 1249            buffers.retain(|buffer| {
 1250                this.buffers_being_formatted
 1251                    .insert(buffer.read(cx).remote_id())
 1252            });
 1253        })?;
 1254        let _cleanup = defer({
 1255            let this = lsp_store.clone();
 1256            let mut cx = cx.clone();
 1257            let buffers = &buffers;
 1258            move || {
 1259                this.update(&mut cx, |this, cx| {
 1260                    let this = this.as_local_mut().unwrap();
 1261                    for buffer in buffers {
 1262                        this.buffers_being_formatted
 1263                            .remove(&buffer.read(cx).remote_id());
 1264                    }
 1265                })
 1266                .ok();
 1267            }
 1268        });
 1269        let mut project_transaction = ProjectTransaction::default();
 1270
 1271        for buffer in &buffers {
 1272            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1273                buffer.update(cx, |buffer, cx| {
 1274                    lsp_store
 1275                        .as_local()
 1276                        .unwrap()
 1277                        .language_servers_for_buffer(buffer, cx)
 1278                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1279                        .collect::<Vec<_>>()
 1280                })
 1281            })?;
 1282            for (_, language_server) in adapters_and_servers.iter() {
 1283                let actions = Self::get_server_code_actions_from_action_kinds(
 1284                    &lsp_store,
 1285                    language_server.server_id(),
 1286                    vec![kind.clone()],
 1287                    buffer,
 1288                    cx,
 1289                )
 1290                .await?;
 1291                Self::execute_code_actions_on_server(
 1292                    &lsp_store,
 1293                    language_server,
 1294                    actions,
 1295                    push_to_history,
 1296                    &mut project_transaction,
 1297                    cx,
 1298                )
 1299                .await?;
 1300            }
 1301        }
 1302        Ok(project_transaction)
 1303    }
 1304
 1305    async fn format_locally(
 1306        lsp_store: WeakEntity<LspStore>,
 1307        mut buffers: Vec<FormattableBuffer>,
 1308        push_to_history: bool,
 1309        trigger: FormatTrigger,
 1310        logger: zlog::Logger,
 1311        cx: &mut AsyncApp,
 1312    ) -> anyhow::Result<ProjectTransaction> {
 1313        // Do not allow multiple concurrent formatting requests for the
 1314        // same buffer.
 1315        lsp_store.update(cx, |this, cx| {
 1316            let this = this.as_local_mut().unwrap();
 1317            buffers.retain(|buffer| {
 1318                this.buffers_being_formatted
 1319                    .insert(buffer.handle.read(cx).remote_id())
 1320            });
 1321        })?;
 1322
 1323        let _cleanup = defer({
 1324            let this = lsp_store.clone();
 1325            let mut cx = cx.clone();
 1326            let buffers = &buffers;
 1327            move || {
 1328                this.update(&mut cx, |this, cx| {
 1329                    let this = this.as_local_mut().unwrap();
 1330                    for buffer in buffers {
 1331                        this.buffers_being_formatted
 1332                            .remove(&buffer.handle.read(cx).remote_id());
 1333                    }
 1334                })
 1335                .ok();
 1336            }
 1337        });
 1338
 1339        let mut project_transaction = ProjectTransaction::default();
 1340
 1341        for buffer in &buffers {
 1342            zlog::debug!(
 1343                logger =>
 1344                "formatting buffer '{:?}'",
 1345                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1346            );
 1347            // Create an empty transaction to hold all of the formatting edits.
 1348            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1349                // ensure no transactions created while formatting are
 1350                // grouped with the previous transaction in the history
 1351                // based on the transaction group interval
 1352                buffer.finalize_last_transaction();
 1353                buffer
 1354                    .start_transaction()
 1355                    .context("transaction already open")?;
 1356                buffer.end_transaction(cx);
 1357                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1358                buffer.finalize_last_transaction();
 1359                anyhow::Ok(transaction_id)
 1360            })??;
 1361
 1362            let result = Self::format_buffer_locally(
 1363                lsp_store.clone(),
 1364                buffer,
 1365                formatting_transaction_id,
 1366                trigger,
 1367                logger,
 1368                cx,
 1369            )
 1370            .await;
 1371
 1372            buffer.handle.update(cx, |buffer, cx| {
 1373                let Some(formatting_transaction) =
 1374                    buffer.get_transaction(formatting_transaction_id).cloned()
 1375                else {
 1376                    zlog::warn!(logger => "no formatting transaction");
 1377                    return;
 1378                };
 1379                if formatting_transaction.edit_ids.is_empty() {
 1380                    zlog::debug!(logger => "no changes made while formatting");
 1381                    buffer.forget_transaction(formatting_transaction_id);
 1382                    return;
 1383                }
 1384                if !push_to_history {
 1385                    zlog::trace!(logger => "forgetting format transaction");
 1386                    buffer.forget_transaction(formatting_transaction.id);
 1387                }
 1388                project_transaction
 1389                    .0
 1390                    .insert(cx.entity(), formatting_transaction);
 1391            })?;
 1392
 1393            result?;
 1394        }
 1395
 1396        Ok(project_transaction)
 1397    }
 1398
 1399    async fn format_buffer_locally(
 1400        lsp_store: WeakEntity<LspStore>,
 1401        buffer: &FormattableBuffer,
 1402        formatting_transaction_id: clock::Lamport,
 1403        trigger: FormatTrigger,
 1404        logger: zlog::Logger,
 1405        cx: &mut AsyncApp,
 1406    ) -> Result<()> {
 1407        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1408            buffer.handle.update(cx, |buffer, cx| {
 1409                let adapters_and_servers = lsp_store
 1410                    .as_local()
 1411                    .unwrap()
 1412                    .language_servers_for_buffer(buffer, cx)
 1413                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1414                    .collect::<Vec<_>>();
 1415                let settings =
 1416                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1417                        .into_owned();
 1418                (adapters_and_servers, settings)
 1419            })
 1420        })?;
 1421
 1422        /// Apply edits to the buffer that will become part of the formatting transaction.
 1423        /// Fails if the buffer has been edited since the start of that transaction.
 1424        fn extend_formatting_transaction(
 1425            buffer: &FormattableBuffer,
 1426            formatting_transaction_id: text::TransactionId,
 1427            cx: &mut AsyncApp,
 1428            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1429        ) -> anyhow::Result<()> {
 1430            buffer.handle.update(cx, |buffer, cx| {
 1431                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1432                if last_transaction_id != Some(formatting_transaction_id) {
 1433                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1434                }
 1435                buffer.start_transaction();
 1436                operation(buffer, cx);
 1437                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1438                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1439                }
 1440                Ok(())
 1441            })?
 1442        }
 1443
 1444        // handle whitespace formatting
 1445        if settings.remove_trailing_whitespace_on_save {
 1446            zlog::trace!(logger => "removing trailing whitespace");
 1447            let diff = buffer
 1448                .handle
 1449                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1450                .await;
 1451            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1452                buffer.apply_diff(diff, cx);
 1453            })?;
 1454        }
 1455
 1456        if settings.ensure_final_newline_on_save {
 1457            zlog::trace!(logger => "ensuring final newline");
 1458            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1459                buffer.ensure_final_newline(cx);
 1460            })?;
 1461        }
 1462
 1463        // Formatter for `code_actions_on_format` that runs before
 1464        // the rest of the formatters
 1465        let mut code_actions_on_format_formatters = None;
 1466        let should_run_code_actions_on_format = !matches!(
 1467            (trigger, &settings.format_on_save),
 1468            (FormatTrigger::Save, &FormatOnSave::Off)
 1469        );
 1470        if should_run_code_actions_on_format {
 1471            let have_code_actions_to_run_on_format = settings
 1472                .code_actions_on_format
 1473                .values()
 1474                .any(|enabled| *enabled);
 1475            if have_code_actions_to_run_on_format {
 1476                zlog::trace!(logger => "going to run code actions on format");
 1477                code_actions_on_format_formatters = Some(
 1478                    settings
 1479                        .code_actions_on_format
 1480                        .iter()
 1481                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1482                        .cloned()
 1483                        .map(Formatter::CodeAction)
 1484                        .collect::<Vec<_>>(),
 1485                );
 1486            }
 1487        }
 1488
 1489        let formatters = match (trigger, &settings.format_on_save) {
 1490            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1491            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1492                settings.formatter.as_ref()
 1493            }
 1494        };
 1495
 1496        let formatters = code_actions_on_format_formatters
 1497            .iter()
 1498            .flatten()
 1499            .chain(formatters);
 1500
 1501        for formatter in formatters {
 1502            let formatter = if formatter == &Formatter::Auto {
 1503                if settings.prettier.allowed {
 1504                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1505                    &Formatter::Prettier
 1506                } else {
 1507                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1508                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1509                }
 1510            } else {
 1511                formatter
 1512            };
 1513            match formatter {
 1514                Formatter::Auto => unreachable!("Auto resolved above"),
 1515                Formatter::Prettier => {
 1516                    let logger = zlog::scoped!(logger => "prettier");
 1517                    zlog::trace!(logger => "formatting");
 1518                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1519
 1520                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1521                        lsp_store.prettier_store().unwrap().downgrade()
 1522                    })?;
 1523                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1524                        .await
 1525                        .transpose()?;
 1526                    let Some(diff) = diff else {
 1527                        zlog::trace!(logger => "No changes");
 1528                        continue;
 1529                    };
 1530
 1531                    extend_formatting_transaction(
 1532                        buffer,
 1533                        formatting_transaction_id,
 1534                        cx,
 1535                        |buffer, cx| {
 1536                            buffer.apply_diff(diff, cx);
 1537                        },
 1538                    )?;
 1539                }
 1540                Formatter::External { command, arguments } => {
 1541                    let logger = zlog::scoped!(logger => "command");
 1542                    zlog::trace!(logger => "formatting");
 1543                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1544
 1545                    let diff = Self::format_via_external_command(
 1546                        buffer,
 1547                        command.as_ref(),
 1548                        arguments.as_deref(),
 1549                        cx,
 1550                    )
 1551                    .await
 1552                    .with_context(|| {
 1553                        format!("Failed to format buffer via external command: {}", command)
 1554                    })?;
 1555                    let Some(diff) = diff else {
 1556                        zlog::trace!(logger => "No changes");
 1557                        continue;
 1558                    };
 1559
 1560                    extend_formatting_transaction(
 1561                        buffer,
 1562                        formatting_transaction_id,
 1563                        cx,
 1564                        |buffer, cx| {
 1565                            buffer.apply_diff(diff, cx);
 1566                        },
 1567                    )?;
 1568                }
 1569                Formatter::LanguageServer(specifier) => {
 1570                    let logger = zlog::scoped!(logger => "language-server");
 1571                    zlog::trace!(logger => "formatting");
 1572                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1573
 1574                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1575                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1576                        continue;
 1577                    };
 1578
 1579                    let language_server = match specifier {
 1580                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1581                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1582                                if adapter.name.0.as_ref() == name {
 1583                                    Some(server.clone())
 1584                                } else {
 1585                                    None
 1586                                }
 1587                            })
 1588                        }
 1589                        settings::LanguageServerFormatterSpecifier::Current => {
 1590                            adapters_and_servers.first().map(|e| e.1.clone())
 1591                        }
 1592                    };
 1593
 1594                    let Some(language_server) = language_server else {
 1595                        log::debug!(
 1596                            "No language server found to format buffer '{:?}'. Skipping",
 1597                            buffer_path_abs.as_path().to_string_lossy()
 1598                        );
 1599                        continue;
 1600                    };
 1601
 1602                    zlog::trace!(
 1603                        logger =>
 1604                        "Formatting buffer '{:?}' using language server '{:?}'",
 1605                        buffer_path_abs.as_path().to_string_lossy(),
 1606                        language_server.name()
 1607                    );
 1608
 1609                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1610                        zlog::trace!(logger => "formatting ranges");
 1611                        Self::format_ranges_via_lsp(
 1612                            &lsp_store,
 1613                            &buffer.handle,
 1614                            ranges,
 1615                            buffer_path_abs,
 1616                            &language_server,
 1617                            &settings,
 1618                            cx,
 1619                        )
 1620                        .await
 1621                        .context("Failed to format ranges via language server")?
 1622                    } else {
 1623                        zlog::trace!(logger => "formatting full");
 1624                        Self::format_via_lsp(
 1625                            &lsp_store,
 1626                            &buffer.handle,
 1627                            buffer_path_abs,
 1628                            &language_server,
 1629                            &settings,
 1630                            cx,
 1631                        )
 1632                        .await
 1633                        .context("failed to format via language server")?
 1634                    };
 1635
 1636                    if edits.is_empty() {
 1637                        zlog::trace!(logger => "No changes");
 1638                        continue;
 1639                    }
 1640                    extend_formatting_transaction(
 1641                        buffer,
 1642                        formatting_transaction_id,
 1643                        cx,
 1644                        |buffer, cx| {
 1645                            buffer.edit(edits, None, cx);
 1646                        },
 1647                    )?;
 1648                }
 1649                Formatter::CodeAction(code_action_name) => {
 1650                    let logger = zlog::scoped!(logger => "code-actions");
 1651                    zlog::trace!(logger => "formatting");
 1652                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1653
 1654                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1655                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1656                        continue;
 1657                    };
 1658
 1659                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1660                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1661
 1662                    let mut actions_and_servers = Vec::new();
 1663
 1664                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1665                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1666                            &lsp_store,
 1667                            language_server.server_id(),
 1668                            vec![code_action_kind.clone()],
 1669                            &buffer.handle,
 1670                            cx,
 1671                        )
 1672                        .await
 1673                        .with_context(|| {
 1674                            format!(
 1675                                "Failed to resolve code action {:?} with language server {}",
 1676                                code_action_kind,
 1677                                language_server.name()
 1678                            )
 1679                        });
 1680                        let Ok(actions) = actions_result else {
 1681                            // note: it may be better to set result to the error and break formatters here
 1682                            // but for now we try to execute the actions that we can resolve and skip the rest
 1683                            zlog::error!(
 1684                                logger =>
 1685                                "Failed to resolve code action {:?} with language server {}",
 1686                                code_action_kind,
 1687                                language_server.name()
 1688                            );
 1689                            continue;
 1690                        };
 1691                        for action in actions {
 1692                            actions_and_servers.push((action, index));
 1693                        }
 1694                    }
 1695
 1696                    if actions_and_servers.is_empty() {
 1697                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1698                        continue;
 1699                    }
 1700
 1701                    'actions: for (mut action, server_index) in actions_and_servers {
 1702                        let server = &adapters_and_servers[server_index].1;
 1703
 1704                        let describe_code_action = |action: &CodeAction| {
 1705                            format!(
 1706                                "code action '{}' with title \"{}\" on server {}",
 1707                                action
 1708                                    .lsp_action
 1709                                    .action_kind()
 1710                                    .unwrap_or("unknown".into())
 1711                                    .as_str(),
 1712                                action.lsp_action.title(),
 1713                                server.name(),
 1714                            )
 1715                        };
 1716
 1717                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1718
 1719                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1720                            zlog::error!(
 1721                                logger =>
 1722                                "Failed to resolve {}. Error: {}",
 1723                                describe_code_action(&action),
 1724                                err
 1725                            );
 1726                            continue;
 1727                        }
 1728
 1729                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1730                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1731                            // but filters out and logs warnings for code actions that require unreasonably
 1732                            // difficult handling on our part, such as:
 1733                            // - applying edits that call commands
 1734                            //   which can result in arbitrary workspace edits being sent from the server that
 1735                            //   have no way of being tied back to the command that initiated them (i.e. we
 1736                            //   can't know which edits are part of the format request, or if the server is done sending
 1737                            //   actions in response to the command)
 1738                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1739                            //   as we then would need to handle such changes correctly in the local history as well
 1740                            //   as the remote history through the ProjectTransaction
 1741                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1742                            // Supporting these actions is not impossible, but not supported as of yet.
 1743                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1744                                zlog::trace!(
 1745                                    logger =>
 1746                                    "No changes for code action. Skipping {}",
 1747                                    describe_code_action(&action),
 1748                                );
 1749                                continue;
 1750                            }
 1751
 1752                            let mut operations = Vec::new();
 1753                            if let Some(document_changes) = edit.document_changes {
 1754                                match document_changes {
 1755                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1756                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1757                                    ),
 1758                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1759                                }
 1760                            } else if let Some(changes) = edit.changes {
 1761                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1762                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1763                                        text_document:
 1764                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1765                                                uri,
 1766                                                version: None,
 1767                                            },
 1768                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1769                                    })
 1770                                }));
 1771                            }
 1772
 1773                            let mut edits = Vec::with_capacity(operations.len());
 1774
 1775                            if operations.is_empty() {
 1776                                zlog::trace!(
 1777                                    logger =>
 1778                                    "No changes for code action. Skipping {}",
 1779                                    describe_code_action(&action),
 1780                                );
 1781                                continue;
 1782                            }
 1783                            for operation in operations {
 1784                                let op = match operation {
 1785                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1786                                    lsp::DocumentChangeOperation::Op(_) => {
 1787                                        zlog::warn!(
 1788                                            logger =>
 1789                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1790                                            describe_code_action(&action),
 1791                                        );
 1792                                        continue 'actions;
 1793                                    }
 1794                                };
 1795                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1796                                    zlog::warn!(
 1797                                        logger =>
 1798                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1799                                        &op.text_document.uri,
 1800                                        describe_code_action(&action),
 1801                                    );
 1802                                    continue 'actions;
 1803                                };
 1804                                if &file_path != buffer_path_abs {
 1805                                    zlog::warn!(
 1806                                        logger =>
 1807                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1808                                        file_path,
 1809                                        buffer_path_abs,
 1810                                        describe_code_action(&action),
 1811                                    );
 1812                                    continue 'actions;
 1813                                }
 1814
 1815                                let mut lsp_edits = Vec::new();
 1816                                for edit in op.edits {
 1817                                    match edit {
 1818                                        Edit::Plain(edit) => {
 1819                                            if !lsp_edits.contains(&edit) {
 1820                                                lsp_edits.push(edit);
 1821                                            }
 1822                                        }
 1823                                        Edit::Annotated(edit) => {
 1824                                            if !lsp_edits.contains(&edit.text_edit) {
 1825                                                lsp_edits.push(edit.text_edit);
 1826                                            }
 1827                                        }
 1828                                        Edit::Snippet(_) => {
 1829                                            zlog::warn!(
 1830                                                logger =>
 1831                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1832                                                describe_code_action(&action),
 1833                                            );
 1834                                            continue 'actions;
 1835                                        }
 1836                                    }
 1837                                }
 1838                                let edits_result = lsp_store
 1839                                    .update(cx, |lsp_store, cx| {
 1840                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1841                                            &buffer.handle,
 1842                                            lsp_edits,
 1843                                            server.server_id(),
 1844                                            op.text_document.version,
 1845                                            cx,
 1846                                        )
 1847                                    })?
 1848                                    .await;
 1849                                let Ok(resolved_edits) = edits_result else {
 1850                                    zlog::warn!(
 1851                                        logger =>
 1852                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1853                                        buffer_path_abs.as_path(),
 1854                                        describe_code_action(&action),
 1855                                    );
 1856                                    continue 'actions;
 1857                                };
 1858                                edits.extend(resolved_edits);
 1859                            }
 1860
 1861                            if edits.is_empty() {
 1862                                zlog::warn!(logger => "No edits resolved from LSP");
 1863                                continue;
 1864                            }
 1865
 1866                            extend_formatting_transaction(
 1867                                buffer,
 1868                                formatting_transaction_id,
 1869                                cx,
 1870                                |buffer, cx| {
 1871                                    zlog::info!(
 1872                                        "Applying edits {edits:?}. Content: {:?}",
 1873                                        buffer.text()
 1874                                    );
 1875                                    buffer.edit(edits, None, cx);
 1876                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1877                                },
 1878                            )?;
 1879                        }
 1880
 1881                        if let Some(command) = action.lsp_action.command() {
 1882                            zlog::warn!(
 1883                                logger =>
 1884                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1885                                &command.command,
 1886                            );
 1887
 1888                            // bail early if command is invalid
 1889                            let server_capabilities = server.capabilities();
 1890                            let available_commands = server_capabilities
 1891                                .execute_command_provider
 1892                                .as_ref()
 1893                                .map(|options| options.commands.as_slice())
 1894                                .unwrap_or_default();
 1895                            if !available_commands.contains(&command.command) {
 1896                                zlog::warn!(
 1897                                    logger =>
 1898                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1899                                    command.command,
 1900                                    server.name(),
 1901                                );
 1902                                continue;
 1903                            }
 1904
 1905                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1906                            extend_formatting_transaction(
 1907                                buffer,
 1908                                formatting_transaction_id,
 1909                                cx,
 1910                                |_, _| {},
 1911                            )?;
 1912                            zlog::info!(logger => "Executing command {}", &command.command);
 1913
 1914                            lsp_store.update(cx, |this, _| {
 1915                                this.as_local_mut()
 1916                                    .unwrap()
 1917                                    .last_workspace_edits_by_language_server
 1918                                    .remove(&server.server_id());
 1919                            })?;
 1920
 1921                            let execute_command_result = server
 1922                                .request::<lsp::request::ExecuteCommand>(
 1923                                    lsp::ExecuteCommandParams {
 1924                                        command: command.command.clone(),
 1925                                        arguments: command.arguments.clone().unwrap_or_default(),
 1926                                        ..Default::default()
 1927                                    },
 1928                                )
 1929                                .await
 1930                                .into_response();
 1931
 1932                            if execute_command_result.is_err() {
 1933                                zlog::error!(
 1934                                    logger =>
 1935                                    "Failed to execute command '{}' as part of {}",
 1936                                    &command.command,
 1937                                    describe_code_action(&action),
 1938                                );
 1939                                continue 'actions;
 1940                            }
 1941
 1942                            let mut project_transaction_command =
 1943                                lsp_store.update(cx, |this, _| {
 1944                                    this.as_local_mut()
 1945                                        .unwrap()
 1946                                        .last_workspace_edits_by_language_server
 1947                                        .remove(&server.server_id())
 1948                                        .unwrap_or_default()
 1949                                })?;
 1950
 1951                            if let Some(transaction) =
 1952                                project_transaction_command.0.remove(&buffer.handle)
 1953                            {
 1954                                zlog::trace!(
 1955                                    logger =>
 1956                                    "Successfully captured {} edits that resulted from command {}",
 1957                                    transaction.edit_ids.len(),
 1958                                    &command.command,
 1959                                );
 1960                                let transaction_id_project_transaction = transaction.id;
 1961                                buffer.handle.update(cx, |buffer, _| {
 1962                                    // it may have been removed from history if push_to_history was
 1963                                    // false in deserialize_workspace_edit. If so push it so we
 1964                                    // can merge it with the format transaction
 1965                                    // and pop the combined transaction off the history stack
 1966                                    // later if push_to_history is false
 1967                                    if buffer.get_transaction(transaction.id).is_none() {
 1968                                        buffer.push_transaction(transaction, Instant::now());
 1969                                    }
 1970                                    buffer.merge_transactions(
 1971                                        transaction_id_project_transaction,
 1972                                        formatting_transaction_id,
 1973                                    );
 1974                                })?;
 1975                            }
 1976
 1977                            if !project_transaction_command.0.is_empty() {
 1978                                let mut extra_buffers = String::new();
 1979                                for buffer in project_transaction_command.0.keys() {
 1980                                    buffer
 1981                                        .read_with(cx, |b, cx| {
 1982                                            if let Some(path) = b.project_path(cx) {
 1983                                                if !extra_buffers.is_empty() {
 1984                                                    extra_buffers.push_str(", ");
 1985                                                }
 1986                                                extra_buffers.push_str(path.path.as_unix_str());
 1987                                            }
 1988                                        })
 1989                                        .ok();
 1990                                }
 1991                                zlog::warn!(
 1992                                    logger =>
 1993                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1994                                    &command.command,
 1995                                    extra_buffers,
 1996                                );
 1997                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1998                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1999                                // add it so it's included, and merge it into the format transaction when its created later
 2000                            }
 2001                        }
 2002                    }
 2003                }
 2004            }
 2005        }
 2006
 2007        Ok(())
 2008    }
 2009
 2010    pub async fn format_ranges_via_lsp(
 2011        this: &WeakEntity<LspStore>,
 2012        buffer_handle: &Entity<Buffer>,
 2013        ranges: &[Range<Anchor>],
 2014        abs_path: &Path,
 2015        language_server: &Arc<LanguageServer>,
 2016        settings: &LanguageSettings,
 2017        cx: &mut AsyncApp,
 2018    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2019        let capabilities = &language_server.capabilities();
 2020        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2021        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2022            anyhow::bail!(
 2023                "{} language server does not support range formatting",
 2024                language_server.name()
 2025            );
 2026        }
 2027
 2028        let uri = file_path_to_lsp_url(abs_path)?;
 2029        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2030
 2031        let lsp_edits = {
 2032            let mut lsp_ranges = Vec::new();
 2033            this.update(cx, |_this, cx| {
 2034                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2035                // not have been sent to the language server. This seems like a fairly systemic
 2036                // issue, though, the resolution probably is not specific to formatting.
 2037                //
 2038                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2039                // LSP.
 2040                let snapshot = buffer_handle.read(cx).snapshot();
 2041                for range in ranges {
 2042                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2043                }
 2044                anyhow::Ok(())
 2045            })??;
 2046
 2047            let mut edits = None;
 2048            for range in lsp_ranges {
 2049                if let Some(mut edit) = language_server
 2050                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2051                        text_document: text_document.clone(),
 2052                        range,
 2053                        options: lsp_command::lsp_formatting_options(settings),
 2054                        work_done_progress_params: Default::default(),
 2055                    })
 2056                    .await
 2057                    .into_response()?
 2058                {
 2059                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2060                }
 2061            }
 2062            edits
 2063        };
 2064
 2065        if let Some(lsp_edits) = lsp_edits {
 2066            this.update(cx, |this, cx| {
 2067                this.as_local_mut().unwrap().edits_from_lsp(
 2068                    buffer_handle,
 2069                    lsp_edits,
 2070                    language_server.server_id(),
 2071                    None,
 2072                    cx,
 2073                )
 2074            })?
 2075            .await
 2076        } else {
 2077            Ok(Vec::with_capacity(0))
 2078        }
 2079    }
 2080
 2081    async fn format_via_lsp(
 2082        this: &WeakEntity<LspStore>,
 2083        buffer: &Entity<Buffer>,
 2084        abs_path: &Path,
 2085        language_server: &Arc<LanguageServer>,
 2086        settings: &LanguageSettings,
 2087        cx: &mut AsyncApp,
 2088    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2089        let logger = zlog::scoped!("lsp_format");
 2090        zlog::debug!(logger => "Formatting via LSP");
 2091
 2092        let uri = file_path_to_lsp_url(abs_path)?;
 2093        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2094        let capabilities = &language_server.capabilities();
 2095
 2096        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2097        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2098
 2099        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2100            let _timer = zlog::time!(logger => "format-full");
 2101            language_server
 2102                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2103                    text_document,
 2104                    options: lsp_command::lsp_formatting_options(settings),
 2105                    work_done_progress_params: Default::default(),
 2106                })
 2107                .await
 2108                .into_response()?
 2109        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2110            let _timer = zlog::time!(logger => "format-range");
 2111            let buffer_start = lsp::Position::new(0, 0);
 2112            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2113            language_server
 2114                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2115                    text_document: text_document.clone(),
 2116                    range: lsp::Range::new(buffer_start, buffer_end),
 2117                    options: lsp_command::lsp_formatting_options(settings),
 2118                    work_done_progress_params: Default::default(),
 2119                })
 2120                .await
 2121                .into_response()?
 2122        } else {
 2123            None
 2124        };
 2125
 2126        if let Some(lsp_edits) = lsp_edits {
 2127            this.update(cx, |this, cx| {
 2128                this.as_local_mut().unwrap().edits_from_lsp(
 2129                    buffer,
 2130                    lsp_edits,
 2131                    language_server.server_id(),
 2132                    None,
 2133                    cx,
 2134                )
 2135            })?
 2136            .await
 2137        } else {
 2138            Ok(Vec::with_capacity(0))
 2139        }
 2140    }
 2141
 2142    async fn format_via_external_command(
 2143        buffer: &FormattableBuffer,
 2144        command: &str,
 2145        arguments: Option<&[String]>,
 2146        cx: &mut AsyncApp,
 2147    ) -> Result<Option<Diff>> {
 2148        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2149            let file = File::from_dyn(buffer.file())?;
 2150            let worktree = file.worktree.read(cx);
 2151            let mut worktree_path = worktree.abs_path().to_path_buf();
 2152            if worktree.root_entry()?.is_file() {
 2153                worktree_path.pop();
 2154            }
 2155            Some(worktree_path)
 2156        })?;
 2157
 2158        let mut child = util::command::new_smol_command(command);
 2159
 2160        if let Some(buffer_env) = buffer.env.as_ref() {
 2161            child.envs(buffer_env);
 2162        }
 2163
 2164        if let Some(working_dir_path) = working_dir_path {
 2165            child.current_dir(working_dir_path);
 2166        }
 2167
 2168        if let Some(arguments) = arguments {
 2169            child.args(arguments.iter().map(|arg| {
 2170                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2171                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2172                } else {
 2173                    arg.replace("{buffer_path}", "Untitled")
 2174                }
 2175            }));
 2176        }
 2177
 2178        let mut child = child
 2179            .stdin(smol::process::Stdio::piped())
 2180            .stdout(smol::process::Stdio::piped())
 2181            .stderr(smol::process::Stdio::piped())
 2182            .spawn()?;
 2183
 2184        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2185        let text = buffer
 2186            .handle
 2187            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2188        for chunk in text.chunks() {
 2189            stdin.write_all(chunk.as_bytes()).await?;
 2190        }
 2191        stdin.flush().await?;
 2192
 2193        let output = child.output().await?;
 2194        anyhow::ensure!(
 2195            output.status.success(),
 2196            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2197            output.status.code(),
 2198            String::from_utf8_lossy(&output.stdout),
 2199            String::from_utf8_lossy(&output.stderr),
 2200        );
 2201
 2202        let stdout = String::from_utf8(output.stdout)?;
 2203        Ok(Some(
 2204            buffer
 2205                .handle
 2206                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2207                .await,
 2208        ))
 2209    }
 2210
 2211    async fn try_resolve_code_action(
 2212        lang_server: &LanguageServer,
 2213        action: &mut CodeAction,
 2214    ) -> anyhow::Result<()> {
 2215        match &mut action.lsp_action {
 2216            LspAction::Action(lsp_action) => {
 2217                if !action.resolved
 2218                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2219                    && lsp_action.data.is_some()
 2220                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2221                {
 2222                    *lsp_action = Box::new(
 2223                        lang_server
 2224                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2225                            .await
 2226                            .into_response()?,
 2227                    );
 2228                }
 2229            }
 2230            LspAction::CodeLens(lens) => {
 2231                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2232                    *lens = lang_server
 2233                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2234                        .await
 2235                        .into_response()?;
 2236                }
 2237            }
 2238            LspAction::Command(_) => {}
 2239        }
 2240
 2241        action.resolved = true;
 2242        anyhow::Ok(())
 2243    }
 2244
 2245    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2246        let buffer = buffer_handle.read(cx);
 2247
 2248        let file = buffer.file().cloned();
 2249
 2250        let Some(file) = File::from_dyn(file.as_ref()) else {
 2251            return;
 2252        };
 2253        if !file.is_local() {
 2254            return;
 2255        }
 2256        let path = ProjectPath::from_file(file, cx);
 2257        let worktree_id = file.worktree_id(cx);
 2258        let language = buffer.language().cloned();
 2259
 2260        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2261            for (server_id, diagnostics) in
 2262                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2263            {
 2264                self.update_buffer_diagnostics(
 2265                    buffer_handle,
 2266                    server_id,
 2267                    None,
 2268                    None,
 2269                    None,
 2270                    Vec::new(),
 2271                    diagnostics,
 2272                    cx,
 2273                )
 2274                .log_err();
 2275            }
 2276        }
 2277        let Some(language) = language else {
 2278            return;
 2279        };
 2280        let Some(snapshot) = self
 2281            .worktree_store
 2282            .read(cx)
 2283            .worktree_for_id(worktree_id, cx)
 2284            .map(|worktree| worktree.read(cx).snapshot())
 2285        else {
 2286            return;
 2287        };
 2288        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2289
 2290        for server_id in
 2291            self.lsp_tree
 2292                .get(path, language.name(), language.manifest(), &delegate, cx)
 2293        {
 2294            let server = self
 2295                .language_servers
 2296                .get(&server_id)
 2297                .and_then(|server_state| {
 2298                    if let LanguageServerState::Running { server, .. } = server_state {
 2299                        Some(server.clone())
 2300                    } else {
 2301                        None
 2302                    }
 2303                });
 2304            let server = match server {
 2305                Some(server) => server,
 2306                None => continue,
 2307            };
 2308
 2309            buffer_handle.update(cx, |buffer, cx| {
 2310                buffer.set_completion_triggers(
 2311                    server.server_id(),
 2312                    server
 2313                        .capabilities()
 2314                        .completion_provider
 2315                        .as_ref()
 2316                        .and_then(|provider| {
 2317                            provider
 2318                                .trigger_characters
 2319                                .as_ref()
 2320                                .map(|characters| characters.iter().cloned().collect())
 2321                        })
 2322                        .unwrap_or_default(),
 2323                    cx,
 2324                );
 2325            });
 2326        }
 2327    }
 2328
 2329    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2330        buffer.update(cx, |buffer, cx| {
 2331            let Some(language) = buffer.language() else {
 2332                return;
 2333            };
 2334            let path = ProjectPath {
 2335                worktree_id: old_file.worktree_id(cx),
 2336                path: old_file.path.clone(),
 2337            };
 2338            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2339                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2340                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2341            }
 2342        });
 2343    }
 2344
 2345    fn update_buffer_diagnostics(
 2346        &mut self,
 2347        buffer: &Entity<Buffer>,
 2348        server_id: LanguageServerId,
 2349        registration_id: Option<Option<SharedString>>,
 2350        result_id: Option<SharedString>,
 2351        version: Option<i32>,
 2352        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2353        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2354        cx: &mut Context<LspStore>,
 2355    ) -> Result<()> {
 2356        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2357            Ordering::Equal
 2358                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2359                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2360                .then_with(|| a.severity.cmp(&b.severity))
 2361                .then_with(|| a.message.cmp(&b.message))
 2362        }
 2363
 2364        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2365        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2366        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2367
 2368        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2369            Ordering::Equal
 2370                .then_with(|| a.range.start.cmp(&b.range.start))
 2371                .then_with(|| b.range.end.cmp(&a.range.end))
 2372                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2373        });
 2374
 2375        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2376
 2377        let edits_since_save = std::cell::LazyCell::new(|| {
 2378            let saved_version = buffer.read(cx).saved_version();
 2379            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2380        });
 2381
 2382        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2383
 2384        for (new_diagnostic, entry) in diagnostics {
 2385            let start;
 2386            let end;
 2387            if new_diagnostic && entry.diagnostic.is_disk_based {
 2388                // Some diagnostics are based on files on disk instead of buffers'
 2389                // current contents. Adjust these diagnostics' ranges to reflect
 2390                // any unsaved edits.
 2391                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2392                // and were properly adjusted on reuse.
 2393                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2394                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2395            } else {
 2396                start = entry.range.start;
 2397                end = entry.range.end;
 2398            }
 2399
 2400            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2401                ..snapshot.clip_point_utf16(end, Bias::Right);
 2402
 2403            // Expand empty ranges by one codepoint
 2404            if range.start == range.end {
 2405                // This will be go to the next boundary when being clipped
 2406                range.end.column += 1;
 2407                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2408                if range.start == range.end && range.end.column > 0 {
 2409                    range.start.column -= 1;
 2410                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2411                }
 2412            }
 2413
 2414            sanitized_diagnostics.push(DiagnosticEntry {
 2415                range,
 2416                diagnostic: entry.diagnostic,
 2417            });
 2418        }
 2419        drop(edits_since_save);
 2420
 2421        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2422        buffer.update(cx, |buffer, cx| {
 2423            if let Some(registration_id) = registration_id {
 2424                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2425                    self.buffer_pull_diagnostics_result_ids
 2426                        .entry(server_id)
 2427                        .or_default()
 2428                        .entry(registration_id)
 2429                        .or_default()
 2430                        .insert(abs_path, result_id);
 2431                }
 2432            }
 2433
 2434            buffer.update_diagnostics(server_id, set, cx)
 2435        });
 2436
 2437        Ok(())
 2438    }
 2439
 2440    fn register_language_server_for_invisible_worktree(
 2441        &mut self,
 2442        worktree: &Entity<Worktree>,
 2443        language_server_id: LanguageServerId,
 2444        cx: &mut App,
 2445    ) {
 2446        let worktree = worktree.read(cx);
 2447        let worktree_id = worktree.id();
 2448        debug_assert!(!worktree.is_visible());
 2449        let Some(mut origin_seed) = self
 2450            .language_server_ids
 2451            .iter()
 2452            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2453        else {
 2454            return;
 2455        };
 2456        origin_seed.worktree_id = worktree_id;
 2457        self.language_server_ids
 2458            .entry(origin_seed)
 2459            .or_insert_with(|| UnifiedLanguageServer {
 2460                id: language_server_id,
 2461                project_roots: Default::default(),
 2462            });
 2463    }
 2464
 2465    fn register_buffer_with_language_servers(
 2466        &mut self,
 2467        buffer_handle: &Entity<Buffer>,
 2468        only_register_servers: HashSet<LanguageServerSelector>,
 2469        cx: &mut Context<LspStore>,
 2470    ) {
 2471        let buffer = buffer_handle.read(cx);
 2472        let buffer_id = buffer.remote_id();
 2473
 2474        let Some(file) = File::from_dyn(buffer.file()) else {
 2475            return;
 2476        };
 2477        if !file.is_local() {
 2478            return;
 2479        }
 2480
 2481        let abs_path = file.abs_path(cx);
 2482        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2483            return;
 2484        };
 2485        let initial_snapshot = buffer.text_snapshot();
 2486        let worktree_id = file.worktree_id(cx);
 2487
 2488        let Some(language) = buffer.language().cloned() else {
 2489            return;
 2490        };
 2491        let path: Arc<RelPath> = file
 2492            .path()
 2493            .parent()
 2494            .map(Arc::from)
 2495            .unwrap_or_else(|| file.path().clone());
 2496        let Some(worktree) = self
 2497            .worktree_store
 2498            .read(cx)
 2499            .worktree_for_id(worktree_id, cx)
 2500        else {
 2501            return;
 2502        };
 2503        let language_name = language.name();
 2504        let (reused, delegate, servers) = self
 2505            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2506            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2507            .unwrap_or_else(|| {
 2508                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2509                let delegate: Arc<dyn ManifestDelegate> =
 2510                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2511
 2512                let servers = self
 2513                    .lsp_tree
 2514                    .walk(
 2515                        ProjectPath { worktree_id, path },
 2516                        language.name(),
 2517                        language.manifest(),
 2518                        &delegate,
 2519                        cx,
 2520                    )
 2521                    .collect::<Vec<_>>();
 2522                (false, lsp_delegate, servers)
 2523            });
 2524        let servers_and_adapters = servers
 2525            .into_iter()
 2526            .filter_map(|server_node| {
 2527                if reused && server_node.server_id().is_none() {
 2528                    return None;
 2529                }
 2530                if !only_register_servers.is_empty() {
 2531                    if let Some(server_id) = server_node.server_id()
 2532                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2533                    {
 2534                        return None;
 2535                    }
 2536                    if let Some(name) = server_node.name()
 2537                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2538                    {
 2539                        return None;
 2540                    }
 2541                }
 2542
 2543                let server_id = server_node.server_id_or_init(|disposition| {
 2544                    let path = &disposition.path;
 2545
 2546                    {
 2547                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2548
 2549                        let server_id = self.get_or_insert_language_server(
 2550                            &worktree,
 2551                            delegate.clone(),
 2552                            disposition,
 2553                            &language_name,
 2554                            cx,
 2555                        );
 2556
 2557                        if let Some(state) = self.language_servers.get(&server_id)
 2558                            && let Ok(uri) = uri
 2559                        {
 2560                            state.add_workspace_folder(uri);
 2561                        };
 2562                        server_id
 2563                    }
 2564                })?;
 2565                let server_state = self.language_servers.get(&server_id)?;
 2566                if let LanguageServerState::Running {
 2567                    server, adapter, ..
 2568                } = server_state
 2569                {
 2570                    Some((server.clone(), adapter.clone()))
 2571                } else {
 2572                    None
 2573                }
 2574            })
 2575            .collect::<Vec<_>>();
 2576        for (server, adapter) in servers_and_adapters {
 2577            buffer_handle.update(cx, |buffer, cx| {
 2578                buffer.set_completion_triggers(
 2579                    server.server_id(),
 2580                    server
 2581                        .capabilities()
 2582                        .completion_provider
 2583                        .as_ref()
 2584                        .and_then(|provider| {
 2585                            provider
 2586                                .trigger_characters
 2587                                .as_ref()
 2588                                .map(|characters| characters.iter().cloned().collect())
 2589                        })
 2590                        .unwrap_or_default(),
 2591                    cx,
 2592                );
 2593            });
 2594
 2595            let snapshot = LspBufferSnapshot {
 2596                version: 0,
 2597                snapshot: initial_snapshot.clone(),
 2598            };
 2599
 2600            let mut registered = false;
 2601            self.buffer_snapshots
 2602                .entry(buffer_id)
 2603                .or_default()
 2604                .entry(server.server_id())
 2605                .or_insert_with(|| {
 2606                    registered = true;
 2607                    server.register_buffer(
 2608                        uri.clone(),
 2609                        adapter.language_id(&language.name()),
 2610                        0,
 2611                        initial_snapshot.text(),
 2612                    );
 2613
 2614                    vec![snapshot]
 2615                });
 2616
 2617            self.buffers_opened_in_servers
 2618                .entry(buffer_id)
 2619                .or_default()
 2620                .insert(server.server_id());
 2621            if registered {
 2622                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2623                    language_server_id: server.server_id(),
 2624                    name: None,
 2625                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2626                        proto::RegisteredForBuffer {
 2627                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2628                            buffer_id: buffer_id.to_proto(),
 2629                        },
 2630                    ),
 2631                });
 2632            }
 2633        }
 2634    }
 2635
 2636    fn reuse_existing_language_server<'lang_name>(
 2637        &self,
 2638        server_tree: &LanguageServerTree,
 2639        worktree: &Entity<Worktree>,
 2640        language_name: &'lang_name LanguageName,
 2641        cx: &mut App,
 2642    ) -> Option<(
 2643        Arc<LocalLspAdapterDelegate>,
 2644        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2645    )> {
 2646        if worktree.read(cx).is_visible() {
 2647            return None;
 2648        }
 2649
 2650        let worktree_store = self.worktree_store.read(cx);
 2651        let servers = server_tree
 2652            .instances
 2653            .iter()
 2654            .filter(|(worktree_id, _)| {
 2655                worktree_store
 2656                    .worktree_for_id(**worktree_id, cx)
 2657                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2658            })
 2659            .flat_map(|(worktree_id, servers)| {
 2660                servers
 2661                    .roots
 2662                    .iter()
 2663                    .flat_map(|(_, language_servers)| language_servers)
 2664                    .map(move |(_, (server_node, server_languages))| {
 2665                        (worktree_id, server_node, server_languages)
 2666                    })
 2667                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2668                    .map(|(worktree_id, server_node, _)| {
 2669                        (
 2670                            *worktree_id,
 2671                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2672                        )
 2673                    })
 2674            })
 2675            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2676                acc.entry(worktree_id)
 2677                    .or_insert_with(Vec::new)
 2678                    .push(server_node);
 2679                acc
 2680            })
 2681            .into_values()
 2682            .max_by_key(|servers| servers.len())?;
 2683
 2684        let worktree_id = worktree.read(cx).id();
 2685        let apply = move |tree: &mut LanguageServerTree| {
 2686            for server_node in &servers {
 2687                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2688            }
 2689            servers
 2690        };
 2691
 2692        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2693        Some((delegate, apply))
 2694    }
 2695
 2696    pub(crate) fn unregister_old_buffer_from_language_servers(
 2697        &mut self,
 2698        buffer: &Entity<Buffer>,
 2699        old_file: &File,
 2700        cx: &mut App,
 2701    ) {
 2702        let old_path = match old_file.as_local() {
 2703            Some(local) => local.abs_path(cx),
 2704            None => return,
 2705        };
 2706
 2707        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2708            debug_panic!("{old_path:?} is not parseable as an URI");
 2709            return;
 2710        };
 2711        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2712    }
 2713
 2714    pub(crate) fn unregister_buffer_from_language_servers(
 2715        &mut self,
 2716        buffer: &Entity<Buffer>,
 2717        file_url: &lsp::Uri,
 2718        cx: &mut App,
 2719    ) {
 2720        buffer.update(cx, |buffer, cx| {
 2721            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2722
 2723            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2724                if snapshots
 2725                    .as_mut()
 2726                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2727                {
 2728                    language_server.unregister_buffer(file_url.clone());
 2729                }
 2730            }
 2731        });
 2732    }
 2733
 2734    fn buffer_snapshot_for_lsp_version(
 2735        &mut self,
 2736        buffer: &Entity<Buffer>,
 2737        server_id: LanguageServerId,
 2738        version: Option<i32>,
 2739        cx: &App,
 2740    ) -> Result<TextBufferSnapshot> {
 2741        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2742
 2743        if let Some(version) = version {
 2744            let buffer_id = buffer.read(cx).remote_id();
 2745            let snapshots = if let Some(snapshots) = self
 2746                .buffer_snapshots
 2747                .get_mut(&buffer_id)
 2748                .and_then(|m| m.get_mut(&server_id))
 2749            {
 2750                snapshots
 2751            } else if version == 0 {
 2752                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2753                // We detect this case and treat it as if the version was `None`.
 2754                return Ok(buffer.read(cx).text_snapshot());
 2755            } else {
 2756                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2757            };
 2758
 2759            let found_snapshot = snapshots
 2760                    .binary_search_by_key(&version, |e| e.version)
 2761                    .map(|ix| snapshots[ix].snapshot.clone())
 2762                    .map_err(|_| {
 2763                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2764                    })?;
 2765
 2766            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2767            Ok(found_snapshot)
 2768        } else {
 2769            Ok((buffer.read(cx)).text_snapshot())
 2770        }
 2771    }
 2772
 2773    async fn get_server_code_actions_from_action_kinds(
 2774        lsp_store: &WeakEntity<LspStore>,
 2775        language_server_id: LanguageServerId,
 2776        code_action_kinds: Vec<lsp::CodeActionKind>,
 2777        buffer: &Entity<Buffer>,
 2778        cx: &mut AsyncApp,
 2779    ) -> Result<Vec<CodeAction>> {
 2780        let actions = lsp_store
 2781            .update(cx, move |this, cx| {
 2782                let request = GetCodeActions {
 2783                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2784                    kinds: Some(code_action_kinds),
 2785                };
 2786                let server = LanguageServerToQuery::Other(language_server_id);
 2787                this.request_lsp(buffer.clone(), server, request, cx)
 2788            })?
 2789            .await?;
 2790        Ok(actions)
 2791    }
 2792
 2793    pub async fn execute_code_actions_on_server(
 2794        lsp_store: &WeakEntity<LspStore>,
 2795        language_server: &Arc<LanguageServer>,
 2796
 2797        actions: Vec<CodeAction>,
 2798        push_to_history: bool,
 2799        project_transaction: &mut ProjectTransaction,
 2800        cx: &mut AsyncApp,
 2801    ) -> anyhow::Result<()> {
 2802        for mut action in actions {
 2803            Self::try_resolve_code_action(language_server, &mut action)
 2804                .await
 2805                .context("resolving a formatting code action")?;
 2806
 2807            if let Some(edit) = action.lsp_action.edit() {
 2808                if edit.changes.is_none() && edit.document_changes.is_none() {
 2809                    continue;
 2810                }
 2811
 2812                let new = Self::deserialize_workspace_edit(
 2813                    lsp_store.upgrade().context("project dropped")?,
 2814                    edit.clone(),
 2815                    push_to_history,
 2816                    language_server.clone(),
 2817                    cx,
 2818                )
 2819                .await?;
 2820                project_transaction.0.extend(new.0);
 2821            }
 2822
 2823            if let Some(command) = action.lsp_action.command() {
 2824                let server_capabilities = language_server.capabilities();
 2825                let available_commands = server_capabilities
 2826                    .execute_command_provider
 2827                    .as_ref()
 2828                    .map(|options| options.commands.as_slice())
 2829                    .unwrap_or_default();
 2830                if available_commands.contains(&command.command) {
 2831                    lsp_store.update(cx, |lsp_store, _| {
 2832                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2833                            mode.last_workspace_edits_by_language_server
 2834                                .remove(&language_server.server_id());
 2835                        }
 2836                    })?;
 2837
 2838                    language_server
 2839                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2840                            command: command.command.clone(),
 2841                            arguments: command.arguments.clone().unwrap_or_default(),
 2842                            ..Default::default()
 2843                        })
 2844                        .await
 2845                        .into_response()
 2846                        .context("execute command")?;
 2847
 2848                    lsp_store.update(cx, |this, _| {
 2849                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2850                            project_transaction.0.extend(
 2851                                mode.last_workspace_edits_by_language_server
 2852                                    .remove(&language_server.server_id())
 2853                                    .unwrap_or_default()
 2854                                    .0,
 2855                            )
 2856                        }
 2857                    })?;
 2858                } else {
 2859                    log::warn!(
 2860                        "Cannot execute a command {} not listed in the language server capabilities",
 2861                        command.command
 2862                    )
 2863                }
 2864            }
 2865        }
 2866        Ok(())
 2867    }
 2868
 2869    pub async fn deserialize_text_edits(
 2870        this: Entity<LspStore>,
 2871        buffer_to_edit: Entity<Buffer>,
 2872        edits: Vec<lsp::TextEdit>,
 2873        push_to_history: bool,
 2874        _: Arc<CachedLspAdapter>,
 2875        language_server: Arc<LanguageServer>,
 2876        cx: &mut AsyncApp,
 2877    ) -> Result<Option<Transaction>> {
 2878        let edits = this
 2879            .update(cx, |this, cx| {
 2880                this.as_local_mut().unwrap().edits_from_lsp(
 2881                    &buffer_to_edit,
 2882                    edits,
 2883                    language_server.server_id(),
 2884                    None,
 2885                    cx,
 2886                )
 2887            })?
 2888            .await?;
 2889
 2890        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2891            buffer.finalize_last_transaction();
 2892            buffer.start_transaction();
 2893            for (range, text) in edits {
 2894                buffer.edit([(range, text)], None, cx);
 2895            }
 2896
 2897            if buffer.end_transaction(cx).is_some() {
 2898                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2899                if !push_to_history {
 2900                    buffer.forget_transaction(transaction.id);
 2901                }
 2902                Some(transaction)
 2903            } else {
 2904                None
 2905            }
 2906        })?;
 2907
 2908        Ok(transaction)
 2909    }
 2910
 2911    #[allow(clippy::type_complexity)]
 2912    pub(crate) fn edits_from_lsp(
 2913        &mut self,
 2914        buffer: &Entity<Buffer>,
 2915        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2916        server_id: LanguageServerId,
 2917        version: Option<i32>,
 2918        cx: &mut Context<LspStore>,
 2919    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2920        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2921        cx.background_spawn(async move {
 2922            let snapshot = snapshot?;
 2923            let mut lsp_edits = lsp_edits
 2924                .into_iter()
 2925                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2926                .collect::<Vec<_>>();
 2927
 2928            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2929
 2930            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2931            let mut edits = Vec::new();
 2932            while let Some((range, mut new_text)) = lsp_edits.next() {
 2933                // Clip invalid ranges provided by the language server.
 2934                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2935                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2936
 2937                // Combine any LSP edits that are adjacent.
 2938                //
 2939                // Also, combine LSP edits that are separated from each other by only
 2940                // a newline. This is important because for some code actions,
 2941                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2942                // are separated by unchanged newline characters.
 2943                //
 2944                // In order for the diffing logic below to work properly, any edits that
 2945                // cancel each other out must be combined into one.
 2946                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2947                    if next_range.start.0 > range.end {
 2948                        if next_range.start.0.row > range.end.row + 1
 2949                            || next_range.start.0.column > 0
 2950                            || snapshot.clip_point_utf16(
 2951                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2952                                Bias::Left,
 2953                            ) > range.end
 2954                        {
 2955                            break;
 2956                        }
 2957                        new_text.push('\n');
 2958                    }
 2959                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2960                    new_text.push_str(next_text);
 2961                    lsp_edits.next();
 2962                }
 2963
 2964                // For multiline edits, perform a diff of the old and new text so that
 2965                // we can identify the changes more precisely, preserving the locations
 2966                // of any anchors positioned in the unchanged regions.
 2967                if range.end.row > range.start.row {
 2968                    let offset = range.start.to_offset(&snapshot);
 2969                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2970                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2971                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2972                        (
 2973                            snapshot.anchor_after(offset + range.start)
 2974                                ..snapshot.anchor_before(offset + range.end),
 2975                            replacement,
 2976                        )
 2977                    }));
 2978                } else if range.end == range.start {
 2979                    let anchor = snapshot.anchor_after(range.start);
 2980                    edits.push((anchor..anchor, new_text.into()));
 2981                } else {
 2982                    let edit_start = snapshot.anchor_after(range.start);
 2983                    let edit_end = snapshot.anchor_before(range.end);
 2984                    edits.push((edit_start..edit_end, new_text.into()));
 2985                }
 2986            }
 2987
 2988            Ok(edits)
 2989        })
 2990    }
 2991
 2992    pub(crate) async fn deserialize_workspace_edit(
 2993        this: Entity<LspStore>,
 2994        edit: lsp::WorkspaceEdit,
 2995        push_to_history: bool,
 2996        language_server: Arc<LanguageServer>,
 2997        cx: &mut AsyncApp,
 2998    ) -> Result<ProjectTransaction> {
 2999        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3000
 3001        let mut operations = Vec::new();
 3002        if let Some(document_changes) = edit.document_changes {
 3003            match document_changes {
 3004                lsp::DocumentChanges::Edits(edits) => {
 3005                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3006                }
 3007                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3008            }
 3009        } else if let Some(changes) = edit.changes {
 3010            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3011                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3012                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3013                        uri,
 3014                        version: None,
 3015                    },
 3016                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3017                })
 3018            }));
 3019        }
 3020
 3021        let mut project_transaction = ProjectTransaction::default();
 3022        for operation in operations {
 3023            match operation {
 3024                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3025                    let abs_path = op
 3026                        .uri
 3027                        .to_file_path()
 3028                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3029
 3030                    if let Some(parent_path) = abs_path.parent() {
 3031                        fs.create_dir(parent_path).await?;
 3032                    }
 3033                    if abs_path.ends_with("/") {
 3034                        fs.create_dir(&abs_path).await?;
 3035                    } else {
 3036                        fs.create_file(
 3037                            &abs_path,
 3038                            op.options
 3039                                .map(|options| fs::CreateOptions {
 3040                                    overwrite: options.overwrite.unwrap_or(false),
 3041                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3042                                })
 3043                                .unwrap_or_default(),
 3044                        )
 3045                        .await?;
 3046                    }
 3047                }
 3048
 3049                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3050                    let source_abs_path = op
 3051                        .old_uri
 3052                        .to_file_path()
 3053                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3054                    let target_abs_path = op
 3055                        .new_uri
 3056                        .to_file_path()
 3057                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3058
 3059                    let options = fs::RenameOptions {
 3060                        overwrite: op
 3061                            .options
 3062                            .as_ref()
 3063                            .and_then(|options| options.overwrite)
 3064                            .unwrap_or(false),
 3065                        ignore_if_exists: op
 3066                            .options
 3067                            .as_ref()
 3068                            .and_then(|options| options.ignore_if_exists)
 3069                            .unwrap_or(false),
 3070                        create_parents: true,
 3071                    };
 3072
 3073                    fs.rename(&source_abs_path, &target_abs_path, options)
 3074                        .await?;
 3075                }
 3076
 3077                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3078                    let abs_path = op
 3079                        .uri
 3080                        .to_file_path()
 3081                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3082                    let options = op
 3083                        .options
 3084                        .map(|options| fs::RemoveOptions {
 3085                            recursive: options.recursive.unwrap_or(false),
 3086                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3087                        })
 3088                        .unwrap_or_default();
 3089                    if abs_path.ends_with("/") {
 3090                        fs.remove_dir(&abs_path, options).await?;
 3091                    } else {
 3092                        fs.remove_file(&abs_path, options).await?;
 3093                    }
 3094                }
 3095
 3096                lsp::DocumentChangeOperation::Edit(op) => {
 3097                    let buffer_to_edit = this
 3098                        .update(cx, |this, cx| {
 3099                            this.open_local_buffer_via_lsp(
 3100                                op.text_document.uri.clone(),
 3101                                language_server.server_id(),
 3102                                cx,
 3103                            )
 3104                        })?
 3105                        .await?;
 3106
 3107                    let edits = this
 3108                        .update(cx, |this, cx| {
 3109                            let path = buffer_to_edit.read(cx).project_path(cx);
 3110                            let active_entry = this.active_entry;
 3111                            let is_active_entry = path.is_some_and(|project_path| {
 3112                                this.worktree_store
 3113                                    .read(cx)
 3114                                    .entry_for_path(&project_path, cx)
 3115                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3116                            });
 3117                            let local = this.as_local_mut().unwrap();
 3118
 3119                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3120                            for edit in op.edits {
 3121                                match edit {
 3122                                    Edit::Plain(edit) => {
 3123                                        if !edits.contains(&edit) {
 3124                                            edits.push(edit)
 3125                                        }
 3126                                    }
 3127                                    Edit::Annotated(edit) => {
 3128                                        if !edits.contains(&edit.text_edit) {
 3129                                            edits.push(edit.text_edit)
 3130                                        }
 3131                                    }
 3132                                    Edit::Snippet(edit) => {
 3133                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3134                                        else {
 3135                                            continue;
 3136                                        };
 3137
 3138                                        if is_active_entry {
 3139                                            snippet_edits.push((edit.range, snippet));
 3140                                        } else {
 3141                                            // Since this buffer is not focused, apply a normal edit.
 3142                                            let new_edit = TextEdit {
 3143                                                range: edit.range,
 3144                                                new_text: snippet.text,
 3145                                            };
 3146                                            if !edits.contains(&new_edit) {
 3147                                                edits.push(new_edit);
 3148                                            }
 3149                                        }
 3150                                    }
 3151                                }
 3152                            }
 3153                            if !snippet_edits.is_empty() {
 3154                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3155                                let version = if let Some(buffer_version) = op.text_document.version
 3156                                {
 3157                                    local
 3158                                        .buffer_snapshot_for_lsp_version(
 3159                                            &buffer_to_edit,
 3160                                            language_server.server_id(),
 3161                                            Some(buffer_version),
 3162                                            cx,
 3163                                        )
 3164                                        .ok()
 3165                                        .map(|snapshot| snapshot.version)
 3166                                } else {
 3167                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3168                                };
 3169
 3170                                let most_recent_edit =
 3171                                    version.and_then(|version| version.most_recent());
 3172                                // Check if the edit that triggered that edit has been made by this participant.
 3173
 3174                                if let Some(most_recent_edit) = most_recent_edit {
 3175                                    cx.emit(LspStoreEvent::SnippetEdit {
 3176                                        buffer_id,
 3177                                        edits: snippet_edits,
 3178                                        most_recent_edit,
 3179                                    });
 3180                                }
 3181                            }
 3182
 3183                            local.edits_from_lsp(
 3184                                &buffer_to_edit,
 3185                                edits,
 3186                                language_server.server_id(),
 3187                                op.text_document.version,
 3188                                cx,
 3189                            )
 3190                        })?
 3191                        .await?;
 3192
 3193                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3194                        buffer.finalize_last_transaction();
 3195                        buffer.start_transaction();
 3196                        for (range, text) in edits {
 3197                            buffer.edit([(range, text)], None, cx);
 3198                        }
 3199
 3200                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3201                            if push_to_history {
 3202                                buffer.finalize_last_transaction();
 3203                                buffer.get_transaction(transaction_id).cloned()
 3204                            } else {
 3205                                buffer.forget_transaction(transaction_id)
 3206                            }
 3207                        })
 3208                    })?;
 3209                    if let Some(transaction) = transaction {
 3210                        project_transaction.0.insert(buffer_to_edit, transaction);
 3211                    }
 3212                }
 3213            }
 3214        }
 3215
 3216        Ok(project_transaction)
 3217    }
 3218
 3219    async fn on_lsp_workspace_edit(
 3220        this: WeakEntity<LspStore>,
 3221        params: lsp::ApplyWorkspaceEditParams,
 3222        server_id: LanguageServerId,
 3223        cx: &mut AsyncApp,
 3224    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3225        let this = this.upgrade().context("project project closed")?;
 3226        let language_server = this
 3227            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3228            .context("language server not found")?;
 3229        let transaction = Self::deserialize_workspace_edit(
 3230            this.clone(),
 3231            params.edit,
 3232            true,
 3233            language_server.clone(),
 3234            cx,
 3235        )
 3236        .await
 3237        .log_err();
 3238        this.update(cx, |this, _| {
 3239            if let Some(transaction) = transaction {
 3240                this.as_local_mut()
 3241                    .unwrap()
 3242                    .last_workspace_edits_by_language_server
 3243                    .insert(server_id, transaction);
 3244            }
 3245        })?;
 3246        Ok(lsp::ApplyWorkspaceEditResponse {
 3247            applied: true,
 3248            failed_change: None,
 3249            failure_reason: None,
 3250        })
 3251    }
 3252
 3253    fn remove_worktree(
 3254        &mut self,
 3255        id_to_remove: WorktreeId,
 3256        cx: &mut Context<LspStore>,
 3257    ) -> Vec<LanguageServerId> {
 3258        self.diagnostics.remove(&id_to_remove);
 3259        self.prettier_store.update(cx, |prettier_store, cx| {
 3260            prettier_store.remove_worktree(id_to_remove, cx);
 3261        });
 3262
 3263        let mut servers_to_remove = BTreeSet::default();
 3264        let mut servers_to_preserve = HashSet::default();
 3265        for (seed, state) in &self.language_server_ids {
 3266            if seed.worktree_id == id_to_remove {
 3267                servers_to_remove.insert(state.id);
 3268            } else {
 3269                servers_to_preserve.insert(state.id);
 3270            }
 3271        }
 3272        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3273        self.language_server_ids
 3274            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3275        for server_id_to_remove in &servers_to_remove {
 3276            self.language_server_watched_paths
 3277                .remove(server_id_to_remove);
 3278            self.language_server_paths_watched_for_rename
 3279                .remove(server_id_to_remove);
 3280            self.last_workspace_edits_by_language_server
 3281                .remove(server_id_to_remove);
 3282            self.language_servers.remove(server_id_to_remove);
 3283            self.buffer_pull_diagnostics_result_ids
 3284                .remove(server_id_to_remove);
 3285            self.workspace_pull_diagnostics_result_ids
 3286                .remove(server_id_to_remove);
 3287            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3288                buffer_servers.remove(server_id_to_remove);
 3289            }
 3290            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3291        }
 3292        servers_to_remove.into_iter().collect()
 3293    }
 3294
 3295    fn rebuild_watched_paths_inner<'a>(
 3296        &'a self,
 3297        language_server_id: LanguageServerId,
 3298        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3299        cx: &mut Context<LspStore>,
 3300    ) -> LanguageServerWatchedPathsBuilder {
 3301        let worktrees = self
 3302            .worktree_store
 3303            .read(cx)
 3304            .worktrees()
 3305            .filter_map(|worktree| {
 3306                self.language_servers_for_worktree(worktree.read(cx).id())
 3307                    .find(|server| server.server_id() == language_server_id)
 3308                    .map(|_| worktree)
 3309            })
 3310            .collect::<Vec<_>>();
 3311
 3312        let mut worktree_globs = HashMap::default();
 3313        let mut abs_globs = HashMap::default();
 3314        log::trace!(
 3315            "Processing new watcher paths for language server with id {}",
 3316            language_server_id
 3317        );
 3318
 3319        for watcher in watchers {
 3320            if let Some((worktree, literal_prefix, pattern)) =
 3321                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3322            {
 3323                worktree.update(cx, |worktree, _| {
 3324                    if let Some((tree, glob)) =
 3325                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3326                    {
 3327                        tree.add_path_prefix_to_scan(literal_prefix);
 3328                        worktree_globs
 3329                            .entry(tree.id())
 3330                            .or_insert_with(GlobSetBuilder::new)
 3331                            .add(glob);
 3332                    }
 3333                });
 3334            } else {
 3335                let (path, pattern) = match &watcher.glob_pattern {
 3336                    lsp::GlobPattern::String(s) => {
 3337                        let watcher_path = SanitizedPath::new(s);
 3338                        let path = glob_literal_prefix(watcher_path.as_path());
 3339                        let pattern = watcher_path
 3340                            .as_path()
 3341                            .strip_prefix(&path)
 3342                            .map(|p| p.to_string_lossy().into_owned())
 3343                            .unwrap_or_else(|e| {
 3344                                debug_panic!(
 3345                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3346                                    s,
 3347                                    path.display(),
 3348                                    e
 3349                                );
 3350                                watcher_path.as_path().to_string_lossy().into_owned()
 3351                            });
 3352                        (path, pattern)
 3353                    }
 3354                    lsp::GlobPattern::Relative(rp) => {
 3355                        let Ok(mut base_uri) = match &rp.base_uri {
 3356                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3357                            lsp::OneOf::Right(base_uri) => base_uri,
 3358                        }
 3359                        .to_file_path() else {
 3360                            continue;
 3361                        };
 3362
 3363                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3364                        let pattern = Path::new(&rp.pattern)
 3365                            .strip_prefix(&path)
 3366                            .map(|p| p.to_string_lossy().into_owned())
 3367                            .unwrap_or_else(|e| {
 3368                                debug_panic!(
 3369                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3370                                    rp.pattern,
 3371                                    path.display(),
 3372                                    e
 3373                                );
 3374                                rp.pattern.clone()
 3375                            });
 3376                        base_uri.push(path);
 3377                        (base_uri, pattern)
 3378                    }
 3379                };
 3380
 3381                if let Some(glob) = Glob::new(&pattern).log_err() {
 3382                    if !path
 3383                        .components()
 3384                        .any(|c| matches!(c, path::Component::Normal(_)))
 3385                    {
 3386                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3387                        // rather than adding a new watcher for `/`.
 3388                        for worktree in &worktrees {
 3389                            worktree_globs
 3390                                .entry(worktree.read(cx).id())
 3391                                .or_insert_with(GlobSetBuilder::new)
 3392                                .add(glob.clone());
 3393                        }
 3394                    } else {
 3395                        abs_globs
 3396                            .entry(path.into())
 3397                            .or_insert_with(GlobSetBuilder::new)
 3398                            .add(glob);
 3399                    }
 3400                }
 3401            }
 3402        }
 3403
 3404        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3405        for (worktree_id, builder) in worktree_globs {
 3406            if let Ok(globset) = builder.build() {
 3407                watch_builder.watch_worktree(worktree_id, globset);
 3408            }
 3409        }
 3410        for (abs_path, builder) in abs_globs {
 3411            if let Ok(globset) = builder.build() {
 3412                watch_builder.watch_abs_path(abs_path, globset);
 3413            }
 3414        }
 3415        watch_builder
 3416    }
 3417
 3418    fn worktree_and_path_for_file_watcher(
 3419        worktrees: &[Entity<Worktree>],
 3420        watcher: &FileSystemWatcher,
 3421        cx: &App,
 3422    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3423        worktrees.iter().find_map(|worktree| {
 3424            let tree = worktree.read(cx);
 3425            let worktree_root_path = tree.abs_path();
 3426            let path_style = tree.path_style();
 3427            match &watcher.glob_pattern {
 3428                lsp::GlobPattern::String(s) => {
 3429                    let watcher_path = SanitizedPath::new(s);
 3430                    let relative = watcher_path
 3431                        .as_path()
 3432                        .strip_prefix(&worktree_root_path)
 3433                        .ok()?;
 3434                    let literal_prefix = glob_literal_prefix(relative);
 3435                    Some((
 3436                        worktree.clone(),
 3437                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3438                        relative.to_string_lossy().into_owned(),
 3439                    ))
 3440                }
 3441                lsp::GlobPattern::Relative(rp) => {
 3442                    let base_uri = match &rp.base_uri {
 3443                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3444                        lsp::OneOf::Right(base_uri) => base_uri,
 3445                    }
 3446                    .to_file_path()
 3447                    .ok()?;
 3448                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3449                    let mut literal_prefix = relative.to_owned();
 3450                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3451                    Some((
 3452                        worktree.clone(),
 3453                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3454                        rp.pattern.clone(),
 3455                    ))
 3456                }
 3457            }
 3458        })
 3459    }
 3460
 3461    fn rebuild_watched_paths(
 3462        &mut self,
 3463        language_server_id: LanguageServerId,
 3464        cx: &mut Context<LspStore>,
 3465    ) {
 3466        let Some(registrations) = self
 3467            .language_server_dynamic_registrations
 3468            .get(&language_server_id)
 3469        else {
 3470            return;
 3471        };
 3472
 3473        let watch_builder = self.rebuild_watched_paths_inner(
 3474            language_server_id,
 3475            registrations.did_change_watched_files.values().flatten(),
 3476            cx,
 3477        );
 3478        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3479        self.language_server_watched_paths
 3480            .insert(language_server_id, watcher);
 3481
 3482        cx.notify();
 3483    }
 3484
 3485    fn on_lsp_did_change_watched_files(
 3486        &mut self,
 3487        language_server_id: LanguageServerId,
 3488        registration_id: &str,
 3489        params: DidChangeWatchedFilesRegistrationOptions,
 3490        cx: &mut Context<LspStore>,
 3491    ) {
 3492        let registrations = self
 3493            .language_server_dynamic_registrations
 3494            .entry(language_server_id)
 3495            .or_default();
 3496
 3497        registrations
 3498            .did_change_watched_files
 3499            .insert(registration_id.to_string(), params.watchers);
 3500
 3501        self.rebuild_watched_paths(language_server_id, cx);
 3502    }
 3503
 3504    fn on_lsp_unregister_did_change_watched_files(
 3505        &mut self,
 3506        language_server_id: LanguageServerId,
 3507        registration_id: &str,
 3508        cx: &mut Context<LspStore>,
 3509    ) {
 3510        let registrations = self
 3511            .language_server_dynamic_registrations
 3512            .entry(language_server_id)
 3513            .or_default();
 3514
 3515        if registrations
 3516            .did_change_watched_files
 3517            .remove(registration_id)
 3518            .is_some()
 3519        {
 3520            log::info!(
 3521                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3522                language_server_id,
 3523                registration_id
 3524            );
 3525        } else {
 3526            log::warn!(
 3527                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3528                language_server_id,
 3529                registration_id
 3530            );
 3531        }
 3532
 3533        self.rebuild_watched_paths(language_server_id, cx);
 3534    }
 3535
 3536    async fn initialization_options_for_adapter(
 3537        adapter: Arc<dyn LspAdapter>,
 3538        delegate: &Arc<dyn LspAdapterDelegate>,
 3539    ) -> Result<Option<serde_json::Value>> {
 3540        let Some(mut initialization_config) =
 3541            adapter.clone().initialization_options(delegate).await?
 3542        else {
 3543            return Ok(None);
 3544        };
 3545
 3546        for other_adapter in delegate.registered_lsp_adapters() {
 3547            if other_adapter.name() == adapter.name() {
 3548                continue;
 3549            }
 3550            if let Ok(Some(target_config)) = other_adapter
 3551                .clone()
 3552                .additional_initialization_options(adapter.name(), delegate)
 3553                .await
 3554            {
 3555                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3556            }
 3557        }
 3558
 3559        Ok(Some(initialization_config))
 3560    }
 3561
 3562    async fn workspace_configuration_for_adapter(
 3563        adapter: Arc<dyn LspAdapter>,
 3564        delegate: &Arc<dyn LspAdapterDelegate>,
 3565        toolchain: Option<Toolchain>,
 3566        requested_uri: Option<Uri>,
 3567        cx: &mut AsyncApp,
 3568    ) -> Result<serde_json::Value> {
 3569        let mut workspace_config = adapter
 3570            .clone()
 3571            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3572            .await?;
 3573
 3574        for other_adapter in delegate.registered_lsp_adapters() {
 3575            if other_adapter.name() == adapter.name() {
 3576                continue;
 3577            }
 3578            if let Ok(Some(target_config)) = other_adapter
 3579                .clone()
 3580                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3581                .await
 3582            {
 3583                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3584            }
 3585        }
 3586
 3587        Ok(workspace_config)
 3588    }
 3589
 3590    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3591        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3592            Some(server.clone())
 3593        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3594            Some(Arc::clone(server))
 3595        } else {
 3596            None
 3597        }
 3598    }
 3599}
 3600
 3601fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3602    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3603        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3604            language_server_id: server.server_id(),
 3605            name: Some(server.name()),
 3606            message: proto::update_language_server::Variant::MetadataUpdated(
 3607                proto::ServerMetadataUpdated {
 3608                    capabilities: Some(capabilities),
 3609                    binary: Some(proto::LanguageServerBinaryInfo {
 3610                        path: server.binary().path.to_string_lossy().into_owned(),
 3611                        arguments: server
 3612                            .binary()
 3613                            .arguments
 3614                            .iter()
 3615                            .map(|arg| arg.to_string_lossy().into_owned())
 3616                            .collect(),
 3617                    }),
 3618                    configuration: serde_json::to_string(server.configuration()).ok(),
 3619                    workspace_folders: server
 3620                        .workspace_folders()
 3621                        .iter()
 3622                        .map(|uri| uri.to_string())
 3623                        .collect(),
 3624                },
 3625            ),
 3626        });
 3627    }
 3628}
 3629
 3630#[derive(Debug)]
 3631pub struct FormattableBuffer {
 3632    handle: Entity<Buffer>,
 3633    abs_path: Option<PathBuf>,
 3634    env: Option<HashMap<String, String>>,
 3635    ranges: Option<Vec<Range<Anchor>>>,
 3636}
 3637
 3638pub struct RemoteLspStore {
 3639    upstream_client: Option<AnyProtoClient>,
 3640    upstream_project_id: u64,
 3641}
 3642
 3643pub(crate) enum LspStoreMode {
 3644    Local(LocalLspStore),   // ssh host and collab host
 3645    Remote(RemoteLspStore), // collab guest
 3646}
 3647
 3648impl LspStoreMode {
 3649    fn is_local(&self) -> bool {
 3650        matches!(self, LspStoreMode::Local(_))
 3651    }
 3652}
 3653
 3654pub struct LspStore {
 3655    mode: LspStoreMode,
 3656    last_formatting_failure: Option<String>,
 3657    downstream_client: Option<(AnyProtoClient, u64)>,
 3658    nonce: u128,
 3659    buffer_store: Entity<BufferStore>,
 3660    worktree_store: Entity<WorktreeStore>,
 3661    pub languages: Arc<LanguageRegistry>,
 3662    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3663    active_entry: Option<ProjectEntryId>,
 3664    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3665    _maintain_buffer_languages: Task<()>,
 3666    diagnostic_summaries:
 3667        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3668    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3669    lsp_data: HashMap<BufferId, BufferLspData>,
 3670    next_hint_id: Arc<AtomicUsize>,
 3671}
 3672
 3673#[derive(Debug)]
 3674pub struct BufferLspData {
 3675    buffer_version: Global,
 3676    document_colors: Option<DocumentColorData>,
 3677    code_lens: Option<CodeLensData>,
 3678    inlay_hints: BufferInlayHints,
 3679    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3680    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3681}
 3682
 3683#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3684struct LspKey {
 3685    request_type: TypeId,
 3686    server_queried: Option<LanguageServerId>,
 3687}
 3688
 3689impl BufferLspData {
 3690    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3691        Self {
 3692            buffer_version: buffer.read(cx).version(),
 3693            document_colors: None,
 3694            code_lens: None,
 3695            inlay_hints: BufferInlayHints::new(buffer, cx),
 3696            lsp_requests: HashMap::default(),
 3697            chunk_lsp_requests: HashMap::default(),
 3698        }
 3699    }
 3700
 3701    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3702        if let Some(document_colors) = &mut self.document_colors {
 3703            document_colors.colors.remove(&for_server);
 3704            document_colors.cache_version += 1;
 3705        }
 3706
 3707        if let Some(code_lens) = &mut self.code_lens {
 3708            code_lens.lens.remove(&for_server);
 3709        }
 3710
 3711        self.inlay_hints.remove_server_data(for_server);
 3712    }
 3713
 3714    #[cfg(any(test, feature = "test-support"))]
 3715    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3716        &self.inlay_hints
 3717    }
 3718}
 3719
 3720#[derive(Debug, Default, Clone)]
 3721pub struct DocumentColors {
 3722    pub colors: HashSet<DocumentColor>,
 3723    pub cache_version: Option<usize>,
 3724}
 3725
 3726type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3727type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3728
 3729#[derive(Debug, Default)]
 3730struct DocumentColorData {
 3731    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3732    cache_version: usize,
 3733    colors_update: Option<(Global, DocumentColorTask)>,
 3734}
 3735
 3736#[derive(Debug, Default)]
 3737struct CodeLensData {
 3738    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3739    update: Option<(Global, CodeLensTask)>,
 3740}
 3741
 3742#[derive(Debug)]
 3743pub enum LspStoreEvent {
 3744    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3745    LanguageServerRemoved(LanguageServerId),
 3746    LanguageServerUpdate {
 3747        language_server_id: LanguageServerId,
 3748        name: Option<LanguageServerName>,
 3749        message: proto::update_language_server::Variant,
 3750    },
 3751    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3752    LanguageServerPrompt(LanguageServerPromptRequest),
 3753    LanguageDetected {
 3754        buffer: Entity<Buffer>,
 3755        new_language: Option<Arc<Language>>,
 3756    },
 3757    Notification(String),
 3758    RefreshInlayHints {
 3759        server_id: LanguageServerId,
 3760        request_id: Option<usize>,
 3761    },
 3762    RefreshCodeLens,
 3763    DiagnosticsUpdated {
 3764        server_id: LanguageServerId,
 3765        paths: Vec<ProjectPath>,
 3766    },
 3767    DiskBasedDiagnosticsStarted {
 3768        language_server_id: LanguageServerId,
 3769    },
 3770    DiskBasedDiagnosticsFinished {
 3771        language_server_id: LanguageServerId,
 3772    },
 3773    SnippetEdit {
 3774        buffer_id: BufferId,
 3775        edits: Vec<(lsp::Range, Snippet)>,
 3776        most_recent_edit: clock::Lamport,
 3777    },
 3778}
 3779
 3780#[derive(Clone, Debug, Serialize)]
 3781pub struct LanguageServerStatus {
 3782    pub name: LanguageServerName,
 3783    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3784    pub has_pending_diagnostic_updates: bool,
 3785    pub progress_tokens: HashSet<ProgressToken>,
 3786    pub worktree: Option<WorktreeId>,
 3787    pub binary: Option<LanguageServerBinary>,
 3788    pub configuration: Option<Value>,
 3789    pub workspace_folders: BTreeSet<Uri>,
 3790}
 3791
 3792#[derive(Clone, Debug)]
 3793struct CoreSymbol {
 3794    pub language_server_name: LanguageServerName,
 3795    pub source_worktree_id: WorktreeId,
 3796    pub source_language_server_id: LanguageServerId,
 3797    pub path: SymbolLocation,
 3798    pub name: String,
 3799    pub kind: lsp::SymbolKind,
 3800    pub range: Range<Unclipped<PointUtf16>>,
 3801}
 3802
 3803#[derive(Clone, Debug, PartialEq, Eq)]
 3804pub enum SymbolLocation {
 3805    InProject(ProjectPath),
 3806    OutsideProject {
 3807        abs_path: Arc<Path>,
 3808        signature: [u8; 32],
 3809    },
 3810}
 3811
 3812impl SymbolLocation {
 3813    fn file_name(&self) -> Option<&str> {
 3814        match self {
 3815            Self::InProject(path) => path.path.file_name(),
 3816            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3817        }
 3818    }
 3819}
 3820
 3821impl LspStore {
 3822    pub fn init(client: &AnyProtoClient) {
 3823        client.add_entity_request_handler(Self::handle_lsp_query);
 3824        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3825        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3826        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3827        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3828        client.add_entity_message_handler(Self::handle_start_language_server);
 3829        client.add_entity_message_handler(Self::handle_update_language_server);
 3830        client.add_entity_message_handler(Self::handle_language_server_log);
 3831        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3832        client.add_entity_request_handler(Self::handle_format_buffers);
 3833        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3834        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3835        client.add_entity_request_handler(Self::handle_apply_code_action);
 3836        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3837        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3838        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3839        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3840        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3841        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3842        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3843        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3844        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3845        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3846        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3847        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3848        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3849        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3850        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3851        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3852        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3853
 3854        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3855        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3856        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3857        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3858        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3859        client.add_entity_request_handler(
 3860            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3861        );
 3862        client.add_entity_request_handler(
 3863            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3864        );
 3865        client.add_entity_request_handler(
 3866            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3867        );
 3868    }
 3869
 3870    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3871        match &self.mode {
 3872            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3873            _ => None,
 3874        }
 3875    }
 3876
 3877    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3878        match &self.mode {
 3879            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3880            _ => None,
 3881        }
 3882    }
 3883
 3884    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3885        match &mut self.mode {
 3886            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3887            _ => None,
 3888        }
 3889    }
 3890
 3891    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3892        match &self.mode {
 3893            LspStoreMode::Remote(RemoteLspStore {
 3894                upstream_client: Some(upstream_client),
 3895                upstream_project_id,
 3896                ..
 3897            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3898
 3899            LspStoreMode::Remote(RemoteLspStore {
 3900                upstream_client: None,
 3901                ..
 3902            }) => None,
 3903            LspStoreMode::Local(_) => None,
 3904        }
 3905    }
 3906
 3907    pub fn new_local(
 3908        buffer_store: Entity<BufferStore>,
 3909        worktree_store: Entity<WorktreeStore>,
 3910        prettier_store: Entity<PrettierStore>,
 3911        toolchain_store: Entity<LocalToolchainStore>,
 3912        environment: Entity<ProjectEnvironment>,
 3913        manifest_tree: Entity<ManifestTree>,
 3914        languages: Arc<LanguageRegistry>,
 3915        http_client: Arc<dyn HttpClient>,
 3916        fs: Arc<dyn Fs>,
 3917        cx: &mut Context<Self>,
 3918    ) -> Self {
 3919        let yarn = YarnPathStore::new(fs.clone(), cx);
 3920        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3921            .detach();
 3922        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3923            .detach();
 3924        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3925            .detach();
 3926        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3927            .detach();
 3928        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3929            .detach();
 3930        subscribe_to_binary_statuses(&languages, cx).detach();
 3931
 3932        let _maintain_workspace_config = {
 3933            let (sender, receiver) = watch::channel();
 3934            (Self::maintain_workspace_config(receiver, cx), sender)
 3935        };
 3936
 3937        Self {
 3938            mode: LspStoreMode::Local(LocalLspStore {
 3939                weak: cx.weak_entity(),
 3940                worktree_store: worktree_store.clone(),
 3941
 3942                supplementary_language_servers: Default::default(),
 3943                languages: languages.clone(),
 3944                language_server_ids: Default::default(),
 3945                language_servers: Default::default(),
 3946                last_workspace_edits_by_language_server: Default::default(),
 3947                language_server_watched_paths: Default::default(),
 3948                language_server_paths_watched_for_rename: Default::default(),
 3949                language_server_dynamic_registrations: Default::default(),
 3950                buffers_being_formatted: Default::default(),
 3951                buffer_snapshots: Default::default(),
 3952                prettier_store,
 3953                environment,
 3954                http_client,
 3955                fs,
 3956                yarn,
 3957                next_diagnostic_group_id: Default::default(),
 3958                diagnostics: Default::default(),
 3959                _subscription: cx.on_app_quit(|this, cx| {
 3960                    this.as_local_mut()
 3961                        .unwrap()
 3962                        .shutdown_language_servers_on_quit(cx)
 3963                }),
 3964                lsp_tree: LanguageServerTree::new(
 3965                    manifest_tree,
 3966                    languages.clone(),
 3967                    toolchain_store.clone(),
 3968                ),
 3969                toolchain_store,
 3970                registered_buffers: HashMap::default(),
 3971                buffers_opened_in_servers: HashMap::default(),
 3972                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3973                workspace_pull_diagnostics_result_ids: HashMap::default(),
 3974                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3975                    .manifest_file_names(),
 3976            }),
 3977            last_formatting_failure: None,
 3978            downstream_client: None,
 3979            buffer_store,
 3980            worktree_store,
 3981            languages: languages.clone(),
 3982            language_server_statuses: Default::default(),
 3983            nonce: StdRng::from_os_rng().random(),
 3984            diagnostic_summaries: HashMap::default(),
 3985            lsp_server_capabilities: HashMap::default(),
 3986            lsp_data: HashMap::default(),
 3987            next_hint_id: Arc::default(),
 3988            active_entry: None,
 3989            _maintain_workspace_config,
 3990            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3991        }
 3992    }
 3993
 3994    fn send_lsp_proto_request<R: LspCommand>(
 3995        &self,
 3996        buffer: Entity<Buffer>,
 3997        client: AnyProtoClient,
 3998        upstream_project_id: u64,
 3999        request: R,
 4000        cx: &mut Context<LspStore>,
 4001    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4002        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4003            return Task::ready(Ok(R::Response::default()));
 4004        }
 4005        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4006        cx.spawn(async move |this, cx| {
 4007            let response = client.request(message).await?;
 4008            let this = this.upgrade().context("project dropped")?;
 4009            request
 4010                .response_from_proto(response, this, buffer, cx.clone())
 4011                .await
 4012        })
 4013    }
 4014
 4015    pub(super) fn new_remote(
 4016        buffer_store: Entity<BufferStore>,
 4017        worktree_store: Entity<WorktreeStore>,
 4018        languages: Arc<LanguageRegistry>,
 4019        upstream_client: AnyProtoClient,
 4020        project_id: u64,
 4021        cx: &mut Context<Self>,
 4022    ) -> Self {
 4023        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4024            .detach();
 4025        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4026            .detach();
 4027        subscribe_to_binary_statuses(&languages, cx).detach();
 4028        let _maintain_workspace_config = {
 4029            let (sender, receiver) = watch::channel();
 4030            (Self::maintain_workspace_config(receiver, cx), sender)
 4031        };
 4032        Self {
 4033            mode: LspStoreMode::Remote(RemoteLspStore {
 4034                upstream_client: Some(upstream_client),
 4035                upstream_project_id: project_id,
 4036            }),
 4037            downstream_client: None,
 4038            last_formatting_failure: None,
 4039            buffer_store,
 4040            worktree_store,
 4041            languages: languages.clone(),
 4042            language_server_statuses: Default::default(),
 4043            nonce: StdRng::from_os_rng().random(),
 4044            diagnostic_summaries: HashMap::default(),
 4045            lsp_server_capabilities: HashMap::default(),
 4046            next_hint_id: Arc::default(),
 4047            lsp_data: HashMap::default(),
 4048            active_entry: None,
 4049
 4050            _maintain_workspace_config,
 4051            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4052        }
 4053    }
 4054
 4055    fn on_buffer_store_event(
 4056        &mut self,
 4057        _: Entity<BufferStore>,
 4058        event: &BufferStoreEvent,
 4059        cx: &mut Context<Self>,
 4060    ) {
 4061        match event {
 4062            BufferStoreEvent::BufferAdded(buffer) => {
 4063                self.on_buffer_added(buffer, cx).log_err();
 4064            }
 4065            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4066                let buffer_id = buffer.read(cx).remote_id();
 4067                if let Some(local) = self.as_local_mut()
 4068                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4069                {
 4070                    local.reset_buffer(buffer, old_file, cx);
 4071
 4072                    if local.registered_buffers.contains_key(&buffer_id) {
 4073                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4074                    }
 4075                }
 4076
 4077                self.detect_language_for_buffer(buffer, cx);
 4078                if let Some(local) = self.as_local_mut() {
 4079                    local.initialize_buffer(buffer, cx);
 4080                    if local.registered_buffers.contains_key(&buffer_id) {
 4081                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4082                    }
 4083                }
 4084            }
 4085            _ => {}
 4086        }
 4087    }
 4088
 4089    fn on_worktree_store_event(
 4090        &mut self,
 4091        _: Entity<WorktreeStore>,
 4092        event: &WorktreeStoreEvent,
 4093        cx: &mut Context<Self>,
 4094    ) {
 4095        match event {
 4096            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4097                if !worktree.read(cx).is_local() {
 4098                    return;
 4099                }
 4100                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4101                    worktree::Event::UpdatedEntries(changes) => {
 4102                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4103                    }
 4104                    worktree::Event::UpdatedGitRepositories(_)
 4105                    | worktree::Event::DeletedEntry(_) => {}
 4106                })
 4107                .detach()
 4108            }
 4109            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4110            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4111                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4112            }
 4113            WorktreeStoreEvent::WorktreeReleased(..)
 4114            | WorktreeStoreEvent::WorktreeOrderChanged
 4115            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4116            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4117            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4118        }
 4119    }
 4120
 4121    fn on_prettier_store_event(
 4122        &mut self,
 4123        _: Entity<PrettierStore>,
 4124        event: &PrettierStoreEvent,
 4125        cx: &mut Context<Self>,
 4126    ) {
 4127        match event {
 4128            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4129                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4130            }
 4131            PrettierStoreEvent::LanguageServerAdded {
 4132                new_server_id,
 4133                name,
 4134                prettier_server,
 4135            } => {
 4136                self.register_supplementary_language_server(
 4137                    *new_server_id,
 4138                    name.clone(),
 4139                    prettier_server.clone(),
 4140                    cx,
 4141                );
 4142            }
 4143        }
 4144    }
 4145
 4146    fn on_toolchain_store_event(
 4147        &mut self,
 4148        _: Entity<LocalToolchainStore>,
 4149        event: &ToolchainStoreEvent,
 4150        _: &mut Context<Self>,
 4151    ) {
 4152        if let ToolchainStoreEvent::ToolchainActivated = event {
 4153            self.request_workspace_config_refresh()
 4154        }
 4155    }
 4156
 4157    fn request_workspace_config_refresh(&mut self) {
 4158        *self._maintain_workspace_config.1.borrow_mut() = ();
 4159    }
 4160
 4161    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4162        self.as_local().map(|local| local.prettier_store.clone())
 4163    }
 4164
 4165    fn on_buffer_event(
 4166        &mut self,
 4167        buffer: Entity<Buffer>,
 4168        event: &language::BufferEvent,
 4169        cx: &mut Context<Self>,
 4170    ) {
 4171        match event {
 4172            language::BufferEvent::Edited => {
 4173                self.on_buffer_edited(buffer, cx);
 4174            }
 4175
 4176            language::BufferEvent::Saved => {
 4177                self.on_buffer_saved(buffer, cx);
 4178            }
 4179
 4180            _ => {}
 4181        }
 4182    }
 4183
 4184    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4185        buffer
 4186            .read(cx)
 4187            .set_language_registry(self.languages.clone());
 4188
 4189        cx.subscribe(buffer, |this, buffer, event, cx| {
 4190            this.on_buffer_event(buffer, event, cx);
 4191        })
 4192        .detach();
 4193
 4194        self.detect_language_for_buffer(buffer, cx);
 4195        if let Some(local) = self.as_local_mut() {
 4196            local.initialize_buffer(buffer, cx);
 4197        }
 4198
 4199        Ok(())
 4200    }
 4201
 4202    pub(crate) fn register_buffer_with_language_servers(
 4203        &mut self,
 4204        buffer: &Entity<Buffer>,
 4205        only_register_servers: HashSet<LanguageServerSelector>,
 4206        ignore_refcounts: bool,
 4207        cx: &mut Context<Self>,
 4208    ) -> OpenLspBufferHandle {
 4209        let buffer_id = buffer.read(cx).remote_id();
 4210        let handle = cx.new(|_| buffer.clone());
 4211        if let Some(local) = self.as_local_mut() {
 4212            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4213            if !ignore_refcounts {
 4214                *refcount += 1;
 4215            }
 4216
 4217            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4218            // 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
 4219            // 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
 4220            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4221            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4222                return handle;
 4223            };
 4224            if !file.is_local() {
 4225                return handle;
 4226            }
 4227
 4228            if ignore_refcounts || *refcount == 1 {
 4229                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4230            }
 4231            if !ignore_refcounts {
 4232                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4233                    let refcount = {
 4234                        let local = lsp_store.as_local_mut().unwrap();
 4235                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4236                            debug_panic!("bad refcounting");
 4237                            return;
 4238                        };
 4239
 4240                        *refcount -= 1;
 4241                        *refcount
 4242                    };
 4243                    if refcount == 0 {
 4244                        lsp_store.lsp_data.remove(&buffer_id);
 4245                        let local = lsp_store.as_local_mut().unwrap();
 4246                        local.registered_buffers.remove(&buffer_id);
 4247
 4248                        local.buffers_opened_in_servers.remove(&buffer_id);
 4249                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4250                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4251
 4252                            let buffer_abs_path = file.abs_path(cx);
 4253                            for (_, buffer_pull_diagnostics_result_ids) in
 4254                                &mut local.buffer_pull_diagnostics_result_ids
 4255                            {
 4256                                buffer_pull_diagnostics_result_ids.retain(
 4257                                    |_, buffer_result_ids| {
 4258                                        buffer_result_ids.remove(&buffer_abs_path);
 4259                                        !buffer_result_ids.is_empty()
 4260                                    },
 4261                                );
 4262                            }
 4263
 4264                            let diagnostic_updates = local
 4265                                .language_servers
 4266                                .keys()
 4267                                .cloned()
 4268                                .map(|server_id| DocumentDiagnosticsUpdate {
 4269                                    diagnostics: DocumentDiagnostics {
 4270                                        document_abs_path: buffer_abs_path.clone(),
 4271                                        version: None,
 4272                                        diagnostics: Vec::new(),
 4273                                    },
 4274                                    result_id: None,
 4275                                    registration_id: None,
 4276                                    server_id: server_id,
 4277                                    disk_based_sources: Cow::Borrowed(&[]),
 4278                                })
 4279                                .collect::<Vec<_>>();
 4280
 4281                            lsp_store
 4282                                .merge_diagnostic_entries(
 4283                                    diagnostic_updates,
 4284                                    |_, diagnostic, _| {
 4285                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4286                                    },
 4287                                    cx,
 4288                                )
 4289                                .context("Clearing diagnostics for the closed buffer")
 4290                                .log_err();
 4291                        }
 4292                    }
 4293                })
 4294                .detach();
 4295            }
 4296        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4297            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4298            cx.background_spawn(async move {
 4299                upstream_client
 4300                    .request(proto::RegisterBufferWithLanguageServers {
 4301                        project_id: upstream_project_id,
 4302                        buffer_id,
 4303                        only_servers: only_register_servers
 4304                            .into_iter()
 4305                            .map(|selector| {
 4306                                let selector = match selector {
 4307                                    LanguageServerSelector::Id(language_server_id) => {
 4308                                        proto::language_server_selector::Selector::ServerId(
 4309                                            language_server_id.to_proto(),
 4310                                        )
 4311                                    }
 4312                                    LanguageServerSelector::Name(language_server_name) => {
 4313                                        proto::language_server_selector::Selector::Name(
 4314                                            language_server_name.to_string(),
 4315                                        )
 4316                                    }
 4317                                };
 4318                                proto::LanguageServerSelector {
 4319                                    selector: Some(selector),
 4320                                }
 4321                            })
 4322                            .collect(),
 4323                    })
 4324                    .await
 4325            })
 4326            .detach();
 4327        } else {
 4328            // Our remote connection got closed
 4329        }
 4330        handle
 4331    }
 4332
 4333    fn maintain_buffer_languages(
 4334        languages: Arc<LanguageRegistry>,
 4335        cx: &mut Context<Self>,
 4336    ) -> Task<()> {
 4337        let mut subscription = languages.subscribe();
 4338        let mut prev_reload_count = languages.reload_count();
 4339        cx.spawn(async move |this, cx| {
 4340            while let Some(()) = subscription.next().await {
 4341                if let Some(this) = this.upgrade() {
 4342                    // If the language registry has been reloaded, then remove and
 4343                    // re-assign the languages on all open buffers.
 4344                    let reload_count = languages.reload_count();
 4345                    if reload_count > prev_reload_count {
 4346                        prev_reload_count = reload_count;
 4347                        this.update(cx, |this, cx| {
 4348                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4349                                for buffer in buffer_store.buffers() {
 4350                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4351                                    {
 4352                                        buffer.update(cx, |buffer, cx| {
 4353                                            buffer.set_language_async(None, cx)
 4354                                        });
 4355                                        if let Some(local) = this.as_local_mut() {
 4356                                            local.reset_buffer(&buffer, &f, cx);
 4357
 4358                                            if local
 4359                                                .registered_buffers
 4360                                                .contains_key(&buffer.read(cx).remote_id())
 4361                                                && let Some(file_url) =
 4362                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4363                                            {
 4364                                                local.unregister_buffer_from_language_servers(
 4365                                                    &buffer, &file_url, cx,
 4366                                                );
 4367                                            }
 4368                                        }
 4369                                    }
 4370                                }
 4371                            });
 4372                        })
 4373                        .ok();
 4374                    }
 4375
 4376                    this.update(cx, |this, cx| {
 4377                        let mut plain_text_buffers = Vec::new();
 4378                        let mut buffers_with_unknown_injections = Vec::new();
 4379                        for handle in this.buffer_store.read(cx).buffers() {
 4380                            let buffer = handle.read(cx);
 4381                            if buffer.language().is_none()
 4382                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4383                            {
 4384                                plain_text_buffers.push(handle);
 4385                            } else if buffer.contains_unknown_injections() {
 4386                                buffers_with_unknown_injections.push(handle);
 4387                            }
 4388                        }
 4389
 4390                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4391                        // and reused later in the invisible worktrees.
 4392                        plain_text_buffers.sort_by_key(|buffer| {
 4393                            Reverse(
 4394                                File::from_dyn(buffer.read(cx).file())
 4395                                    .map(|file| file.worktree.read(cx).is_visible()),
 4396                            )
 4397                        });
 4398
 4399                        for buffer in plain_text_buffers {
 4400                            this.detect_language_for_buffer(&buffer, cx);
 4401                            if let Some(local) = this.as_local_mut() {
 4402                                local.initialize_buffer(&buffer, cx);
 4403                                if local
 4404                                    .registered_buffers
 4405                                    .contains_key(&buffer.read(cx).remote_id())
 4406                                {
 4407                                    local.register_buffer_with_language_servers(
 4408                                        &buffer,
 4409                                        HashSet::default(),
 4410                                        cx,
 4411                                    );
 4412                                }
 4413                            }
 4414                        }
 4415
 4416                        for buffer in buffers_with_unknown_injections {
 4417                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4418                        }
 4419                    })
 4420                    .ok();
 4421                }
 4422            }
 4423        })
 4424    }
 4425
 4426    fn detect_language_for_buffer(
 4427        &mut self,
 4428        buffer_handle: &Entity<Buffer>,
 4429        cx: &mut Context<Self>,
 4430    ) -> Option<language::AvailableLanguage> {
 4431        // If the buffer has a language, set it and start the language server if we haven't already.
 4432        let buffer = buffer_handle.read(cx);
 4433        let file = buffer.file()?;
 4434
 4435        let content = buffer.as_rope();
 4436        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4437        if let Some(available_language) = &available_language {
 4438            if let Some(Ok(Ok(new_language))) = self
 4439                .languages
 4440                .load_language(available_language)
 4441                .now_or_never()
 4442            {
 4443                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4444            }
 4445        } else {
 4446            cx.emit(LspStoreEvent::LanguageDetected {
 4447                buffer: buffer_handle.clone(),
 4448                new_language: None,
 4449            });
 4450        }
 4451
 4452        available_language
 4453    }
 4454
 4455    pub(crate) fn set_language_for_buffer(
 4456        &mut self,
 4457        buffer_entity: &Entity<Buffer>,
 4458        new_language: Arc<Language>,
 4459        cx: &mut Context<Self>,
 4460    ) {
 4461        let buffer = buffer_entity.read(cx);
 4462        let buffer_file = buffer.file().cloned();
 4463        let buffer_id = buffer.remote_id();
 4464        if let Some(local_store) = self.as_local_mut()
 4465            && local_store.registered_buffers.contains_key(&buffer_id)
 4466            && let Some(abs_path) =
 4467                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4468            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4469        {
 4470            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4471        }
 4472        buffer_entity.update(cx, |buffer, cx| {
 4473            if buffer
 4474                .language()
 4475                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4476            {
 4477                buffer.set_language_async(Some(new_language.clone()), cx);
 4478            }
 4479        });
 4480
 4481        let settings =
 4482            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4483        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4484
 4485        let worktree_id = if let Some(file) = buffer_file {
 4486            let worktree = file.worktree.clone();
 4487
 4488            if let Some(local) = self.as_local_mut()
 4489                && local.registered_buffers.contains_key(&buffer_id)
 4490            {
 4491                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4492            }
 4493            Some(worktree.read(cx).id())
 4494        } else {
 4495            None
 4496        };
 4497
 4498        if settings.prettier.allowed
 4499            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4500        {
 4501            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4502            if let Some(prettier_store) = prettier_store {
 4503                prettier_store.update(cx, |prettier_store, cx| {
 4504                    prettier_store.install_default_prettier(
 4505                        worktree_id,
 4506                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4507                        cx,
 4508                    )
 4509                })
 4510            }
 4511        }
 4512
 4513        cx.emit(LspStoreEvent::LanguageDetected {
 4514            buffer: buffer_entity.clone(),
 4515            new_language: Some(new_language),
 4516        })
 4517    }
 4518
 4519    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4520        self.buffer_store.clone()
 4521    }
 4522
 4523    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4524        self.active_entry = active_entry;
 4525    }
 4526
 4527    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4528        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4529            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4530        {
 4531            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4532                summaries
 4533                    .iter()
 4534                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4535            });
 4536            if let Some(summary) = summaries.next() {
 4537                client
 4538                    .send(proto::UpdateDiagnosticSummary {
 4539                        project_id: downstream_project_id,
 4540                        worktree_id: worktree.id().to_proto(),
 4541                        summary: Some(summary),
 4542                        more_summaries: summaries.collect(),
 4543                    })
 4544                    .log_err();
 4545            }
 4546        }
 4547    }
 4548
 4549    fn is_capable_for_proto_request<R>(
 4550        &self,
 4551        buffer: &Entity<Buffer>,
 4552        request: &R,
 4553        cx: &App,
 4554    ) -> bool
 4555    where
 4556        R: LspCommand,
 4557    {
 4558        self.check_if_capable_for_proto_request(
 4559            buffer,
 4560            |capabilities| {
 4561                request.check_capabilities(AdapterServerCapabilities {
 4562                    server_capabilities: capabilities.clone(),
 4563                    code_action_kinds: None,
 4564                })
 4565            },
 4566            cx,
 4567        )
 4568    }
 4569
 4570    fn check_if_capable_for_proto_request<F>(
 4571        &self,
 4572        buffer: &Entity<Buffer>,
 4573        check: F,
 4574        cx: &App,
 4575    ) -> bool
 4576    where
 4577        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4578    {
 4579        let Some(language) = buffer.read(cx).language().cloned() else {
 4580            return false;
 4581        };
 4582        let relevant_language_servers = self
 4583            .languages
 4584            .lsp_adapters(&language.name())
 4585            .into_iter()
 4586            .map(|lsp_adapter| lsp_adapter.name())
 4587            .collect::<HashSet<_>>();
 4588        self.language_server_statuses
 4589            .iter()
 4590            .filter_map(|(server_id, server_status)| {
 4591                relevant_language_servers
 4592                    .contains(&server_status.name)
 4593                    .then_some(server_id)
 4594            })
 4595            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4596            .any(check)
 4597    }
 4598
 4599    fn all_capable_for_proto_request<F>(
 4600        &self,
 4601        buffer: &Entity<Buffer>,
 4602        mut check: F,
 4603        cx: &App,
 4604    ) -> Vec<lsp::LanguageServerId>
 4605    where
 4606        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4607    {
 4608        let Some(language) = buffer.read(cx).language().cloned() else {
 4609            return Vec::default();
 4610        };
 4611        let relevant_language_servers = self
 4612            .languages
 4613            .lsp_adapters(&language.name())
 4614            .into_iter()
 4615            .map(|lsp_adapter| lsp_adapter.name())
 4616            .collect::<HashSet<_>>();
 4617        self.language_server_statuses
 4618            .iter()
 4619            .filter_map(|(server_id, server_status)| {
 4620                relevant_language_servers
 4621                    .contains(&server_status.name)
 4622                    .then_some((server_id, &server_status.name))
 4623            })
 4624            .filter_map(|(server_id, server_name)| {
 4625                self.lsp_server_capabilities
 4626                    .get(server_id)
 4627                    .map(|c| (server_id, server_name, c))
 4628            })
 4629            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4630            .map(|(server_id, _, _)| *server_id)
 4631            .collect()
 4632    }
 4633
 4634    pub fn request_lsp<R>(
 4635        &mut self,
 4636        buffer: Entity<Buffer>,
 4637        server: LanguageServerToQuery,
 4638        request: R,
 4639        cx: &mut Context<Self>,
 4640    ) -> Task<Result<R::Response>>
 4641    where
 4642        R: LspCommand,
 4643        <R::LspRequest as lsp::request::Request>::Result: Send,
 4644        <R::LspRequest as lsp::request::Request>::Params: Send,
 4645    {
 4646        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4647            return self.send_lsp_proto_request(
 4648                buffer,
 4649                upstream_client,
 4650                upstream_project_id,
 4651                request,
 4652                cx,
 4653            );
 4654        }
 4655
 4656        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4657            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4658                local
 4659                    .language_servers_for_buffer(buffer, cx)
 4660                    .find(|(_, server)| {
 4661                        request.check_capabilities(server.adapter_server_capabilities())
 4662                    })
 4663                    .map(|(_, server)| server.clone())
 4664            }),
 4665            LanguageServerToQuery::Other(id) => self
 4666                .language_server_for_local_buffer(buffer, id, cx)
 4667                .and_then(|(_, server)| {
 4668                    request
 4669                        .check_capabilities(server.adapter_server_capabilities())
 4670                        .then(|| Arc::clone(server))
 4671                }),
 4672        }) else {
 4673            return Task::ready(Ok(Default::default()));
 4674        };
 4675
 4676        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4677
 4678        let Some(file) = file else {
 4679            return Task::ready(Ok(Default::default()));
 4680        };
 4681
 4682        let lsp_params = match request.to_lsp_params_or_response(
 4683            &file.abs_path(cx),
 4684            buffer.read(cx),
 4685            &language_server,
 4686            cx,
 4687        ) {
 4688            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4689            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4690            Err(err) => {
 4691                let message = format!(
 4692                    "{} via {} failed: {}",
 4693                    request.display_name(),
 4694                    language_server.name(),
 4695                    err
 4696                );
 4697                // rust-analyzer likes to error with this when its still loading up
 4698                if !message.ends_with("content modified") {
 4699                    log::warn!("{message}");
 4700                }
 4701                return Task::ready(Err(anyhow!(message)));
 4702            }
 4703        };
 4704
 4705        let status = request.status();
 4706        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4707            return Task::ready(Ok(Default::default()));
 4708        }
 4709        cx.spawn(async move |this, cx| {
 4710            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4711
 4712            let id = lsp_request.id();
 4713            let _cleanup = if status.is_some() {
 4714                cx.update(|cx| {
 4715                    this.update(cx, |this, cx| {
 4716                        this.on_lsp_work_start(
 4717                            language_server.server_id(),
 4718                            ProgressToken::Number(id),
 4719                            LanguageServerProgress {
 4720                                is_disk_based_diagnostics_progress: false,
 4721                                is_cancellable: false,
 4722                                title: None,
 4723                                message: status.clone(),
 4724                                percentage: None,
 4725                                last_update_at: cx.background_executor().now(),
 4726                            },
 4727                            cx,
 4728                        );
 4729                    })
 4730                })
 4731                .log_err();
 4732
 4733                Some(defer(|| {
 4734                    cx.update(|cx| {
 4735                        this.update(cx, |this, cx| {
 4736                            this.on_lsp_work_end(
 4737                                language_server.server_id(),
 4738                                ProgressToken::Number(id),
 4739                                cx,
 4740                            );
 4741                        })
 4742                    })
 4743                    .log_err();
 4744                }))
 4745            } else {
 4746                None
 4747            };
 4748
 4749            let result = lsp_request.await.into_response();
 4750
 4751            let response = result.map_err(|err| {
 4752                let message = format!(
 4753                    "{} via {} failed: {}",
 4754                    request.display_name(),
 4755                    language_server.name(),
 4756                    err
 4757                );
 4758                // rust-analyzer likes to error with this when its still loading up
 4759                if !message.ends_with("content modified") {
 4760                    log::warn!("{message}");
 4761                }
 4762                anyhow::anyhow!(message)
 4763            })?;
 4764
 4765            request
 4766                .response_from_lsp(
 4767                    response,
 4768                    this.upgrade().context("no app context")?,
 4769                    buffer,
 4770                    language_server.server_id(),
 4771                    cx.clone(),
 4772                )
 4773                .await
 4774        })
 4775    }
 4776
 4777    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4778        let mut language_formatters_to_check = Vec::new();
 4779        for buffer in self.buffer_store.read(cx).buffers() {
 4780            let buffer = buffer.read(cx);
 4781            let buffer_file = File::from_dyn(buffer.file());
 4782            let buffer_language = buffer.language();
 4783            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4784            if buffer_language.is_some() {
 4785                language_formatters_to_check.push((
 4786                    buffer_file.map(|f| f.worktree_id(cx)),
 4787                    settings.into_owned(),
 4788                ));
 4789            }
 4790        }
 4791
 4792        self.request_workspace_config_refresh();
 4793
 4794        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4795            prettier_store.update(cx, |prettier_store, cx| {
 4796                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4797            })
 4798        }
 4799
 4800        cx.notify();
 4801    }
 4802
 4803    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4804        let buffer_store = self.buffer_store.clone();
 4805        let Some(local) = self.as_local_mut() else {
 4806            return;
 4807        };
 4808        let mut adapters = BTreeMap::default();
 4809        let get_adapter = {
 4810            let languages = local.languages.clone();
 4811            let environment = local.environment.clone();
 4812            let weak = local.weak.clone();
 4813            let worktree_store = local.worktree_store.clone();
 4814            let http_client = local.http_client.clone();
 4815            let fs = local.fs.clone();
 4816            move |worktree_id, cx: &mut App| {
 4817                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4818                Some(LocalLspAdapterDelegate::new(
 4819                    languages.clone(),
 4820                    &environment,
 4821                    weak.clone(),
 4822                    &worktree,
 4823                    http_client.clone(),
 4824                    fs.clone(),
 4825                    cx,
 4826                ))
 4827            }
 4828        };
 4829
 4830        let mut messages_to_report = Vec::new();
 4831        let (new_tree, to_stop) = {
 4832            let mut rebase = local.lsp_tree.rebase();
 4833            let buffers = buffer_store
 4834                .read(cx)
 4835                .buffers()
 4836                .filter_map(|buffer| {
 4837                    let raw_buffer = buffer.read(cx);
 4838                    if !local
 4839                        .registered_buffers
 4840                        .contains_key(&raw_buffer.remote_id())
 4841                    {
 4842                        return None;
 4843                    }
 4844                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4845                    let language = raw_buffer.language().cloned()?;
 4846                    Some((file, language, raw_buffer.remote_id()))
 4847                })
 4848                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4849            for (file, language, buffer_id) in buffers {
 4850                let worktree_id = file.worktree_id(cx);
 4851                let Some(worktree) = local
 4852                    .worktree_store
 4853                    .read(cx)
 4854                    .worktree_for_id(worktree_id, cx)
 4855                else {
 4856                    continue;
 4857                };
 4858
 4859                if let Some((_, apply)) = local.reuse_existing_language_server(
 4860                    rebase.server_tree(),
 4861                    &worktree,
 4862                    &language.name(),
 4863                    cx,
 4864                ) {
 4865                    (apply)(rebase.server_tree());
 4866                } else if let Some(lsp_delegate) = adapters
 4867                    .entry(worktree_id)
 4868                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4869                    .clone()
 4870                {
 4871                    let delegate =
 4872                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4873                    let path = file
 4874                        .path()
 4875                        .parent()
 4876                        .map(Arc::from)
 4877                        .unwrap_or_else(|| file.path().clone());
 4878                    let worktree_path = ProjectPath { worktree_id, path };
 4879                    let abs_path = file.abs_path(cx);
 4880                    let nodes = rebase
 4881                        .walk(
 4882                            worktree_path,
 4883                            language.name(),
 4884                            language.manifest(),
 4885                            delegate.clone(),
 4886                            cx,
 4887                        )
 4888                        .collect::<Vec<_>>();
 4889                    for node in nodes {
 4890                        let server_id = node.server_id_or_init(|disposition| {
 4891                            let path = &disposition.path;
 4892                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4893                            let key = LanguageServerSeed {
 4894                                worktree_id,
 4895                                name: disposition.server_name.clone(),
 4896                                settings: disposition.settings.clone(),
 4897                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4898                                    path.worktree_id,
 4899                                    &path.path,
 4900                                    language.name(),
 4901                                ),
 4902                            };
 4903                            local.language_server_ids.remove(&key);
 4904
 4905                            let server_id = local.get_or_insert_language_server(
 4906                                &worktree,
 4907                                lsp_delegate.clone(),
 4908                                disposition,
 4909                                &language.name(),
 4910                                cx,
 4911                            );
 4912                            if let Some(state) = local.language_servers.get(&server_id)
 4913                                && let Ok(uri) = uri
 4914                            {
 4915                                state.add_workspace_folder(uri);
 4916                            };
 4917                            server_id
 4918                        });
 4919
 4920                        if let Some(language_server_id) = server_id {
 4921                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4922                                language_server_id,
 4923                                name: node.name(),
 4924                                message:
 4925                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4926                                        proto::RegisteredForBuffer {
 4927                                            buffer_abs_path: abs_path
 4928                                                .to_string_lossy()
 4929                                                .into_owned(),
 4930                                            buffer_id: buffer_id.to_proto(),
 4931                                        },
 4932                                    ),
 4933                            });
 4934                        }
 4935                    }
 4936                } else {
 4937                    continue;
 4938                }
 4939            }
 4940            rebase.finish()
 4941        };
 4942        for message in messages_to_report {
 4943            cx.emit(message);
 4944        }
 4945        local.lsp_tree = new_tree;
 4946        for (id, _) in to_stop {
 4947            self.stop_local_language_server(id, cx).detach();
 4948        }
 4949    }
 4950
 4951    pub fn apply_code_action(
 4952        &self,
 4953        buffer_handle: Entity<Buffer>,
 4954        mut action: CodeAction,
 4955        push_to_history: bool,
 4956        cx: &mut Context<Self>,
 4957    ) -> Task<Result<ProjectTransaction>> {
 4958        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4959            let request = proto::ApplyCodeAction {
 4960                project_id,
 4961                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4962                action: Some(Self::serialize_code_action(&action)),
 4963            };
 4964            let buffer_store = self.buffer_store();
 4965            cx.spawn(async move |_, cx| {
 4966                let response = upstream_client
 4967                    .request(request)
 4968                    .await?
 4969                    .transaction
 4970                    .context("missing transaction")?;
 4971
 4972                buffer_store
 4973                    .update(cx, |buffer_store, cx| {
 4974                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4975                    })?
 4976                    .await
 4977            })
 4978        } else if self.mode.is_local() {
 4979            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4980                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4981                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4982            }) else {
 4983                return Task::ready(Ok(ProjectTransaction::default()));
 4984            };
 4985            cx.spawn(async move |this,  cx| {
 4986                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4987                    .await
 4988                    .context("resolving a code action")?;
 4989                if let Some(edit) = action.lsp_action.edit()
 4990                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4991                        return LocalLspStore::deserialize_workspace_edit(
 4992                            this.upgrade().context("no app present")?,
 4993                            edit.clone(),
 4994                            push_to_history,
 4995
 4996                            lang_server.clone(),
 4997                            cx,
 4998                        )
 4999                        .await;
 5000                    }
 5001
 5002                if let Some(command) = action.lsp_action.command() {
 5003                    let server_capabilities = lang_server.capabilities();
 5004                    let available_commands = server_capabilities
 5005                        .execute_command_provider
 5006                        .as_ref()
 5007                        .map(|options| options.commands.as_slice())
 5008                        .unwrap_or_default();
 5009                    if available_commands.contains(&command.command) {
 5010                        this.update(cx, |this, _| {
 5011                            this.as_local_mut()
 5012                                .unwrap()
 5013                                .last_workspace_edits_by_language_server
 5014                                .remove(&lang_server.server_id());
 5015                        })?;
 5016
 5017                        let _result = lang_server
 5018                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5019                                command: command.command.clone(),
 5020                                arguments: command.arguments.clone().unwrap_or_default(),
 5021                                ..lsp::ExecuteCommandParams::default()
 5022                            })
 5023                            .await.into_response()
 5024                            .context("execute command")?;
 5025
 5026                        return this.update(cx, |this, _| {
 5027                            this.as_local_mut()
 5028                                .unwrap()
 5029                                .last_workspace_edits_by_language_server
 5030                                .remove(&lang_server.server_id())
 5031                                .unwrap_or_default()
 5032                        });
 5033                    } else {
 5034                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5035                    }
 5036                }
 5037
 5038                Ok(ProjectTransaction::default())
 5039            })
 5040        } else {
 5041            Task::ready(Err(anyhow!("no upstream client and not local")))
 5042        }
 5043    }
 5044
 5045    pub fn apply_code_action_kind(
 5046        &mut self,
 5047        buffers: HashSet<Entity<Buffer>>,
 5048        kind: CodeActionKind,
 5049        push_to_history: bool,
 5050        cx: &mut Context<Self>,
 5051    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5052        if self.as_local().is_some() {
 5053            cx.spawn(async move |lsp_store, cx| {
 5054                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5055                let result = LocalLspStore::execute_code_action_kind_locally(
 5056                    lsp_store.clone(),
 5057                    buffers,
 5058                    kind,
 5059                    push_to_history,
 5060                    cx,
 5061                )
 5062                .await;
 5063                lsp_store.update(cx, |lsp_store, _| {
 5064                    lsp_store.update_last_formatting_failure(&result);
 5065                })?;
 5066                result
 5067            })
 5068        } else if let Some((client, project_id)) = self.upstream_client() {
 5069            let buffer_store = self.buffer_store();
 5070            cx.spawn(async move |lsp_store, cx| {
 5071                let result = client
 5072                    .request(proto::ApplyCodeActionKind {
 5073                        project_id,
 5074                        kind: kind.as_str().to_owned(),
 5075                        buffer_ids: buffers
 5076                            .iter()
 5077                            .map(|buffer| {
 5078                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5079                            })
 5080                            .collect::<Result<_>>()?,
 5081                    })
 5082                    .await
 5083                    .and_then(|result| result.transaction.context("missing transaction"));
 5084                lsp_store.update(cx, |lsp_store, _| {
 5085                    lsp_store.update_last_formatting_failure(&result);
 5086                })?;
 5087
 5088                let transaction_response = result?;
 5089                buffer_store
 5090                    .update(cx, |buffer_store, cx| {
 5091                        buffer_store.deserialize_project_transaction(
 5092                            transaction_response,
 5093                            push_to_history,
 5094                            cx,
 5095                        )
 5096                    })?
 5097                    .await
 5098            })
 5099        } else {
 5100            Task::ready(Ok(ProjectTransaction::default()))
 5101        }
 5102    }
 5103
 5104    pub fn resolved_hint(
 5105        &mut self,
 5106        buffer_id: BufferId,
 5107        id: InlayId,
 5108        cx: &mut Context<Self>,
 5109    ) -> Option<ResolvedHint> {
 5110        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5111
 5112        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5113        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5114        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5115        let (server_id, resolve_data) = match &hint.resolve_state {
 5116            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5117            ResolveState::Resolving => {
 5118                return Some(ResolvedHint::Resolving(
 5119                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5120                ));
 5121            }
 5122            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5123        };
 5124
 5125        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5126        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5127        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5128            id,
 5129            cx.spawn(async move |lsp_store, cx| {
 5130                let resolved_hint = resolve_task.await;
 5131                lsp_store
 5132                    .update(cx, |lsp_store, _| {
 5133                        if let Some(old_inlay_hint) = lsp_store
 5134                            .lsp_data
 5135                            .get_mut(&buffer_id)
 5136                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5137                        {
 5138                            match resolved_hint {
 5139                                Ok(resolved_hint) => {
 5140                                    *old_inlay_hint = resolved_hint;
 5141                                }
 5142                                Err(e) => {
 5143                                    old_inlay_hint.resolve_state =
 5144                                        ResolveState::CanResolve(server_id, resolve_data);
 5145                                    log::error!("Inlay hint resolve failed: {e:#}");
 5146                                }
 5147                            }
 5148                        }
 5149                    })
 5150                    .ok();
 5151            })
 5152            .shared(),
 5153        );
 5154        debug_assert!(
 5155            previous_task.is_none(),
 5156            "Did not change hint's resolve state after spawning its resolve"
 5157        );
 5158        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5159        None
 5160    }
 5161
 5162    fn resolve_inlay_hint(
 5163        &self,
 5164        mut hint: InlayHint,
 5165        buffer: Entity<Buffer>,
 5166        server_id: LanguageServerId,
 5167        cx: &mut Context<Self>,
 5168    ) -> Task<anyhow::Result<InlayHint>> {
 5169        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5170            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5171            {
 5172                hint.resolve_state = ResolveState::Resolved;
 5173                return Task::ready(Ok(hint));
 5174            }
 5175            let request = proto::ResolveInlayHint {
 5176                project_id,
 5177                buffer_id: buffer.read(cx).remote_id().into(),
 5178                language_server_id: server_id.0 as u64,
 5179                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5180            };
 5181            cx.background_spawn(async move {
 5182                let response = upstream_client
 5183                    .request(request)
 5184                    .await
 5185                    .context("inlay hints proto request")?;
 5186                match response.hint {
 5187                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5188                        .context("inlay hints proto resolve response conversion"),
 5189                    None => Ok(hint),
 5190                }
 5191            })
 5192        } else {
 5193            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5194                self.language_server_for_local_buffer(buffer, server_id, cx)
 5195                    .map(|(_, server)| server.clone())
 5196            }) else {
 5197                return Task::ready(Ok(hint));
 5198            };
 5199            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5200                return Task::ready(Ok(hint));
 5201            }
 5202            let buffer_snapshot = buffer.read(cx).snapshot();
 5203            cx.spawn(async move |_, cx| {
 5204                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5205                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5206                );
 5207                let resolved_hint = resolve_task
 5208                    .await
 5209                    .into_response()
 5210                    .context("inlay hint resolve LSP request")?;
 5211                let resolved_hint = InlayHints::lsp_to_project_hint(
 5212                    resolved_hint,
 5213                    &buffer,
 5214                    server_id,
 5215                    ResolveState::Resolved,
 5216                    false,
 5217                    cx,
 5218                )
 5219                .await?;
 5220                Ok(resolved_hint)
 5221            })
 5222        }
 5223    }
 5224
 5225    pub fn resolve_color_presentation(
 5226        &mut self,
 5227        mut color: DocumentColor,
 5228        buffer: Entity<Buffer>,
 5229        server_id: LanguageServerId,
 5230        cx: &mut Context<Self>,
 5231    ) -> Task<Result<DocumentColor>> {
 5232        if color.resolved {
 5233            return Task::ready(Ok(color));
 5234        }
 5235
 5236        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5237            let start = color.lsp_range.start;
 5238            let end = color.lsp_range.end;
 5239            let request = proto::GetColorPresentation {
 5240                project_id,
 5241                server_id: server_id.to_proto(),
 5242                buffer_id: buffer.read(cx).remote_id().into(),
 5243                color: Some(proto::ColorInformation {
 5244                    red: color.color.red,
 5245                    green: color.color.green,
 5246                    blue: color.color.blue,
 5247                    alpha: color.color.alpha,
 5248                    lsp_range_start: Some(proto::PointUtf16 {
 5249                        row: start.line,
 5250                        column: start.character,
 5251                    }),
 5252                    lsp_range_end: Some(proto::PointUtf16 {
 5253                        row: end.line,
 5254                        column: end.character,
 5255                    }),
 5256                }),
 5257            };
 5258            cx.background_spawn(async move {
 5259                let response = upstream_client
 5260                    .request(request)
 5261                    .await
 5262                    .context("color presentation proto request")?;
 5263                color.resolved = true;
 5264                color.color_presentations = response
 5265                    .presentations
 5266                    .into_iter()
 5267                    .map(|presentation| ColorPresentation {
 5268                        label: SharedString::from(presentation.label),
 5269                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5270                        additional_text_edits: presentation
 5271                            .additional_text_edits
 5272                            .into_iter()
 5273                            .filter_map(deserialize_lsp_edit)
 5274                            .collect(),
 5275                    })
 5276                    .collect();
 5277                Ok(color)
 5278            })
 5279        } else {
 5280            let path = match buffer
 5281                .update(cx, |buffer, cx| {
 5282                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5283                })
 5284                .context("buffer with the missing path")
 5285            {
 5286                Ok(path) => path,
 5287                Err(e) => return Task::ready(Err(e)),
 5288            };
 5289            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5290                self.language_server_for_local_buffer(buffer, server_id, cx)
 5291                    .map(|(_, server)| server.clone())
 5292            }) else {
 5293                return Task::ready(Ok(color));
 5294            };
 5295            cx.background_spawn(async move {
 5296                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5297                    lsp::ColorPresentationParams {
 5298                        text_document: make_text_document_identifier(&path)?,
 5299                        color: color.color,
 5300                        range: color.lsp_range,
 5301                        work_done_progress_params: Default::default(),
 5302                        partial_result_params: Default::default(),
 5303                    },
 5304                );
 5305                color.color_presentations = resolve_task
 5306                    .await
 5307                    .into_response()
 5308                    .context("color presentation resolve LSP request")?
 5309                    .into_iter()
 5310                    .map(|presentation| ColorPresentation {
 5311                        label: SharedString::from(presentation.label),
 5312                        text_edit: presentation.text_edit,
 5313                        additional_text_edits: presentation
 5314                            .additional_text_edits
 5315                            .unwrap_or_default(),
 5316                    })
 5317                    .collect();
 5318                color.resolved = true;
 5319                Ok(color)
 5320            })
 5321        }
 5322    }
 5323
 5324    pub(crate) fn linked_edits(
 5325        &mut self,
 5326        buffer: &Entity<Buffer>,
 5327        position: Anchor,
 5328        cx: &mut Context<Self>,
 5329    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5330        let snapshot = buffer.read(cx).snapshot();
 5331        let scope = snapshot.language_scope_at(position);
 5332        let Some(server_id) = self
 5333            .as_local()
 5334            .and_then(|local| {
 5335                buffer.update(cx, |buffer, cx| {
 5336                    local
 5337                        .language_servers_for_buffer(buffer, cx)
 5338                        .filter(|(_, server)| {
 5339                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5340                        })
 5341                        .filter(|(adapter, _)| {
 5342                            scope
 5343                                .as_ref()
 5344                                .map(|scope| scope.language_allowed(&adapter.name))
 5345                                .unwrap_or(true)
 5346                        })
 5347                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5348                        .next()
 5349                })
 5350            })
 5351            .or_else(|| {
 5352                self.upstream_client()
 5353                    .is_some()
 5354                    .then_some(LanguageServerToQuery::FirstCapable)
 5355            })
 5356            .filter(|_| {
 5357                maybe!({
 5358                    let language = buffer.read(cx).language_at(position)?;
 5359                    Some(
 5360                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5361                            .linked_edits,
 5362                    )
 5363                }) == Some(true)
 5364            })
 5365        else {
 5366            return Task::ready(Ok(Vec::new()));
 5367        };
 5368
 5369        self.request_lsp(
 5370            buffer.clone(),
 5371            server_id,
 5372            LinkedEditingRange { position },
 5373            cx,
 5374        )
 5375    }
 5376
 5377    fn apply_on_type_formatting(
 5378        &mut self,
 5379        buffer: Entity<Buffer>,
 5380        position: Anchor,
 5381        trigger: String,
 5382        cx: &mut Context<Self>,
 5383    ) -> Task<Result<Option<Transaction>>> {
 5384        if let Some((client, project_id)) = self.upstream_client() {
 5385            if !self.check_if_capable_for_proto_request(
 5386                &buffer,
 5387                |capabilities| {
 5388                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5389                },
 5390                cx,
 5391            ) {
 5392                return Task::ready(Ok(None));
 5393            }
 5394            let request = proto::OnTypeFormatting {
 5395                project_id,
 5396                buffer_id: buffer.read(cx).remote_id().into(),
 5397                position: Some(serialize_anchor(&position)),
 5398                trigger,
 5399                version: serialize_version(&buffer.read(cx).version()),
 5400            };
 5401            cx.background_spawn(async move {
 5402                client
 5403                    .request(request)
 5404                    .await?
 5405                    .transaction
 5406                    .map(language::proto::deserialize_transaction)
 5407                    .transpose()
 5408            })
 5409        } else if let Some(local) = self.as_local_mut() {
 5410            let buffer_id = buffer.read(cx).remote_id();
 5411            local.buffers_being_formatted.insert(buffer_id);
 5412            cx.spawn(async move |this, cx| {
 5413                let _cleanup = defer({
 5414                    let this = this.clone();
 5415                    let mut cx = cx.clone();
 5416                    move || {
 5417                        this.update(&mut cx, |this, _| {
 5418                            if let Some(local) = this.as_local_mut() {
 5419                                local.buffers_being_formatted.remove(&buffer_id);
 5420                            }
 5421                        })
 5422                        .ok();
 5423                    }
 5424                });
 5425
 5426                buffer
 5427                    .update(cx, |buffer, _| {
 5428                        buffer.wait_for_edits(Some(position.timestamp))
 5429                    })?
 5430                    .await?;
 5431                this.update(cx, |this, cx| {
 5432                    let position = position.to_point_utf16(buffer.read(cx));
 5433                    this.on_type_format(buffer, position, trigger, false, cx)
 5434                })?
 5435                .await
 5436            })
 5437        } else {
 5438            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5439        }
 5440    }
 5441
 5442    pub fn on_type_format<T: ToPointUtf16>(
 5443        &mut self,
 5444        buffer: Entity<Buffer>,
 5445        position: T,
 5446        trigger: String,
 5447        push_to_history: bool,
 5448        cx: &mut Context<Self>,
 5449    ) -> Task<Result<Option<Transaction>>> {
 5450        let position = position.to_point_utf16(buffer.read(cx));
 5451        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5452    }
 5453
 5454    fn on_type_format_impl(
 5455        &mut self,
 5456        buffer: Entity<Buffer>,
 5457        position: PointUtf16,
 5458        trigger: String,
 5459        push_to_history: bool,
 5460        cx: &mut Context<Self>,
 5461    ) -> Task<Result<Option<Transaction>>> {
 5462        let options = buffer.update(cx, |buffer, cx| {
 5463            lsp_command::lsp_formatting_options(
 5464                language_settings(
 5465                    buffer.language_at(position).map(|l| l.name()),
 5466                    buffer.file(),
 5467                    cx,
 5468                )
 5469                .as_ref(),
 5470            )
 5471        });
 5472
 5473        cx.spawn(async move |this, cx| {
 5474            if let Some(waiter) =
 5475                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5476            {
 5477                waiter.await?;
 5478            }
 5479            cx.update(|cx| {
 5480                this.update(cx, |this, cx| {
 5481                    this.request_lsp(
 5482                        buffer.clone(),
 5483                        LanguageServerToQuery::FirstCapable,
 5484                        OnTypeFormatting {
 5485                            position,
 5486                            trigger,
 5487                            options,
 5488                            push_to_history,
 5489                        },
 5490                        cx,
 5491                    )
 5492                })
 5493            })??
 5494            .await
 5495        })
 5496    }
 5497
 5498    pub fn definitions(
 5499        &mut self,
 5500        buffer: &Entity<Buffer>,
 5501        position: PointUtf16,
 5502        cx: &mut Context<Self>,
 5503    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5504        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5505            let request = GetDefinitions { position };
 5506            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5507                return Task::ready(Ok(None));
 5508            }
 5509            let request_task = upstream_client.request_lsp(
 5510                project_id,
 5511                None,
 5512                LSP_REQUEST_TIMEOUT,
 5513                cx.background_executor().clone(),
 5514                request.to_proto(project_id, buffer.read(cx)),
 5515            );
 5516            let buffer = buffer.clone();
 5517            cx.spawn(async move |weak_lsp_store, cx| {
 5518                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5519                    return Ok(None);
 5520                };
 5521                let Some(responses) = request_task.await? else {
 5522                    return Ok(None);
 5523                };
 5524                let actions = join_all(responses.payload.into_iter().map(|response| {
 5525                    GetDefinitions { position }.response_from_proto(
 5526                        response.response,
 5527                        lsp_store.clone(),
 5528                        buffer.clone(),
 5529                        cx.clone(),
 5530                    )
 5531                }))
 5532                .await;
 5533
 5534                Ok(Some(
 5535                    actions
 5536                        .into_iter()
 5537                        .collect::<Result<Vec<Vec<_>>>>()?
 5538                        .into_iter()
 5539                        .flatten()
 5540                        .dedup()
 5541                        .collect(),
 5542                ))
 5543            })
 5544        } else {
 5545            let definitions_task = self.request_multiple_lsp_locally(
 5546                buffer,
 5547                Some(position),
 5548                GetDefinitions { position },
 5549                cx,
 5550            );
 5551            cx.background_spawn(async move {
 5552                Ok(Some(
 5553                    definitions_task
 5554                        .await
 5555                        .into_iter()
 5556                        .flat_map(|(_, definitions)| definitions)
 5557                        .dedup()
 5558                        .collect(),
 5559                ))
 5560            })
 5561        }
 5562    }
 5563
 5564    pub fn declarations(
 5565        &mut self,
 5566        buffer: &Entity<Buffer>,
 5567        position: PointUtf16,
 5568        cx: &mut Context<Self>,
 5569    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5570        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5571            let request = GetDeclarations { position };
 5572            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5573                return Task::ready(Ok(None));
 5574            }
 5575            let request_task = upstream_client.request_lsp(
 5576                project_id,
 5577                None,
 5578                LSP_REQUEST_TIMEOUT,
 5579                cx.background_executor().clone(),
 5580                request.to_proto(project_id, buffer.read(cx)),
 5581            );
 5582            let buffer = buffer.clone();
 5583            cx.spawn(async move |weak_lsp_store, cx| {
 5584                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5585                    return Ok(None);
 5586                };
 5587                let Some(responses) = request_task.await? else {
 5588                    return Ok(None);
 5589                };
 5590                let actions = join_all(responses.payload.into_iter().map(|response| {
 5591                    GetDeclarations { position }.response_from_proto(
 5592                        response.response,
 5593                        lsp_store.clone(),
 5594                        buffer.clone(),
 5595                        cx.clone(),
 5596                    )
 5597                }))
 5598                .await;
 5599
 5600                Ok(Some(
 5601                    actions
 5602                        .into_iter()
 5603                        .collect::<Result<Vec<Vec<_>>>>()?
 5604                        .into_iter()
 5605                        .flatten()
 5606                        .dedup()
 5607                        .collect(),
 5608                ))
 5609            })
 5610        } else {
 5611            let declarations_task = self.request_multiple_lsp_locally(
 5612                buffer,
 5613                Some(position),
 5614                GetDeclarations { position },
 5615                cx,
 5616            );
 5617            cx.background_spawn(async move {
 5618                Ok(Some(
 5619                    declarations_task
 5620                        .await
 5621                        .into_iter()
 5622                        .flat_map(|(_, declarations)| declarations)
 5623                        .dedup()
 5624                        .collect(),
 5625                ))
 5626            })
 5627        }
 5628    }
 5629
 5630    pub fn type_definitions(
 5631        &mut self,
 5632        buffer: &Entity<Buffer>,
 5633        position: PointUtf16,
 5634        cx: &mut Context<Self>,
 5635    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5636        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5637            let request = GetTypeDefinitions { position };
 5638            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5639                return Task::ready(Ok(None));
 5640            }
 5641            let request_task = upstream_client.request_lsp(
 5642                project_id,
 5643                None,
 5644                LSP_REQUEST_TIMEOUT,
 5645                cx.background_executor().clone(),
 5646                request.to_proto(project_id, buffer.read(cx)),
 5647            );
 5648            let buffer = buffer.clone();
 5649            cx.spawn(async move |weak_lsp_store, cx| {
 5650                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5651                    return Ok(None);
 5652                };
 5653                let Some(responses) = request_task.await? else {
 5654                    return Ok(None);
 5655                };
 5656                let actions = join_all(responses.payload.into_iter().map(|response| {
 5657                    GetTypeDefinitions { position }.response_from_proto(
 5658                        response.response,
 5659                        lsp_store.clone(),
 5660                        buffer.clone(),
 5661                        cx.clone(),
 5662                    )
 5663                }))
 5664                .await;
 5665
 5666                Ok(Some(
 5667                    actions
 5668                        .into_iter()
 5669                        .collect::<Result<Vec<Vec<_>>>>()?
 5670                        .into_iter()
 5671                        .flatten()
 5672                        .dedup()
 5673                        .collect(),
 5674                ))
 5675            })
 5676        } else {
 5677            let type_definitions_task = self.request_multiple_lsp_locally(
 5678                buffer,
 5679                Some(position),
 5680                GetTypeDefinitions { position },
 5681                cx,
 5682            );
 5683            cx.background_spawn(async move {
 5684                Ok(Some(
 5685                    type_definitions_task
 5686                        .await
 5687                        .into_iter()
 5688                        .flat_map(|(_, type_definitions)| type_definitions)
 5689                        .dedup()
 5690                        .collect(),
 5691                ))
 5692            })
 5693        }
 5694    }
 5695
 5696    pub fn implementations(
 5697        &mut self,
 5698        buffer: &Entity<Buffer>,
 5699        position: PointUtf16,
 5700        cx: &mut Context<Self>,
 5701    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5702        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5703            let request = GetImplementations { position };
 5704            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5705                return Task::ready(Ok(None));
 5706            }
 5707            let request_task = upstream_client.request_lsp(
 5708                project_id,
 5709                None,
 5710                LSP_REQUEST_TIMEOUT,
 5711                cx.background_executor().clone(),
 5712                request.to_proto(project_id, buffer.read(cx)),
 5713            );
 5714            let buffer = buffer.clone();
 5715            cx.spawn(async move |weak_lsp_store, cx| {
 5716                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5717                    return Ok(None);
 5718                };
 5719                let Some(responses) = request_task.await? else {
 5720                    return Ok(None);
 5721                };
 5722                let actions = join_all(responses.payload.into_iter().map(|response| {
 5723                    GetImplementations { position }.response_from_proto(
 5724                        response.response,
 5725                        lsp_store.clone(),
 5726                        buffer.clone(),
 5727                        cx.clone(),
 5728                    )
 5729                }))
 5730                .await;
 5731
 5732                Ok(Some(
 5733                    actions
 5734                        .into_iter()
 5735                        .collect::<Result<Vec<Vec<_>>>>()?
 5736                        .into_iter()
 5737                        .flatten()
 5738                        .dedup()
 5739                        .collect(),
 5740                ))
 5741            })
 5742        } else {
 5743            let implementations_task = self.request_multiple_lsp_locally(
 5744                buffer,
 5745                Some(position),
 5746                GetImplementations { position },
 5747                cx,
 5748            );
 5749            cx.background_spawn(async move {
 5750                Ok(Some(
 5751                    implementations_task
 5752                        .await
 5753                        .into_iter()
 5754                        .flat_map(|(_, implementations)| implementations)
 5755                        .dedup()
 5756                        .collect(),
 5757                ))
 5758            })
 5759        }
 5760    }
 5761
 5762    pub fn references(
 5763        &mut self,
 5764        buffer: &Entity<Buffer>,
 5765        position: PointUtf16,
 5766        cx: &mut Context<Self>,
 5767    ) -> Task<Result<Option<Vec<Location>>>> {
 5768        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5769            let request = GetReferences { position };
 5770            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5771                return Task::ready(Ok(None));
 5772            }
 5773
 5774            let request_task = upstream_client.request_lsp(
 5775                project_id,
 5776                None,
 5777                LSP_REQUEST_TIMEOUT,
 5778                cx.background_executor().clone(),
 5779                request.to_proto(project_id, buffer.read(cx)),
 5780            );
 5781            let buffer = buffer.clone();
 5782            cx.spawn(async move |weak_lsp_store, cx| {
 5783                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5784                    return Ok(None);
 5785                };
 5786                let Some(responses) = request_task.await? else {
 5787                    return Ok(None);
 5788                };
 5789
 5790                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5791                    GetReferences { position }.response_from_proto(
 5792                        lsp_response.response,
 5793                        lsp_store.clone(),
 5794                        buffer.clone(),
 5795                        cx.clone(),
 5796                    )
 5797                }))
 5798                .await
 5799                .into_iter()
 5800                .collect::<Result<Vec<Vec<_>>>>()?
 5801                .into_iter()
 5802                .flatten()
 5803                .dedup()
 5804                .collect();
 5805                Ok(Some(locations))
 5806            })
 5807        } else {
 5808            let references_task = self.request_multiple_lsp_locally(
 5809                buffer,
 5810                Some(position),
 5811                GetReferences { position },
 5812                cx,
 5813            );
 5814            cx.background_spawn(async move {
 5815                Ok(Some(
 5816                    references_task
 5817                        .await
 5818                        .into_iter()
 5819                        .flat_map(|(_, references)| references)
 5820                        .dedup()
 5821                        .collect(),
 5822                ))
 5823            })
 5824        }
 5825    }
 5826
 5827    pub fn code_actions(
 5828        &mut self,
 5829        buffer: &Entity<Buffer>,
 5830        range: Range<Anchor>,
 5831        kinds: Option<Vec<CodeActionKind>>,
 5832        cx: &mut Context<Self>,
 5833    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5834        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5835            let request = GetCodeActions {
 5836                range: range.clone(),
 5837                kinds: kinds.clone(),
 5838            };
 5839            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5840                return Task::ready(Ok(None));
 5841            }
 5842            let request_task = upstream_client.request_lsp(
 5843                project_id,
 5844                None,
 5845                LSP_REQUEST_TIMEOUT,
 5846                cx.background_executor().clone(),
 5847                request.to_proto(project_id, buffer.read(cx)),
 5848            );
 5849            let buffer = buffer.clone();
 5850            cx.spawn(async move |weak_lsp_store, cx| {
 5851                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5852                    return Ok(None);
 5853                };
 5854                let Some(responses) = request_task.await? else {
 5855                    return Ok(None);
 5856                };
 5857                let actions = join_all(responses.payload.into_iter().map(|response| {
 5858                    GetCodeActions {
 5859                        range: range.clone(),
 5860                        kinds: kinds.clone(),
 5861                    }
 5862                    .response_from_proto(
 5863                        response.response,
 5864                        lsp_store.clone(),
 5865                        buffer.clone(),
 5866                        cx.clone(),
 5867                    )
 5868                }))
 5869                .await;
 5870
 5871                Ok(Some(
 5872                    actions
 5873                        .into_iter()
 5874                        .collect::<Result<Vec<Vec<_>>>>()?
 5875                        .into_iter()
 5876                        .flatten()
 5877                        .collect(),
 5878                ))
 5879            })
 5880        } else {
 5881            let all_actions_task = self.request_multiple_lsp_locally(
 5882                buffer,
 5883                Some(range.start),
 5884                GetCodeActions { range, kinds },
 5885                cx,
 5886            );
 5887            cx.background_spawn(async move {
 5888                Ok(Some(
 5889                    all_actions_task
 5890                        .await
 5891                        .into_iter()
 5892                        .flat_map(|(_, actions)| actions)
 5893                        .collect(),
 5894                ))
 5895            })
 5896        }
 5897    }
 5898
 5899    pub fn code_lens_actions(
 5900        &mut self,
 5901        buffer: &Entity<Buffer>,
 5902        cx: &mut Context<Self>,
 5903    ) -> CodeLensTask {
 5904        let version_queried_for = buffer.read(cx).version();
 5905        let buffer_id = buffer.read(cx).remote_id();
 5906        let existing_servers = self.as_local().map(|local| {
 5907            local
 5908                .buffers_opened_in_servers
 5909                .get(&buffer_id)
 5910                .cloned()
 5911                .unwrap_or_default()
 5912        });
 5913
 5914        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5915            if let Some(cached_lens) = &lsp_data.code_lens {
 5916                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5917                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5918                        existing_servers != cached_lens.lens.keys().copied().collect()
 5919                    });
 5920                    if !has_different_servers {
 5921                        return Task::ready(Ok(Some(
 5922                            cached_lens.lens.values().flatten().cloned().collect(),
 5923                        )))
 5924                        .shared();
 5925                    }
 5926                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5927                    if !version_queried_for.changed_since(updating_for) {
 5928                        return running_update.clone();
 5929                    }
 5930                }
 5931            }
 5932        }
 5933
 5934        let lens_lsp_data = self
 5935            .latest_lsp_data(buffer, cx)
 5936            .code_lens
 5937            .get_or_insert_default();
 5938        let buffer = buffer.clone();
 5939        let query_version_queried_for = version_queried_for.clone();
 5940        let new_task = cx
 5941            .spawn(async move |lsp_store, cx| {
 5942                cx.background_executor()
 5943                    .timer(Duration::from_millis(30))
 5944                    .await;
 5945                let fetched_lens = lsp_store
 5946                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5947                    .map_err(Arc::new)?
 5948                    .await
 5949                    .context("fetching code lens")
 5950                    .map_err(Arc::new);
 5951                let fetched_lens = match fetched_lens {
 5952                    Ok(fetched_lens) => fetched_lens,
 5953                    Err(e) => {
 5954                        lsp_store
 5955                            .update(cx, |lsp_store, _| {
 5956                                if let Some(lens_lsp_data) = lsp_store
 5957                                    .lsp_data
 5958                                    .get_mut(&buffer_id)
 5959                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5960                                {
 5961                                    lens_lsp_data.update = None;
 5962                                }
 5963                            })
 5964                            .ok();
 5965                        return Err(e);
 5966                    }
 5967                };
 5968
 5969                lsp_store
 5970                    .update(cx, |lsp_store, _| {
 5971                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5972                        let code_lens = lsp_data.code_lens.as_mut()?;
 5973                        if let Some(fetched_lens) = fetched_lens {
 5974                            if lsp_data.buffer_version == query_version_queried_for {
 5975                                code_lens.lens.extend(fetched_lens);
 5976                            } else if !lsp_data
 5977                                .buffer_version
 5978                                .changed_since(&query_version_queried_for)
 5979                            {
 5980                                lsp_data.buffer_version = query_version_queried_for;
 5981                                code_lens.lens = fetched_lens;
 5982                            }
 5983                        }
 5984                        code_lens.update = None;
 5985                        Some(code_lens.lens.values().flatten().cloned().collect())
 5986                    })
 5987                    .map_err(Arc::new)
 5988            })
 5989            .shared();
 5990        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5991        new_task
 5992    }
 5993
 5994    fn fetch_code_lens(
 5995        &mut self,
 5996        buffer: &Entity<Buffer>,
 5997        cx: &mut Context<Self>,
 5998    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5999        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6000            let request = GetCodeLens;
 6001            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6002                return Task::ready(Ok(None));
 6003            }
 6004            let request_task = upstream_client.request_lsp(
 6005                project_id,
 6006                None,
 6007                LSP_REQUEST_TIMEOUT,
 6008                cx.background_executor().clone(),
 6009                request.to_proto(project_id, buffer.read(cx)),
 6010            );
 6011            let buffer = buffer.clone();
 6012            cx.spawn(async move |weak_lsp_store, cx| {
 6013                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6014                    return Ok(None);
 6015                };
 6016                let Some(responses) = request_task.await? else {
 6017                    return Ok(None);
 6018                };
 6019
 6020                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6021                    let lsp_store = lsp_store.clone();
 6022                    let buffer = buffer.clone();
 6023                    let cx = cx.clone();
 6024                    async move {
 6025                        (
 6026                            LanguageServerId::from_proto(response.server_id),
 6027                            GetCodeLens
 6028                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6029                                .await,
 6030                        )
 6031                    }
 6032                }))
 6033                .await;
 6034
 6035                let mut has_errors = false;
 6036                let code_lens_actions = code_lens_actions
 6037                    .into_iter()
 6038                    .filter_map(|(server_id, code_lens)| match code_lens {
 6039                        Ok(code_lens) => Some((server_id, code_lens)),
 6040                        Err(e) => {
 6041                            has_errors = true;
 6042                            log::error!("{e:#}");
 6043                            None
 6044                        }
 6045                    })
 6046                    .collect::<HashMap<_, _>>();
 6047                anyhow::ensure!(
 6048                    !has_errors || !code_lens_actions.is_empty(),
 6049                    "Failed to fetch code lens"
 6050                );
 6051                Ok(Some(code_lens_actions))
 6052            })
 6053        } else {
 6054            let code_lens_actions_task =
 6055                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6056            cx.background_spawn(async move {
 6057                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6058            })
 6059        }
 6060    }
 6061
 6062    #[inline(never)]
 6063    pub fn completions(
 6064        &self,
 6065        buffer: &Entity<Buffer>,
 6066        position: PointUtf16,
 6067        context: CompletionContext,
 6068        cx: &mut Context<Self>,
 6069    ) -> Task<Result<Vec<CompletionResponse>>> {
 6070        let language_registry = self.languages.clone();
 6071
 6072        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6073            let snapshot = buffer.read(cx).snapshot();
 6074            let offset = position.to_offset(&snapshot);
 6075            let scope = snapshot.language_scope_at(offset);
 6076            let capable_lsps = self.all_capable_for_proto_request(
 6077                buffer,
 6078                |server_name, capabilities| {
 6079                    capabilities.completion_provider.is_some()
 6080                        && scope
 6081                            .as_ref()
 6082                            .map(|scope| scope.language_allowed(server_name))
 6083                            .unwrap_or(true)
 6084                },
 6085                cx,
 6086            );
 6087            if capable_lsps.is_empty() {
 6088                return Task::ready(Ok(Vec::new()));
 6089            }
 6090
 6091            let language = buffer.read(cx).language().cloned();
 6092
 6093            // In the future, we should provide project guests with the names of LSP adapters,
 6094            // so that they can use the correct LSP adapter when computing labels. For now,
 6095            // guests just use the first LSP adapter associated with the buffer's language.
 6096            let lsp_adapter = language.as_ref().and_then(|language| {
 6097                language_registry
 6098                    .lsp_adapters(&language.name())
 6099                    .first()
 6100                    .cloned()
 6101            });
 6102
 6103            let buffer = buffer.clone();
 6104
 6105            cx.spawn(async move |this, cx| {
 6106                let requests = join_all(
 6107                    capable_lsps
 6108                        .into_iter()
 6109                        .map(|id| {
 6110                            let request = GetCompletions {
 6111                                position,
 6112                                context: context.clone(),
 6113                                server_id: Some(id),
 6114                            };
 6115                            let buffer = buffer.clone();
 6116                            let language = language.clone();
 6117                            let lsp_adapter = lsp_adapter.clone();
 6118                            let upstream_client = upstream_client.clone();
 6119                            let response = this
 6120                                .update(cx, |this, cx| {
 6121                                    this.send_lsp_proto_request(
 6122                                        buffer,
 6123                                        upstream_client,
 6124                                        project_id,
 6125                                        request,
 6126                                        cx,
 6127                                    )
 6128                                })
 6129                                .log_err();
 6130                            async move {
 6131                                let response = response?.await.log_err()?;
 6132
 6133                                let completions = populate_labels_for_completions(
 6134                                    response.completions,
 6135                                    language,
 6136                                    lsp_adapter,
 6137                                )
 6138                                .await;
 6139
 6140                                Some(CompletionResponse {
 6141                                    completions,
 6142                                    display_options: CompletionDisplayOptions::default(),
 6143                                    is_incomplete: response.is_incomplete,
 6144                                })
 6145                            }
 6146                        })
 6147                        .collect::<Vec<_>>(),
 6148                );
 6149                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6150            })
 6151        } else if let Some(local) = self.as_local() {
 6152            let snapshot = buffer.read(cx).snapshot();
 6153            let offset = position.to_offset(&snapshot);
 6154            let scope = snapshot.language_scope_at(offset);
 6155            let language = snapshot.language().cloned();
 6156            let completion_settings = language_settings(
 6157                language.as_ref().map(|language| language.name()),
 6158                buffer.read(cx).file(),
 6159                cx,
 6160            )
 6161            .completions
 6162            .clone();
 6163            if !completion_settings.lsp {
 6164                return Task::ready(Ok(Vec::new()));
 6165            }
 6166
 6167            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6168                local
 6169                    .language_servers_for_buffer(buffer, cx)
 6170                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6171                    .filter(|(adapter, _)| {
 6172                        scope
 6173                            .as_ref()
 6174                            .map(|scope| scope.language_allowed(&adapter.name))
 6175                            .unwrap_or(true)
 6176                    })
 6177                    .map(|(_, server)| server.server_id())
 6178                    .collect()
 6179            });
 6180
 6181            let buffer = buffer.clone();
 6182            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6183            let lsp_timeout = if lsp_timeout > 0 {
 6184                Some(Duration::from_millis(lsp_timeout))
 6185            } else {
 6186                None
 6187            };
 6188            cx.spawn(async move |this,  cx| {
 6189                let mut tasks = Vec::with_capacity(server_ids.len());
 6190                this.update(cx, |lsp_store, cx| {
 6191                    for server_id in server_ids {
 6192                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6193                        let lsp_timeout = lsp_timeout
 6194                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6195                        let mut timeout = cx.background_spawn(async move {
 6196                            match lsp_timeout {
 6197                                Some(lsp_timeout) => {
 6198                                    lsp_timeout.await;
 6199                                    true
 6200                                },
 6201                                None => false,
 6202                            }
 6203                        }).fuse();
 6204                        let mut lsp_request = lsp_store.request_lsp(
 6205                            buffer.clone(),
 6206                            LanguageServerToQuery::Other(server_id),
 6207                            GetCompletions {
 6208                                position,
 6209                                context: context.clone(),
 6210                                server_id: Some(server_id),
 6211                            },
 6212                            cx,
 6213                        ).fuse();
 6214                        let new_task = cx.background_spawn(async move {
 6215                            select_biased! {
 6216                                response = lsp_request => anyhow::Ok(Some(response?)),
 6217                                timeout_happened = timeout => {
 6218                                    if timeout_happened {
 6219                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6220                                        Ok(None)
 6221                                    } else {
 6222                                        let completions = lsp_request.await?;
 6223                                        Ok(Some(completions))
 6224                                    }
 6225                                },
 6226                            }
 6227                        });
 6228                        tasks.push((lsp_adapter, new_task));
 6229                    }
 6230                })?;
 6231
 6232                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6233                    let completion_response = task.await.ok()??;
 6234                    let completions = populate_labels_for_completions(
 6235                            completion_response.completions,
 6236                            language.clone(),
 6237                            lsp_adapter,
 6238                        )
 6239                        .await;
 6240                    Some(CompletionResponse {
 6241                        completions,
 6242                        display_options: CompletionDisplayOptions::default(),
 6243                        is_incomplete: completion_response.is_incomplete,
 6244                    })
 6245                });
 6246
 6247                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6248
 6249                Ok(responses.into_iter().flatten().collect())
 6250            })
 6251        } else {
 6252            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6253        }
 6254    }
 6255
 6256    pub fn resolve_completions(
 6257        &self,
 6258        buffer: Entity<Buffer>,
 6259        completion_indices: Vec<usize>,
 6260        completions: Rc<RefCell<Box<[Completion]>>>,
 6261        cx: &mut Context<Self>,
 6262    ) -> Task<Result<bool>> {
 6263        let client = self.upstream_client();
 6264        let buffer_id = buffer.read(cx).remote_id();
 6265        let buffer_snapshot = buffer.read(cx).snapshot();
 6266
 6267        if !self.check_if_capable_for_proto_request(
 6268            &buffer,
 6269            GetCompletions::can_resolve_completions,
 6270            cx,
 6271        ) {
 6272            return Task::ready(Ok(false));
 6273        }
 6274        cx.spawn(async move |lsp_store, cx| {
 6275            let mut did_resolve = false;
 6276            if let Some((client, project_id)) = client {
 6277                for completion_index in completion_indices {
 6278                    let server_id = {
 6279                        let completion = &completions.borrow()[completion_index];
 6280                        completion.source.server_id()
 6281                    };
 6282                    if let Some(server_id) = server_id {
 6283                        if Self::resolve_completion_remote(
 6284                            project_id,
 6285                            server_id,
 6286                            buffer_id,
 6287                            completions.clone(),
 6288                            completion_index,
 6289                            client.clone(),
 6290                        )
 6291                        .await
 6292                        .log_err()
 6293                        .is_some()
 6294                        {
 6295                            did_resolve = true;
 6296                        }
 6297                    } else {
 6298                        resolve_word_completion(
 6299                            &buffer_snapshot,
 6300                            &mut completions.borrow_mut()[completion_index],
 6301                        );
 6302                    }
 6303                }
 6304            } else {
 6305                for completion_index in completion_indices {
 6306                    let server_id = {
 6307                        let completion = &completions.borrow()[completion_index];
 6308                        completion.source.server_id()
 6309                    };
 6310                    if let Some(server_id) = server_id {
 6311                        let server_and_adapter = lsp_store
 6312                            .read_with(cx, |lsp_store, _| {
 6313                                let server = lsp_store.language_server_for_id(server_id)?;
 6314                                let adapter =
 6315                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6316                                Some((server, adapter))
 6317                            })
 6318                            .ok()
 6319                            .flatten();
 6320                        let Some((server, adapter)) = server_and_adapter else {
 6321                            continue;
 6322                        };
 6323
 6324                        let resolved = Self::resolve_completion_local(
 6325                            server,
 6326                            completions.clone(),
 6327                            completion_index,
 6328                        )
 6329                        .await
 6330                        .log_err()
 6331                        .is_some();
 6332                        if resolved {
 6333                            Self::regenerate_completion_labels(
 6334                                adapter,
 6335                                &buffer_snapshot,
 6336                                completions.clone(),
 6337                                completion_index,
 6338                            )
 6339                            .await
 6340                            .log_err();
 6341                            did_resolve = true;
 6342                        }
 6343                    } else {
 6344                        resolve_word_completion(
 6345                            &buffer_snapshot,
 6346                            &mut completions.borrow_mut()[completion_index],
 6347                        );
 6348                    }
 6349                }
 6350            }
 6351
 6352            Ok(did_resolve)
 6353        })
 6354    }
 6355
 6356    async fn resolve_completion_local(
 6357        server: Arc<lsp::LanguageServer>,
 6358        completions: Rc<RefCell<Box<[Completion]>>>,
 6359        completion_index: usize,
 6360    ) -> Result<()> {
 6361        let server_id = server.server_id();
 6362        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6363            return Ok(());
 6364        }
 6365
 6366        let request = {
 6367            let completion = &completions.borrow()[completion_index];
 6368            match &completion.source {
 6369                CompletionSource::Lsp {
 6370                    lsp_completion,
 6371                    resolved,
 6372                    server_id: completion_server_id,
 6373                    ..
 6374                } => {
 6375                    if *resolved {
 6376                        return Ok(());
 6377                    }
 6378                    anyhow::ensure!(
 6379                        server_id == *completion_server_id,
 6380                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6381                    );
 6382                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6383                }
 6384                CompletionSource::BufferWord { .. }
 6385                | CompletionSource::Dap { .. }
 6386                | CompletionSource::Custom => {
 6387                    return Ok(());
 6388                }
 6389            }
 6390        };
 6391        let resolved_completion = request
 6392            .await
 6393            .into_response()
 6394            .context("resolve completion")?;
 6395
 6396        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6397        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6398
 6399        let mut completions = completions.borrow_mut();
 6400        let completion = &mut completions[completion_index];
 6401        if let CompletionSource::Lsp {
 6402            lsp_completion,
 6403            resolved,
 6404            server_id: completion_server_id,
 6405            ..
 6406        } = &mut completion.source
 6407        {
 6408            if *resolved {
 6409                return Ok(());
 6410            }
 6411            anyhow::ensure!(
 6412                server_id == *completion_server_id,
 6413                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6414            );
 6415            *lsp_completion = Box::new(resolved_completion);
 6416            *resolved = true;
 6417        }
 6418        Ok(())
 6419    }
 6420
 6421    async fn regenerate_completion_labels(
 6422        adapter: Arc<CachedLspAdapter>,
 6423        snapshot: &BufferSnapshot,
 6424        completions: Rc<RefCell<Box<[Completion]>>>,
 6425        completion_index: usize,
 6426    ) -> Result<()> {
 6427        let completion_item = completions.borrow()[completion_index]
 6428            .source
 6429            .lsp_completion(true)
 6430            .map(Cow::into_owned);
 6431        if let Some(lsp_documentation) = completion_item
 6432            .as_ref()
 6433            .and_then(|completion_item| completion_item.documentation.clone())
 6434        {
 6435            let mut completions = completions.borrow_mut();
 6436            let completion = &mut completions[completion_index];
 6437            completion.documentation = Some(lsp_documentation.into());
 6438        } else {
 6439            let mut completions = completions.borrow_mut();
 6440            let completion = &mut completions[completion_index];
 6441            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6442        }
 6443
 6444        let mut new_label = match completion_item {
 6445            Some(completion_item) => {
 6446                // 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
 6447                // So we have to update the label here anyway...
 6448                let language = snapshot.language();
 6449                match language {
 6450                    Some(language) => {
 6451                        adapter
 6452                            .labels_for_completions(
 6453                                std::slice::from_ref(&completion_item),
 6454                                language,
 6455                            )
 6456                            .await?
 6457                    }
 6458                    None => Vec::new(),
 6459                }
 6460                .pop()
 6461                .flatten()
 6462                .unwrap_or_else(|| {
 6463                    CodeLabel::fallback_for_completion(
 6464                        &completion_item,
 6465                        language.map(|language| language.as_ref()),
 6466                    )
 6467                })
 6468            }
 6469            None => CodeLabel::plain(
 6470                completions.borrow()[completion_index].new_text.clone(),
 6471                None,
 6472            ),
 6473        };
 6474        ensure_uniform_list_compatible_label(&mut new_label);
 6475
 6476        let mut completions = completions.borrow_mut();
 6477        let completion = &mut completions[completion_index];
 6478        if completion.label.filter_text() == new_label.filter_text() {
 6479            completion.label = new_label;
 6480        } else {
 6481            log::error!(
 6482                "Resolved completion changed display label from {} to {}. \
 6483                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6484                completion.label.text(),
 6485                new_label.text(),
 6486                completion.label.filter_text(),
 6487                new_label.filter_text()
 6488            );
 6489        }
 6490
 6491        Ok(())
 6492    }
 6493
 6494    async fn resolve_completion_remote(
 6495        project_id: u64,
 6496        server_id: LanguageServerId,
 6497        buffer_id: BufferId,
 6498        completions: Rc<RefCell<Box<[Completion]>>>,
 6499        completion_index: usize,
 6500        client: AnyProtoClient,
 6501    ) -> Result<()> {
 6502        let lsp_completion = {
 6503            let completion = &completions.borrow()[completion_index];
 6504            match &completion.source {
 6505                CompletionSource::Lsp {
 6506                    lsp_completion,
 6507                    resolved,
 6508                    server_id: completion_server_id,
 6509                    ..
 6510                } => {
 6511                    anyhow::ensure!(
 6512                        server_id == *completion_server_id,
 6513                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6514                    );
 6515                    if *resolved {
 6516                        return Ok(());
 6517                    }
 6518                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6519                }
 6520                CompletionSource::Custom
 6521                | CompletionSource::Dap { .. }
 6522                | CompletionSource::BufferWord { .. } => {
 6523                    return Ok(());
 6524                }
 6525            }
 6526        };
 6527        let request = proto::ResolveCompletionDocumentation {
 6528            project_id,
 6529            language_server_id: server_id.0 as u64,
 6530            lsp_completion,
 6531            buffer_id: buffer_id.into(),
 6532        };
 6533
 6534        let response = client
 6535            .request(request)
 6536            .await
 6537            .context("completion documentation resolve proto request")?;
 6538        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6539
 6540        let documentation = if response.documentation.is_empty() {
 6541            CompletionDocumentation::Undocumented
 6542        } else if response.documentation_is_markdown {
 6543            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6544        } else if response.documentation.lines().count() <= 1 {
 6545            CompletionDocumentation::SingleLine(response.documentation.into())
 6546        } else {
 6547            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6548        };
 6549
 6550        let mut completions = completions.borrow_mut();
 6551        let completion = &mut completions[completion_index];
 6552        completion.documentation = Some(documentation);
 6553        if let CompletionSource::Lsp {
 6554            insert_range,
 6555            lsp_completion,
 6556            resolved,
 6557            server_id: completion_server_id,
 6558            lsp_defaults: _,
 6559        } = &mut completion.source
 6560        {
 6561            let completion_insert_range = response
 6562                .old_insert_start
 6563                .and_then(deserialize_anchor)
 6564                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6565            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6566
 6567            if *resolved {
 6568                return Ok(());
 6569            }
 6570            anyhow::ensure!(
 6571                server_id == *completion_server_id,
 6572                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6573            );
 6574            *lsp_completion = Box::new(resolved_lsp_completion);
 6575            *resolved = true;
 6576        }
 6577
 6578        let replace_range = response
 6579            .old_replace_start
 6580            .and_then(deserialize_anchor)
 6581            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6582        if let Some((old_replace_start, old_replace_end)) = replace_range
 6583            && !response.new_text.is_empty()
 6584        {
 6585            completion.new_text = response.new_text;
 6586            completion.replace_range = old_replace_start..old_replace_end;
 6587        }
 6588
 6589        Ok(())
 6590    }
 6591
 6592    pub fn apply_additional_edits_for_completion(
 6593        &self,
 6594        buffer_handle: Entity<Buffer>,
 6595        completions: Rc<RefCell<Box<[Completion]>>>,
 6596        completion_index: usize,
 6597        push_to_history: bool,
 6598        cx: &mut Context<Self>,
 6599    ) -> Task<Result<Option<Transaction>>> {
 6600        if let Some((client, project_id)) = self.upstream_client() {
 6601            let buffer = buffer_handle.read(cx);
 6602            let buffer_id = buffer.remote_id();
 6603            cx.spawn(async move |_, cx| {
 6604                let request = {
 6605                    let completion = completions.borrow()[completion_index].clone();
 6606                    proto::ApplyCompletionAdditionalEdits {
 6607                        project_id,
 6608                        buffer_id: buffer_id.into(),
 6609                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6610                            replace_range: completion.replace_range,
 6611                            new_text: completion.new_text,
 6612                            source: completion.source,
 6613                        })),
 6614                    }
 6615                };
 6616
 6617                if let Some(transaction) = client.request(request).await?.transaction {
 6618                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6619                    buffer_handle
 6620                        .update(cx, |buffer, _| {
 6621                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6622                        })?
 6623                        .await?;
 6624                    if push_to_history {
 6625                        buffer_handle.update(cx, |buffer, _| {
 6626                            buffer.push_transaction(transaction.clone(), Instant::now());
 6627                            buffer.finalize_last_transaction();
 6628                        })?;
 6629                    }
 6630                    Ok(Some(transaction))
 6631                } else {
 6632                    Ok(None)
 6633                }
 6634            })
 6635        } else {
 6636            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6637                let completion = &completions.borrow()[completion_index];
 6638                let server_id = completion.source.server_id()?;
 6639                Some(
 6640                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6641                        .1
 6642                        .clone(),
 6643                )
 6644            }) else {
 6645                return Task::ready(Ok(None));
 6646            };
 6647
 6648            cx.spawn(async move |this, cx| {
 6649                Self::resolve_completion_local(
 6650                    server.clone(),
 6651                    completions.clone(),
 6652                    completion_index,
 6653                )
 6654                .await
 6655                .context("resolving completion")?;
 6656                let completion = completions.borrow()[completion_index].clone();
 6657                let additional_text_edits = completion
 6658                    .source
 6659                    .lsp_completion(true)
 6660                    .as_ref()
 6661                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6662                if let Some(edits) = additional_text_edits {
 6663                    let edits = this
 6664                        .update(cx, |this, cx| {
 6665                            this.as_local_mut().unwrap().edits_from_lsp(
 6666                                &buffer_handle,
 6667                                edits,
 6668                                server.server_id(),
 6669                                None,
 6670                                cx,
 6671                            )
 6672                        })?
 6673                        .await?;
 6674
 6675                    buffer_handle.update(cx, |buffer, cx| {
 6676                        buffer.finalize_last_transaction();
 6677                        buffer.start_transaction();
 6678
 6679                        for (range, text) in edits {
 6680                            let primary = &completion.replace_range;
 6681
 6682                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6683                            // and the primary completion is just an insertion (empty range), then this is likely
 6684                            // an auto-import scenario and should not be considered overlapping
 6685                            // https://github.com/zed-industries/zed/issues/26136
 6686                            let is_file_start_auto_import = {
 6687                                let snapshot = buffer.snapshot();
 6688                                let primary_start_point = primary.start.to_point(&snapshot);
 6689                                let range_start_point = range.start.to_point(&snapshot);
 6690
 6691                                let result = primary_start_point.row == 0
 6692                                    && primary_start_point.column == 0
 6693                                    && range_start_point.row == 0
 6694                                    && range_start_point.column == 0;
 6695
 6696                                result
 6697                            };
 6698
 6699                            let has_overlap = if is_file_start_auto_import {
 6700                                false
 6701                            } else {
 6702                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6703                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6704                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6705                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6706                                let result = start_within || end_within;
 6707                                result
 6708                            };
 6709
 6710                            //Skip additional edits which overlap with the primary completion edit
 6711                            //https://github.com/zed-industries/zed/pull/1871
 6712                            if !has_overlap {
 6713                                buffer.edit([(range, text)], None, cx);
 6714                            }
 6715                        }
 6716
 6717                        let transaction = if buffer.end_transaction(cx).is_some() {
 6718                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6719                            if !push_to_history {
 6720                                buffer.forget_transaction(transaction.id);
 6721                            }
 6722                            Some(transaction)
 6723                        } else {
 6724                            None
 6725                        };
 6726                        Ok(transaction)
 6727                    })?
 6728                } else {
 6729                    Ok(None)
 6730                }
 6731            })
 6732        }
 6733    }
 6734
 6735    pub fn pull_diagnostics(
 6736        &mut self,
 6737        buffer: Entity<Buffer>,
 6738        cx: &mut Context<Self>,
 6739    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6740        let buffer_id = buffer.read(cx).remote_id();
 6741
 6742        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6743            let mut suitable_capabilities = None;
 6744            // Are we capable for proto request?
 6745            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6746                &buffer,
 6747                |capabilities| {
 6748                    if let Some(caps) = &capabilities.diagnostic_provider {
 6749                        suitable_capabilities = Some(caps.clone());
 6750                        true
 6751                    } else {
 6752                        false
 6753                    }
 6754                },
 6755                cx,
 6756            );
 6757            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6758            let Some(dynamic_caps) = suitable_capabilities else {
 6759                return Task::ready(Ok(None));
 6760            };
 6761            assert!(any_server_has_diagnostics_provider);
 6762
 6763            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6764            let request = GetDocumentDiagnostics {
 6765                previous_result_id: None,
 6766                identifier,
 6767                registration_id: None,
 6768            };
 6769            let request_task = client.request_lsp(
 6770                upstream_project_id,
 6771                None,
 6772                LSP_REQUEST_TIMEOUT,
 6773                cx.background_executor().clone(),
 6774                request.to_proto(upstream_project_id, buffer.read(cx)),
 6775            );
 6776            cx.background_spawn(async move {
 6777                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6778                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6779                // Do not attempt to further process the dummy responses here.
 6780                let _response = request_task.await?;
 6781                Ok(None)
 6782            })
 6783        } else {
 6784            let servers = buffer.update(cx, |buffer, cx| {
 6785                self.language_servers_for_local_buffer(buffer, cx)
 6786                    .map(|(_, server)| server.clone())
 6787                    .collect::<Vec<_>>()
 6788            });
 6789
 6790            let pull_diagnostics = servers
 6791                .into_iter()
 6792                .flat_map(|server| {
 6793                    let result = maybe!({
 6794                        let local = self.as_local()?;
 6795                        let server_id = server.server_id();
 6796                        let providers_with_identifiers = local
 6797                            .language_server_dynamic_registrations
 6798                            .get(&server_id)
 6799                            .into_iter()
 6800                            .flat_map(|registrations| registrations.diagnostics.clone())
 6801                            .collect::<Vec<_>>();
 6802                        Some(
 6803                            providers_with_identifiers
 6804                                .into_iter()
 6805                                .map(|(registration_id, dynamic_caps)| {
 6806                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6807                                    let registration_id = registration_id.map(SharedString::from);
 6808                                    let result_id = self.result_id_for_buffer_pull(
 6809                                        server_id,
 6810                                        buffer_id,
 6811                                        &registration_id,
 6812                                        cx,
 6813                                    );
 6814                                    self.request_lsp(
 6815                                        buffer.clone(),
 6816                                        LanguageServerToQuery::Other(server_id),
 6817                                        GetDocumentDiagnostics {
 6818                                            previous_result_id: result_id,
 6819                                            registration_id,
 6820                                            identifier,
 6821                                        },
 6822                                        cx,
 6823                                    )
 6824                                })
 6825                                .collect::<Vec<_>>(),
 6826                        )
 6827                    });
 6828
 6829                    result.unwrap_or_default()
 6830                })
 6831                .collect::<Vec<_>>();
 6832
 6833            cx.background_spawn(async move {
 6834                let mut responses = Vec::new();
 6835                for diagnostics in join_all(pull_diagnostics).await {
 6836                    responses.extend(diagnostics?);
 6837                }
 6838                Ok(Some(responses))
 6839            })
 6840        }
 6841    }
 6842
 6843    pub fn applicable_inlay_chunks(
 6844        &mut self,
 6845        buffer: &Entity<Buffer>,
 6846        ranges: &[Range<text::Anchor>],
 6847        cx: &mut Context<Self>,
 6848    ) -> Vec<Range<BufferRow>> {
 6849        self.latest_lsp_data(buffer, cx)
 6850            .inlay_hints
 6851            .applicable_chunks(ranges)
 6852            .map(|chunk| chunk.row_range())
 6853            .collect()
 6854    }
 6855
 6856    pub fn invalidate_inlay_hints<'a>(
 6857        &'a mut self,
 6858        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6859    ) {
 6860        for buffer_id in for_buffers {
 6861            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6862                lsp_data.inlay_hints.clear();
 6863            }
 6864        }
 6865    }
 6866
 6867    pub fn inlay_hints(
 6868        &mut self,
 6869        invalidate: InvalidationStrategy,
 6870        buffer: Entity<Buffer>,
 6871        ranges: Vec<Range<text::Anchor>>,
 6872        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6873        cx: &mut Context<Self>,
 6874    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6875        let next_hint_id = self.next_hint_id.clone();
 6876        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6877        let query_version = lsp_data.buffer_version.clone();
 6878        let mut lsp_refresh_requested = false;
 6879        let for_server = if let InvalidationStrategy::RefreshRequested {
 6880            server_id,
 6881            request_id,
 6882        } = invalidate
 6883        {
 6884            let invalidated = lsp_data
 6885                .inlay_hints
 6886                .invalidate_for_server_refresh(server_id, request_id);
 6887            lsp_refresh_requested = invalidated;
 6888            Some(server_id)
 6889        } else {
 6890            None
 6891        };
 6892        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6893        let known_chunks = known_chunks
 6894            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6895            .map(|(_, known_chunks)| known_chunks)
 6896            .unwrap_or_default();
 6897
 6898        let mut hint_fetch_tasks = Vec::new();
 6899        let mut cached_inlay_hints = None;
 6900        let mut ranges_to_query = None;
 6901        let applicable_chunks = existing_inlay_hints
 6902            .applicable_chunks(ranges.as_slice())
 6903            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6904            .collect::<Vec<_>>();
 6905        if applicable_chunks.is_empty() {
 6906            return HashMap::default();
 6907        }
 6908
 6909        for row_chunk in applicable_chunks {
 6910            match (
 6911                existing_inlay_hints
 6912                    .cached_hints(&row_chunk)
 6913                    .filter(|_| !lsp_refresh_requested)
 6914                    .cloned(),
 6915                existing_inlay_hints
 6916                    .fetched_hints(&row_chunk)
 6917                    .as_ref()
 6918                    .filter(|_| !lsp_refresh_requested)
 6919                    .cloned(),
 6920            ) {
 6921                (None, None) => {
 6922                    let Some(chunk_range) = existing_inlay_hints.chunk_range(row_chunk) else {
 6923                        continue;
 6924                    };
 6925                    ranges_to_query
 6926                        .get_or_insert_with(Vec::new)
 6927                        .push((row_chunk, chunk_range));
 6928                }
 6929                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6930                (Some(cached_hints), None) => {
 6931                    for (server_id, cached_hints) in cached_hints {
 6932                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6933                            cached_inlay_hints
 6934                                .get_or_insert_with(HashMap::default)
 6935                                .entry(row_chunk.row_range())
 6936                                .or_insert_with(HashMap::default)
 6937                                .entry(server_id)
 6938                                .or_insert_with(Vec::new)
 6939                                .extend(cached_hints);
 6940                        }
 6941                    }
 6942                }
 6943                (Some(cached_hints), Some(fetched_hints)) => {
 6944                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6945                    for (server_id, cached_hints) in cached_hints {
 6946                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6947                            cached_inlay_hints
 6948                                .get_or_insert_with(HashMap::default)
 6949                                .entry(row_chunk.row_range())
 6950                                .or_insert_with(HashMap::default)
 6951                                .entry(server_id)
 6952                                .or_insert_with(Vec::new)
 6953                                .extend(cached_hints);
 6954                        }
 6955                    }
 6956                }
 6957            }
 6958        }
 6959
 6960        if hint_fetch_tasks.is_empty()
 6961            && ranges_to_query
 6962                .as_ref()
 6963                .is_none_or(|ranges| ranges.is_empty())
 6964            && let Some(cached_inlay_hints) = cached_inlay_hints
 6965        {
 6966            cached_inlay_hints
 6967                .into_iter()
 6968                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6969                .collect()
 6970        } else {
 6971            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6972                let next_hint_id = next_hint_id.clone();
 6973                let buffer = buffer.clone();
 6974                let query_version = query_version.clone();
 6975                let new_inlay_hints = cx
 6976                    .spawn(async move |lsp_store, cx| {
 6977                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6978                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6979                        })?;
 6980                        new_fetch_task
 6981                            .await
 6982                            .and_then(|new_hints_by_server| {
 6983                                lsp_store.update(cx, |lsp_store, cx| {
 6984                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6985                                    let update_cache = lsp_data.buffer_version == query_version;
 6986                                    if new_hints_by_server.is_empty() {
 6987                                        if update_cache {
 6988                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6989                                        }
 6990                                        HashMap::default()
 6991                                    } else {
 6992                                        new_hints_by_server
 6993                                            .into_iter()
 6994                                            .map(|(server_id, new_hints)| {
 6995                                                let new_hints = new_hints
 6996                                                    .into_iter()
 6997                                                    .map(|new_hint| {
 6998                                                        (
 6999                                                            InlayId::Hint(next_hint_id.fetch_add(
 7000                                                                1,
 7001                                                                atomic::Ordering::AcqRel,
 7002                                                            )),
 7003                                                            new_hint,
 7004                                                        )
 7005                                                    })
 7006                                                    .collect::<Vec<_>>();
 7007                                                if update_cache {
 7008                                                    lsp_data.inlay_hints.insert_new_hints(
 7009                                                        chunk,
 7010                                                        server_id,
 7011                                                        new_hints.clone(),
 7012                                                    );
 7013                                                }
 7014                                                (server_id, new_hints)
 7015                                            })
 7016                                            .collect()
 7017                                    }
 7018                                })
 7019                            })
 7020                            .map_err(Arc::new)
 7021                    })
 7022                    .shared();
 7023
 7024                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7025                *fetch_task = Some(new_inlay_hints.clone());
 7026                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7027            }
 7028
 7029            cached_inlay_hints
 7030                .unwrap_or_default()
 7031                .into_iter()
 7032                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7033                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7034                    (
 7035                        chunk.row_range(),
 7036                        cx.spawn(async move |_, _| {
 7037                            hints_fetch.await.map_err(|e| {
 7038                                if e.error_code() != ErrorCode::Internal {
 7039                                    anyhow!(e.error_code())
 7040                                } else {
 7041                                    anyhow!("{e:#}")
 7042                                }
 7043                            })
 7044                        }),
 7045                    )
 7046                }))
 7047                .collect()
 7048        }
 7049    }
 7050
 7051    fn fetch_inlay_hints(
 7052        &mut self,
 7053        for_server: Option<LanguageServerId>,
 7054        buffer: &Entity<Buffer>,
 7055        range: Range<Anchor>,
 7056        cx: &mut Context<Self>,
 7057    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7058        let request = InlayHints {
 7059            range: range.clone(),
 7060        };
 7061        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7062            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7063                return Task::ready(Ok(HashMap::default()));
 7064            }
 7065            let request_task = upstream_client.request_lsp(
 7066                project_id,
 7067                for_server.map(|id| id.to_proto()),
 7068                LSP_REQUEST_TIMEOUT,
 7069                cx.background_executor().clone(),
 7070                request.to_proto(project_id, buffer.read(cx)),
 7071            );
 7072            let buffer = buffer.clone();
 7073            cx.spawn(async move |weak_lsp_store, cx| {
 7074                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7075                    return Ok(HashMap::default());
 7076                };
 7077                let Some(responses) = request_task.await? else {
 7078                    return Ok(HashMap::default());
 7079                };
 7080
 7081                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7082                    let lsp_store = lsp_store.clone();
 7083                    let buffer = buffer.clone();
 7084                    let cx = cx.clone();
 7085                    let request = request.clone();
 7086                    async move {
 7087                        (
 7088                            LanguageServerId::from_proto(response.server_id),
 7089                            request
 7090                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7091                                .await,
 7092                        )
 7093                    }
 7094                }))
 7095                .await;
 7096
 7097                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7098                let mut has_errors = false;
 7099                let inlay_hints = inlay_hints
 7100                    .into_iter()
 7101                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7102                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7103                        Err(e) => {
 7104                            has_errors = true;
 7105                            log::error!("{e:#}");
 7106                            None
 7107                        }
 7108                    })
 7109                    .map(|(server_id, mut new_hints)| {
 7110                        new_hints.retain(|hint| {
 7111                            hint.position.is_valid(&buffer_snapshot)
 7112                                && range.start.is_valid(&buffer_snapshot)
 7113                                && range.end.is_valid(&buffer_snapshot)
 7114                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7115                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7116                        });
 7117                        (server_id, new_hints)
 7118                    })
 7119                    .collect::<HashMap<_, _>>();
 7120                anyhow::ensure!(
 7121                    !has_errors || !inlay_hints.is_empty(),
 7122                    "Failed to fetch inlay hints"
 7123                );
 7124                Ok(inlay_hints)
 7125            })
 7126        } else {
 7127            let inlay_hints_task = match for_server {
 7128                Some(server_id) => {
 7129                    let server_task = self.request_lsp(
 7130                        buffer.clone(),
 7131                        LanguageServerToQuery::Other(server_id),
 7132                        request,
 7133                        cx,
 7134                    );
 7135                    cx.background_spawn(async move {
 7136                        let mut responses = Vec::new();
 7137                        match server_task.await {
 7138                            Ok(response) => responses.push((server_id, response)),
 7139                            // rust-analyzer likes to error with this when its still loading up
 7140                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7141                            Err(e) => log::error!(
 7142                                "Error handling response for inlay hints request: {e:#}"
 7143                            ),
 7144                        }
 7145                        responses
 7146                    })
 7147                }
 7148                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7149            };
 7150            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7151            cx.background_spawn(async move {
 7152                Ok(inlay_hints_task
 7153                    .await
 7154                    .into_iter()
 7155                    .map(|(server_id, mut new_hints)| {
 7156                        new_hints.retain(|hint| {
 7157                            hint.position.is_valid(&buffer_snapshot)
 7158                                && range.start.is_valid(&buffer_snapshot)
 7159                                && range.end.is_valid(&buffer_snapshot)
 7160                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7161                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7162                        });
 7163                        (server_id, new_hints)
 7164                    })
 7165                    .collect())
 7166            })
 7167        }
 7168    }
 7169
 7170    pub fn pull_diagnostics_for_buffer(
 7171        &mut self,
 7172        buffer: Entity<Buffer>,
 7173        cx: &mut Context<Self>,
 7174    ) -> Task<anyhow::Result<()>> {
 7175        let diagnostics = self.pull_diagnostics(buffer, cx);
 7176        cx.spawn(async move |lsp_store, cx| {
 7177            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7178                return Ok(());
 7179            };
 7180            lsp_store.update(cx, |lsp_store, cx| {
 7181                if lsp_store.as_local().is_none() {
 7182                    return;
 7183                }
 7184
 7185                let mut unchanged_buffers = HashMap::default();
 7186                let server_diagnostics_updates = diagnostics
 7187                    .into_iter()
 7188                    .filter_map(|diagnostics_set| match diagnostics_set {
 7189                        LspPullDiagnostics::Response {
 7190                            server_id,
 7191                            uri,
 7192                            diagnostics,
 7193                            registration_id,
 7194                        } => Some((server_id, uri, diagnostics, registration_id)),
 7195                        LspPullDiagnostics::Default => None,
 7196                    })
 7197                    .fold(
 7198                        HashMap::default(),
 7199                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7200                            let (result_id, diagnostics) = match diagnostics {
 7201                                PulledDiagnostics::Unchanged { result_id } => {
 7202                                    unchanged_buffers
 7203                                        .entry(new_registration_id.clone())
 7204                                        .or_insert_with(HashSet::default)
 7205                                        .insert(uri.clone());
 7206                                    (Some(result_id), Vec::new())
 7207                                }
 7208                                PulledDiagnostics::Changed {
 7209                                    result_id,
 7210                                    diagnostics,
 7211                                } => (result_id, diagnostics),
 7212                            };
 7213                            let disk_based_sources = Cow::Owned(
 7214                                lsp_store
 7215                                    .language_server_adapter_for_id(server_id)
 7216                                    .as_ref()
 7217                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7218                                    .unwrap_or(&[])
 7219                                    .to_vec(),
 7220                            );
 7221                            acc.entry(server_id)
 7222                                .or_insert_with(HashMap::default)
 7223                                .entry(new_registration_id.clone())
 7224                                .or_insert_with(Vec::new)
 7225                                .push(DocumentDiagnosticsUpdate {
 7226                                    server_id,
 7227                                    diagnostics: lsp::PublishDiagnosticsParams {
 7228                                        uri,
 7229                                        diagnostics,
 7230                                        version: None,
 7231                                    },
 7232                                    result_id,
 7233                                    disk_based_sources,
 7234                                    registration_id: new_registration_id,
 7235                                });
 7236                            acc
 7237                        },
 7238                    );
 7239
 7240                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7241                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7242                        lsp_store
 7243                            .merge_lsp_diagnostics(
 7244                                DiagnosticSourceKind::Pulled,
 7245                                diagnostic_updates,
 7246                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7247                                    DiagnosticSourceKind::Pulled => {
 7248                                        old_diagnostic.registration_id != registration_id
 7249                                            || unchanged_buffers
 7250                                                .get(&old_diagnostic.registration_id)
 7251                                                .is_some_and(|unchanged_buffers| {
 7252                                                    unchanged_buffers.contains(&document_uri)
 7253                                                })
 7254                                    }
 7255                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7256                                        true
 7257                                    }
 7258                                },
 7259                                cx,
 7260                            )
 7261                            .log_err();
 7262                    }
 7263                }
 7264            })
 7265        })
 7266    }
 7267
 7268    pub fn document_colors(
 7269        &mut self,
 7270        known_cache_version: Option<usize>,
 7271        buffer: Entity<Buffer>,
 7272        cx: &mut Context<Self>,
 7273    ) -> Option<DocumentColorTask> {
 7274        let version_queried_for = buffer.read(cx).version();
 7275        let buffer_id = buffer.read(cx).remote_id();
 7276
 7277        let current_language_servers = self.as_local().map(|local| {
 7278            local
 7279                .buffers_opened_in_servers
 7280                .get(&buffer_id)
 7281                .cloned()
 7282                .unwrap_or_default()
 7283        });
 7284
 7285        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7286            if let Some(cached_colors) = &lsp_data.document_colors {
 7287                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7288                    let has_different_servers =
 7289                        current_language_servers.is_some_and(|current_language_servers| {
 7290                            current_language_servers
 7291                                != cached_colors.colors.keys().copied().collect()
 7292                        });
 7293                    if !has_different_servers {
 7294                        let cache_version = cached_colors.cache_version;
 7295                        if Some(cache_version) == known_cache_version {
 7296                            return None;
 7297                        } else {
 7298                            return Some(
 7299                                Task::ready(Ok(DocumentColors {
 7300                                    colors: cached_colors
 7301                                        .colors
 7302                                        .values()
 7303                                        .flatten()
 7304                                        .cloned()
 7305                                        .collect(),
 7306                                    cache_version: Some(cache_version),
 7307                                }))
 7308                                .shared(),
 7309                            );
 7310                        }
 7311                    }
 7312                }
 7313            }
 7314        }
 7315
 7316        let color_lsp_data = self
 7317            .latest_lsp_data(&buffer, cx)
 7318            .document_colors
 7319            .get_or_insert_default();
 7320        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7321            && !version_queried_for.changed_since(updating_for)
 7322        {
 7323            return Some(running_update.clone());
 7324        }
 7325        let buffer_version_queried_for = version_queried_for.clone();
 7326        let new_task = cx
 7327            .spawn(async move |lsp_store, cx| {
 7328                cx.background_executor()
 7329                    .timer(Duration::from_millis(30))
 7330                    .await;
 7331                let fetched_colors = lsp_store
 7332                    .update(cx, |lsp_store, cx| {
 7333                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7334                    })?
 7335                    .await
 7336                    .context("fetching document colors")
 7337                    .map_err(Arc::new);
 7338                let fetched_colors = match fetched_colors {
 7339                    Ok(fetched_colors) => {
 7340                        if Some(true)
 7341                            == buffer
 7342                                .update(cx, |buffer, _| {
 7343                                    buffer.version() != buffer_version_queried_for
 7344                                })
 7345                                .ok()
 7346                        {
 7347                            return Ok(DocumentColors::default());
 7348                        }
 7349                        fetched_colors
 7350                    }
 7351                    Err(e) => {
 7352                        lsp_store
 7353                            .update(cx, |lsp_store, _| {
 7354                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7355                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7356                                        document_colors.colors_update = None;
 7357                                    }
 7358                                }
 7359                            })
 7360                            .ok();
 7361                        return Err(e);
 7362                    }
 7363                };
 7364
 7365                lsp_store
 7366                    .update(cx, |lsp_store, cx| {
 7367                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7368                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7369
 7370                        if let Some(fetched_colors) = fetched_colors {
 7371                            if lsp_data.buffer_version == buffer_version_queried_for {
 7372                                lsp_colors.colors.extend(fetched_colors);
 7373                                lsp_colors.cache_version += 1;
 7374                            } else if !lsp_data
 7375                                .buffer_version
 7376                                .changed_since(&buffer_version_queried_for)
 7377                            {
 7378                                lsp_data.buffer_version = buffer_version_queried_for;
 7379                                lsp_colors.colors = fetched_colors;
 7380                                lsp_colors.cache_version += 1;
 7381                            }
 7382                        }
 7383                        lsp_colors.colors_update = None;
 7384                        let colors = lsp_colors
 7385                            .colors
 7386                            .values()
 7387                            .flatten()
 7388                            .cloned()
 7389                            .collect::<HashSet<_>>();
 7390                        DocumentColors {
 7391                            colors,
 7392                            cache_version: Some(lsp_colors.cache_version),
 7393                        }
 7394                    })
 7395                    .map_err(Arc::new)
 7396            })
 7397            .shared();
 7398        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7399        Some(new_task)
 7400    }
 7401
 7402    fn fetch_document_colors_for_buffer(
 7403        &mut self,
 7404        buffer: &Entity<Buffer>,
 7405        cx: &mut Context<Self>,
 7406    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7407        if let Some((client, project_id)) = self.upstream_client() {
 7408            let request = GetDocumentColor {};
 7409            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7410                return Task::ready(Ok(None));
 7411            }
 7412
 7413            let request_task = client.request_lsp(
 7414                project_id,
 7415                None,
 7416                LSP_REQUEST_TIMEOUT,
 7417                cx.background_executor().clone(),
 7418                request.to_proto(project_id, buffer.read(cx)),
 7419            );
 7420            let buffer = buffer.clone();
 7421            cx.spawn(async move |lsp_store, cx| {
 7422                let Some(lsp_store) = lsp_store.upgrade() else {
 7423                    return Ok(None);
 7424                };
 7425                let colors = join_all(
 7426                    request_task
 7427                        .await
 7428                        .log_err()
 7429                        .flatten()
 7430                        .map(|response| response.payload)
 7431                        .unwrap_or_default()
 7432                        .into_iter()
 7433                        .map(|color_response| {
 7434                            let response = request.response_from_proto(
 7435                                color_response.response,
 7436                                lsp_store.clone(),
 7437                                buffer.clone(),
 7438                                cx.clone(),
 7439                            );
 7440                            async move {
 7441                                (
 7442                                    LanguageServerId::from_proto(color_response.server_id),
 7443                                    response.await.log_err().unwrap_or_default(),
 7444                                )
 7445                            }
 7446                        }),
 7447                )
 7448                .await
 7449                .into_iter()
 7450                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7451                    acc.entry(server_id)
 7452                        .or_insert_with(HashSet::default)
 7453                        .extend(colors);
 7454                    acc
 7455                });
 7456                Ok(Some(colors))
 7457            })
 7458        } else {
 7459            let document_colors_task =
 7460                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7461            cx.background_spawn(async move {
 7462                Ok(Some(
 7463                    document_colors_task
 7464                        .await
 7465                        .into_iter()
 7466                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7467                            acc.entry(server_id)
 7468                                .or_insert_with(HashSet::default)
 7469                                .extend(colors);
 7470                            acc
 7471                        })
 7472                        .into_iter()
 7473                        .collect(),
 7474                ))
 7475            })
 7476        }
 7477    }
 7478
 7479    pub fn signature_help<T: ToPointUtf16>(
 7480        &mut self,
 7481        buffer: &Entity<Buffer>,
 7482        position: T,
 7483        cx: &mut Context<Self>,
 7484    ) -> Task<Option<Vec<SignatureHelp>>> {
 7485        let position = position.to_point_utf16(buffer.read(cx));
 7486
 7487        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7488            let request = GetSignatureHelp { position };
 7489            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7490                return Task::ready(None);
 7491            }
 7492            let request_task = client.request_lsp(
 7493                upstream_project_id,
 7494                None,
 7495                LSP_REQUEST_TIMEOUT,
 7496                cx.background_executor().clone(),
 7497                request.to_proto(upstream_project_id, buffer.read(cx)),
 7498            );
 7499            let buffer = buffer.clone();
 7500            cx.spawn(async move |weak_lsp_store, cx| {
 7501                let lsp_store = weak_lsp_store.upgrade()?;
 7502                let signatures = join_all(
 7503                    request_task
 7504                        .await
 7505                        .log_err()
 7506                        .flatten()
 7507                        .map(|response| response.payload)
 7508                        .unwrap_or_default()
 7509                        .into_iter()
 7510                        .map(|response| {
 7511                            let response = GetSignatureHelp { position }.response_from_proto(
 7512                                response.response,
 7513                                lsp_store.clone(),
 7514                                buffer.clone(),
 7515                                cx.clone(),
 7516                            );
 7517                            async move { response.await.log_err().flatten() }
 7518                        }),
 7519                )
 7520                .await
 7521                .into_iter()
 7522                .flatten()
 7523                .collect();
 7524                Some(signatures)
 7525            })
 7526        } else {
 7527            let all_actions_task = self.request_multiple_lsp_locally(
 7528                buffer,
 7529                Some(position),
 7530                GetSignatureHelp { position },
 7531                cx,
 7532            );
 7533            cx.background_spawn(async move {
 7534                Some(
 7535                    all_actions_task
 7536                        .await
 7537                        .into_iter()
 7538                        .flat_map(|(_, actions)| actions)
 7539                        .collect::<Vec<_>>(),
 7540                )
 7541            })
 7542        }
 7543    }
 7544
 7545    pub fn hover(
 7546        &mut self,
 7547        buffer: &Entity<Buffer>,
 7548        position: PointUtf16,
 7549        cx: &mut Context<Self>,
 7550    ) -> Task<Option<Vec<Hover>>> {
 7551        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7552            let request = GetHover { position };
 7553            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7554                return Task::ready(None);
 7555            }
 7556            let request_task = client.request_lsp(
 7557                upstream_project_id,
 7558                None,
 7559                LSP_REQUEST_TIMEOUT,
 7560                cx.background_executor().clone(),
 7561                request.to_proto(upstream_project_id, buffer.read(cx)),
 7562            );
 7563            let buffer = buffer.clone();
 7564            cx.spawn(async move |weak_lsp_store, cx| {
 7565                let lsp_store = weak_lsp_store.upgrade()?;
 7566                let hovers = join_all(
 7567                    request_task
 7568                        .await
 7569                        .log_err()
 7570                        .flatten()
 7571                        .map(|response| response.payload)
 7572                        .unwrap_or_default()
 7573                        .into_iter()
 7574                        .map(|response| {
 7575                            let response = GetHover { position }.response_from_proto(
 7576                                response.response,
 7577                                lsp_store.clone(),
 7578                                buffer.clone(),
 7579                                cx.clone(),
 7580                            );
 7581                            async move {
 7582                                response
 7583                                    .await
 7584                                    .log_err()
 7585                                    .flatten()
 7586                                    .and_then(remove_empty_hover_blocks)
 7587                            }
 7588                        }),
 7589                )
 7590                .await
 7591                .into_iter()
 7592                .flatten()
 7593                .collect();
 7594                Some(hovers)
 7595            })
 7596        } else {
 7597            let all_actions_task = self.request_multiple_lsp_locally(
 7598                buffer,
 7599                Some(position),
 7600                GetHover { position },
 7601                cx,
 7602            );
 7603            cx.background_spawn(async move {
 7604                Some(
 7605                    all_actions_task
 7606                        .await
 7607                        .into_iter()
 7608                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7609                        .collect::<Vec<Hover>>(),
 7610                )
 7611            })
 7612        }
 7613    }
 7614
 7615    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7616        let language_registry = self.languages.clone();
 7617
 7618        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7619            let request = upstream_client.request(proto::GetProjectSymbols {
 7620                project_id: *project_id,
 7621                query: query.to_string(),
 7622            });
 7623            cx.foreground_executor().spawn(async move {
 7624                let response = request.await?;
 7625                let mut symbols = Vec::new();
 7626                let core_symbols = response
 7627                    .symbols
 7628                    .into_iter()
 7629                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7630                    .collect::<Vec<_>>();
 7631                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7632                    .await;
 7633                Ok(symbols)
 7634            })
 7635        } else if let Some(local) = self.as_local() {
 7636            struct WorkspaceSymbolsResult {
 7637                server_id: LanguageServerId,
 7638                lsp_adapter: Arc<CachedLspAdapter>,
 7639                worktree: WeakEntity<Worktree>,
 7640                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7641            }
 7642
 7643            let mut requests = Vec::new();
 7644            let mut requested_servers = BTreeSet::new();
 7645            for (seed, state) in local.language_server_ids.iter() {
 7646                let Some(worktree_handle) = self
 7647                    .worktree_store
 7648                    .read(cx)
 7649                    .worktree_for_id(seed.worktree_id, cx)
 7650                else {
 7651                    continue;
 7652                };
 7653                let worktree = worktree_handle.read(cx);
 7654                if !worktree.is_visible() {
 7655                    continue;
 7656                }
 7657
 7658                if !requested_servers.insert(state.id) {
 7659                    continue;
 7660                }
 7661
 7662                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7663                    Some(LanguageServerState::Running {
 7664                        adapter, server, ..
 7665                    }) => (adapter.clone(), server),
 7666
 7667                    _ => continue,
 7668                };
 7669                let supports_workspace_symbol_request =
 7670                    match server.capabilities().workspace_symbol_provider {
 7671                        Some(OneOf::Left(supported)) => supported,
 7672                        Some(OneOf::Right(_)) => true,
 7673                        None => false,
 7674                    };
 7675                if !supports_workspace_symbol_request {
 7676                    continue;
 7677                }
 7678                let worktree_handle = worktree_handle.clone();
 7679                let server_id = server.server_id();
 7680                requests.push(
 7681                        server
 7682                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7683                                lsp::WorkspaceSymbolParams {
 7684                                    query: query.to_string(),
 7685                                    ..Default::default()
 7686                                },
 7687                            )
 7688                            .map(move |response| {
 7689                                let lsp_symbols = response.into_response()
 7690                                    .context("workspace symbols request")
 7691                                    .log_err()
 7692                                    .flatten()
 7693                                    .map(|symbol_response| match symbol_response {
 7694                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7695                                            flat_responses.into_iter().map(|lsp_symbol| {
 7696                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7697                                            }).collect::<Vec<_>>()
 7698                                        }
 7699                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7700                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7701                                                let location = match lsp_symbol.location {
 7702                                                    OneOf::Left(location) => location,
 7703                                                    OneOf::Right(_) => {
 7704                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7705                                                        return None
 7706                                                    }
 7707                                                };
 7708                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7709                                            }).collect::<Vec<_>>()
 7710                                        }
 7711                                    }).unwrap_or_default();
 7712
 7713                                WorkspaceSymbolsResult {
 7714                                    server_id,
 7715                                    lsp_adapter,
 7716                                    worktree: worktree_handle.downgrade(),
 7717                                    lsp_symbols,
 7718                                }
 7719                            }),
 7720                    );
 7721            }
 7722
 7723            cx.spawn(async move |this, cx| {
 7724                let responses = futures::future::join_all(requests).await;
 7725                let this = match this.upgrade() {
 7726                    Some(this) => this,
 7727                    None => return Ok(Vec::new()),
 7728                };
 7729
 7730                let mut symbols = Vec::new();
 7731                for result in responses {
 7732                    let core_symbols = this.update(cx, |this, cx| {
 7733                        result
 7734                            .lsp_symbols
 7735                            .into_iter()
 7736                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7737                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7738                                let source_worktree = result.worktree.upgrade()?;
 7739                                let source_worktree_id = source_worktree.read(cx).id();
 7740
 7741                                let path = if let Some((tree, rel_path)) =
 7742                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7743                                {
 7744                                    let worktree_id = tree.read(cx).id();
 7745                                    SymbolLocation::InProject(ProjectPath {
 7746                                        worktree_id,
 7747                                        path: rel_path,
 7748                                    })
 7749                                } else {
 7750                                    SymbolLocation::OutsideProject {
 7751                                        signature: this.symbol_signature(&abs_path),
 7752                                        abs_path: abs_path.into(),
 7753                                    }
 7754                                };
 7755
 7756                                Some(CoreSymbol {
 7757                                    source_language_server_id: result.server_id,
 7758                                    language_server_name: result.lsp_adapter.name.clone(),
 7759                                    source_worktree_id,
 7760                                    path,
 7761                                    kind: symbol_kind,
 7762                                    name: symbol_name,
 7763                                    range: range_from_lsp(symbol_location.range),
 7764                                })
 7765                            })
 7766                            .collect()
 7767                    })?;
 7768
 7769                    populate_labels_for_symbols(
 7770                        core_symbols,
 7771                        &language_registry,
 7772                        Some(result.lsp_adapter),
 7773                        &mut symbols,
 7774                    )
 7775                    .await;
 7776                }
 7777
 7778                Ok(symbols)
 7779            })
 7780        } else {
 7781            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7782        }
 7783    }
 7784
 7785    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7786        let mut summary = DiagnosticSummary::default();
 7787        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7788            summary.error_count += path_summary.error_count;
 7789            summary.warning_count += path_summary.warning_count;
 7790        }
 7791        summary
 7792    }
 7793
 7794    /// Returns the diagnostic summary for a specific project path.
 7795    pub fn diagnostic_summary_for_path(
 7796        &self,
 7797        project_path: &ProjectPath,
 7798        _: &App,
 7799    ) -> DiagnosticSummary {
 7800        if let Some(summaries) = self
 7801            .diagnostic_summaries
 7802            .get(&project_path.worktree_id)
 7803            .and_then(|map| map.get(&project_path.path))
 7804        {
 7805            let (error_count, warning_count) = summaries.iter().fold(
 7806                (0, 0),
 7807                |(error_count, warning_count), (_language_server_id, summary)| {
 7808                    (
 7809                        error_count + summary.error_count,
 7810                        warning_count + summary.warning_count,
 7811                    )
 7812                },
 7813            );
 7814
 7815            DiagnosticSummary {
 7816                error_count,
 7817                warning_count,
 7818            }
 7819        } else {
 7820            DiagnosticSummary::default()
 7821        }
 7822    }
 7823
 7824    pub fn diagnostic_summaries<'a>(
 7825        &'a self,
 7826        include_ignored: bool,
 7827        cx: &'a App,
 7828    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7829        self.worktree_store
 7830            .read(cx)
 7831            .visible_worktrees(cx)
 7832            .filter_map(|worktree| {
 7833                let worktree = worktree.read(cx);
 7834                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7835            })
 7836            .flat_map(move |(worktree, summaries)| {
 7837                let worktree_id = worktree.id();
 7838                summaries
 7839                    .iter()
 7840                    .filter(move |(path, _)| {
 7841                        include_ignored
 7842                            || worktree
 7843                                .entry_for_path(path.as_ref())
 7844                                .is_some_and(|entry| !entry.is_ignored)
 7845                    })
 7846                    .flat_map(move |(path, summaries)| {
 7847                        summaries.iter().map(move |(server_id, summary)| {
 7848                            (
 7849                                ProjectPath {
 7850                                    worktree_id,
 7851                                    path: path.clone(),
 7852                                },
 7853                                *server_id,
 7854                                *summary,
 7855                            )
 7856                        })
 7857                    })
 7858            })
 7859    }
 7860
 7861    pub fn on_buffer_edited(
 7862        &mut self,
 7863        buffer: Entity<Buffer>,
 7864        cx: &mut Context<Self>,
 7865    ) -> Option<()> {
 7866        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7867            Some(
 7868                self.as_local()?
 7869                    .language_servers_for_buffer(buffer, cx)
 7870                    .map(|i| i.1.clone())
 7871                    .collect(),
 7872            )
 7873        })?;
 7874
 7875        let buffer = buffer.read(cx);
 7876        let file = File::from_dyn(buffer.file())?;
 7877        let abs_path = file.as_local()?.abs_path(cx);
 7878        let uri = lsp::Uri::from_file_path(&abs_path)
 7879            .ok()
 7880            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7881            .log_err()?;
 7882        let next_snapshot = buffer.text_snapshot();
 7883        for language_server in language_servers {
 7884            let language_server = language_server.clone();
 7885
 7886            let buffer_snapshots = self
 7887                .as_local_mut()?
 7888                .buffer_snapshots
 7889                .get_mut(&buffer.remote_id())
 7890                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7891            let previous_snapshot = buffer_snapshots.last()?;
 7892
 7893            let build_incremental_change = || {
 7894                buffer
 7895                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7896                        previous_snapshot.snapshot.version(),
 7897                    )
 7898                    .map(|edit| {
 7899                        let edit_start = edit.new.start.0;
 7900                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7901                        let new_text = next_snapshot
 7902                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7903                            .collect();
 7904                        lsp::TextDocumentContentChangeEvent {
 7905                            range: Some(lsp::Range::new(
 7906                                point_to_lsp(edit_start),
 7907                                point_to_lsp(edit_end),
 7908                            )),
 7909                            range_length: None,
 7910                            text: new_text,
 7911                        }
 7912                    })
 7913                    .collect()
 7914            };
 7915
 7916            let document_sync_kind = language_server
 7917                .capabilities()
 7918                .text_document_sync
 7919                .as_ref()
 7920                .and_then(|sync| match sync {
 7921                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7922                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7923                });
 7924
 7925            let content_changes: Vec<_> = match document_sync_kind {
 7926                Some(lsp::TextDocumentSyncKind::FULL) => {
 7927                    vec![lsp::TextDocumentContentChangeEvent {
 7928                        range: None,
 7929                        range_length: None,
 7930                        text: next_snapshot.text(),
 7931                    }]
 7932                }
 7933                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7934                _ => {
 7935                    #[cfg(any(test, feature = "test-support"))]
 7936                    {
 7937                        build_incremental_change()
 7938                    }
 7939
 7940                    #[cfg(not(any(test, feature = "test-support")))]
 7941                    {
 7942                        continue;
 7943                    }
 7944                }
 7945            };
 7946
 7947            let next_version = previous_snapshot.version + 1;
 7948            buffer_snapshots.push(LspBufferSnapshot {
 7949                version: next_version,
 7950                snapshot: next_snapshot.clone(),
 7951            });
 7952
 7953            language_server
 7954                .notify::<lsp::notification::DidChangeTextDocument>(
 7955                    lsp::DidChangeTextDocumentParams {
 7956                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7957                            uri.clone(),
 7958                            next_version,
 7959                        ),
 7960                        content_changes,
 7961                    },
 7962                )
 7963                .ok();
 7964            self.pull_workspace_diagnostics(language_server.server_id());
 7965        }
 7966
 7967        None
 7968    }
 7969
 7970    pub fn on_buffer_saved(
 7971        &mut self,
 7972        buffer: Entity<Buffer>,
 7973        cx: &mut Context<Self>,
 7974    ) -> Option<()> {
 7975        let file = File::from_dyn(buffer.read(cx).file())?;
 7976        let worktree_id = file.worktree_id(cx);
 7977        let abs_path = file.as_local()?.abs_path(cx);
 7978        let text_document = lsp::TextDocumentIdentifier {
 7979            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7980        };
 7981        let local = self.as_local()?;
 7982
 7983        for server in local.language_servers_for_worktree(worktree_id) {
 7984            if let Some(include_text) = include_text(server.as_ref()) {
 7985                let text = if include_text {
 7986                    Some(buffer.read(cx).text())
 7987                } else {
 7988                    None
 7989                };
 7990                server
 7991                    .notify::<lsp::notification::DidSaveTextDocument>(
 7992                        lsp::DidSaveTextDocumentParams {
 7993                            text_document: text_document.clone(),
 7994                            text,
 7995                        },
 7996                    )
 7997                    .ok();
 7998            }
 7999        }
 8000
 8001        let language_servers = buffer.update(cx, |buffer, cx| {
 8002            local.language_server_ids_for_buffer(buffer, cx)
 8003        });
 8004        for language_server_id in language_servers {
 8005            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8006        }
 8007
 8008        None
 8009    }
 8010
 8011    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8012        maybe!(async move {
 8013            let mut refreshed_servers = HashSet::default();
 8014            let servers = lsp_store
 8015                .update(cx, |lsp_store, cx| {
 8016                    let local = lsp_store.as_local()?;
 8017
 8018                    let servers = local
 8019                        .language_server_ids
 8020                        .iter()
 8021                        .filter_map(|(seed, state)| {
 8022                            let worktree = lsp_store
 8023                                .worktree_store
 8024                                .read(cx)
 8025                                .worktree_for_id(seed.worktree_id, cx);
 8026                            let delegate: Arc<dyn LspAdapterDelegate> =
 8027                                worktree.map(|worktree| {
 8028                                    LocalLspAdapterDelegate::new(
 8029                                        local.languages.clone(),
 8030                                        &local.environment,
 8031                                        cx.weak_entity(),
 8032                                        &worktree,
 8033                                        local.http_client.clone(),
 8034                                        local.fs.clone(),
 8035                                        cx,
 8036                                    )
 8037                                })?;
 8038                            let server_id = state.id;
 8039
 8040                            let states = local.language_servers.get(&server_id)?;
 8041
 8042                            match states {
 8043                                LanguageServerState::Starting { .. } => None,
 8044                                LanguageServerState::Running {
 8045                                    adapter, server, ..
 8046                                } => {
 8047                                    let adapter = adapter.clone();
 8048                                    let server = server.clone();
 8049                                    refreshed_servers.insert(server.name());
 8050                                    let toolchain = seed.toolchain.clone();
 8051                                    Some(cx.spawn(async move |_, cx| {
 8052                                        let settings =
 8053                                            LocalLspStore::workspace_configuration_for_adapter(
 8054                                                adapter.adapter.clone(),
 8055                                                &delegate,
 8056                                                toolchain,
 8057                                                None,
 8058                                                cx,
 8059                                            )
 8060                                            .await
 8061                                            .ok()?;
 8062                                        server
 8063                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8064                                                lsp::DidChangeConfigurationParams { settings },
 8065                                            )
 8066                                            .ok()?;
 8067                                        Some(())
 8068                                    }))
 8069                                }
 8070                            }
 8071                        })
 8072                        .collect::<Vec<_>>();
 8073
 8074                    Some(servers)
 8075                })
 8076                .ok()
 8077                .flatten()?;
 8078
 8079            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8080            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8081            // to stop and unregister its language server wrapper.
 8082            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8083            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8084            let _: Vec<Option<()>> = join_all(servers).await;
 8085
 8086            Some(())
 8087        })
 8088        .await;
 8089    }
 8090
 8091    fn maintain_workspace_config(
 8092        external_refresh_requests: watch::Receiver<()>,
 8093        cx: &mut Context<Self>,
 8094    ) -> Task<Result<()>> {
 8095        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8096        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8097
 8098        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8099            *settings_changed_tx.borrow_mut() = ();
 8100        });
 8101
 8102        let mut joint_future =
 8103            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8104        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8105        // - 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).
 8106        // - 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.
 8107        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8108        // - 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,
 8109        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8110        cx.spawn(async move |this, cx| {
 8111            while let Some(()) = joint_future.next().await {
 8112                this.update(cx, |this, cx| {
 8113                    this.refresh_server_tree(cx);
 8114                })
 8115                .ok();
 8116
 8117                Self::refresh_workspace_configurations(&this, cx).await;
 8118            }
 8119
 8120            drop(settings_observation);
 8121            anyhow::Ok(())
 8122        })
 8123    }
 8124
 8125    pub fn language_servers_for_local_buffer<'a>(
 8126        &'a self,
 8127        buffer: &Buffer,
 8128        cx: &mut App,
 8129    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8130        let local = self.as_local();
 8131        let language_server_ids = local
 8132            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8133            .unwrap_or_default();
 8134
 8135        language_server_ids
 8136            .into_iter()
 8137            .filter_map(
 8138                move |server_id| match local?.language_servers.get(&server_id)? {
 8139                    LanguageServerState::Running {
 8140                        adapter, server, ..
 8141                    } => Some((adapter, server)),
 8142                    _ => None,
 8143                },
 8144            )
 8145    }
 8146
 8147    pub fn language_server_for_local_buffer<'a>(
 8148        &'a self,
 8149        buffer: &'a Buffer,
 8150        server_id: LanguageServerId,
 8151        cx: &'a mut App,
 8152    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8153        self.as_local()?
 8154            .language_servers_for_buffer(buffer, cx)
 8155            .find(|(_, s)| s.server_id() == server_id)
 8156    }
 8157
 8158    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8159        self.diagnostic_summaries.remove(&id_to_remove);
 8160        if let Some(local) = self.as_local_mut() {
 8161            let to_remove = local.remove_worktree(id_to_remove, cx);
 8162            for server in to_remove {
 8163                self.language_server_statuses.remove(&server);
 8164            }
 8165        }
 8166    }
 8167
 8168    pub fn shared(
 8169        &mut self,
 8170        project_id: u64,
 8171        downstream_client: AnyProtoClient,
 8172        _: &mut Context<Self>,
 8173    ) {
 8174        self.downstream_client = Some((downstream_client.clone(), project_id));
 8175
 8176        for (server_id, status) in &self.language_server_statuses {
 8177            if let Some(server) = self.language_server_for_id(*server_id) {
 8178                downstream_client
 8179                    .send(proto::StartLanguageServer {
 8180                        project_id,
 8181                        server: Some(proto::LanguageServer {
 8182                            id: server_id.to_proto(),
 8183                            name: status.name.to_string(),
 8184                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8185                        }),
 8186                        capabilities: serde_json::to_string(&server.capabilities())
 8187                            .expect("serializing server LSP capabilities"),
 8188                    })
 8189                    .log_err();
 8190            }
 8191        }
 8192    }
 8193
 8194    pub fn disconnected_from_host(&mut self) {
 8195        self.downstream_client.take();
 8196    }
 8197
 8198    pub fn disconnected_from_ssh_remote(&mut self) {
 8199        if let LspStoreMode::Remote(RemoteLspStore {
 8200            upstream_client, ..
 8201        }) = &mut self.mode
 8202        {
 8203            upstream_client.take();
 8204        }
 8205    }
 8206
 8207    pub(crate) fn set_language_server_statuses_from_proto(
 8208        &mut self,
 8209        project: WeakEntity<Project>,
 8210        language_servers: Vec<proto::LanguageServer>,
 8211        server_capabilities: Vec<String>,
 8212        cx: &mut Context<Self>,
 8213    ) {
 8214        let lsp_logs = cx
 8215            .try_global::<GlobalLogStore>()
 8216            .map(|lsp_store| lsp_store.0.clone());
 8217
 8218        self.language_server_statuses = language_servers
 8219            .into_iter()
 8220            .zip(server_capabilities)
 8221            .map(|(server, server_capabilities)| {
 8222                let server_id = LanguageServerId(server.id as usize);
 8223                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8224                    self.lsp_server_capabilities
 8225                        .insert(server_id, server_capabilities);
 8226                }
 8227
 8228                let name = LanguageServerName::from_proto(server.name);
 8229                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8230
 8231                if let Some(lsp_logs) = &lsp_logs {
 8232                    lsp_logs.update(cx, |lsp_logs, cx| {
 8233                        lsp_logs.add_language_server(
 8234                            // Only remote clients get their language servers set from proto
 8235                            LanguageServerKind::Remote {
 8236                                project: project.clone(),
 8237                            },
 8238                            server_id,
 8239                            Some(name.clone()),
 8240                            worktree,
 8241                            None,
 8242                            cx,
 8243                        );
 8244                    });
 8245                }
 8246
 8247                (
 8248                    server_id,
 8249                    LanguageServerStatus {
 8250                        name,
 8251                        pending_work: Default::default(),
 8252                        has_pending_diagnostic_updates: false,
 8253                        progress_tokens: Default::default(),
 8254                        worktree,
 8255                        binary: None,
 8256                        configuration: None,
 8257                        workspace_folders: BTreeSet::new(),
 8258                    },
 8259                )
 8260            })
 8261            .collect();
 8262    }
 8263
 8264    #[cfg(test)]
 8265    pub fn update_diagnostic_entries(
 8266        &mut self,
 8267        server_id: LanguageServerId,
 8268        abs_path: PathBuf,
 8269        result_id: Option<SharedString>,
 8270        version: Option<i32>,
 8271        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8272        cx: &mut Context<Self>,
 8273    ) -> anyhow::Result<()> {
 8274        self.merge_diagnostic_entries(
 8275            vec![DocumentDiagnosticsUpdate {
 8276                diagnostics: DocumentDiagnostics {
 8277                    diagnostics,
 8278                    document_abs_path: abs_path,
 8279                    version,
 8280                },
 8281                result_id,
 8282                server_id,
 8283                disk_based_sources: Cow::Borrowed(&[]),
 8284                registration_id: None,
 8285            }],
 8286            |_, _, _| false,
 8287            cx,
 8288        )?;
 8289        Ok(())
 8290    }
 8291
 8292    pub fn merge_diagnostic_entries<'a>(
 8293        &mut self,
 8294        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8295        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8296        cx: &mut Context<Self>,
 8297    ) -> anyhow::Result<()> {
 8298        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8299        let mut updated_diagnostics_paths = HashMap::default();
 8300        for mut update in diagnostic_updates {
 8301            let abs_path = &update.diagnostics.document_abs_path;
 8302            let server_id = update.server_id;
 8303            let Some((worktree, relative_path)) =
 8304                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8305            else {
 8306                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8307                return Ok(());
 8308            };
 8309
 8310            let worktree_id = worktree.read(cx).id();
 8311            let project_path = ProjectPath {
 8312                worktree_id,
 8313                path: relative_path,
 8314            };
 8315
 8316            let document_uri = lsp::Uri::from_file_path(abs_path)
 8317                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8318            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8319                let snapshot = buffer_handle.read(cx).snapshot();
 8320                let buffer = buffer_handle.read(cx);
 8321                let reused_diagnostics = buffer
 8322                    .buffer_diagnostics(Some(server_id))
 8323                    .iter()
 8324                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8325                    .map(|v| {
 8326                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8327                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8328                        DiagnosticEntry {
 8329                            range: start..end,
 8330                            diagnostic: v.diagnostic.clone(),
 8331                        }
 8332                    })
 8333                    .collect::<Vec<_>>();
 8334
 8335                self.as_local_mut()
 8336                    .context("cannot merge diagnostics on a remote LspStore")?
 8337                    .update_buffer_diagnostics(
 8338                        &buffer_handle,
 8339                        server_id,
 8340                        Some(update.registration_id),
 8341                        update.result_id,
 8342                        update.diagnostics.version,
 8343                        update.diagnostics.diagnostics.clone(),
 8344                        reused_diagnostics.clone(),
 8345                        cx,
 8346                    )?;
 8347
 8348                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8349            } else if let Some(local) = self.as_local() {
 8350                let reused_diagnostics = local
 8351                    .diagnostics
 8352                    .get(&worktree_id)
 8353                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8354                    .and_then(|diagnostics_by_server_id| {
 8355                        diagnostics_by_server_id
 8356                            .binary_search_by_key(&server_id, |e| e.0)
 8357                            .ok()
 8358                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8359                    })
 8360                    .into_iter()
 8361                    .flatten()
 8362                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8363
 8364                update
 8365                    .diagnostics
 8366                    .diagnostics
 8367                    .extend(reused_diagnostics.cloned());
 8368            }
 8369
 8370            let updated = worktree.update(cx, |worktree, cx| {
 8371                self.update_worktree_diagnostics(
 8372                    worktree.id(),
 8373                    server_id,
 8374                    project_path.path.clone(),
 8375                    update.diagnostics.diagnostics,
 8376                    cx,
 8377                )
 8378            })?;
 8379            match updated {
 8380                ControlFlow::Continue(new_summary) => {
 8381                    if let Some((project_id, new_summary)) = new_summary {
 8382                        match &mut diagnostics_summary {
 8383                            Some(diagnostics_summary) => {
 8384                                diagnostics_summary
 8385                                    .more_summaries
 8386                                    .push(proto::DiagnosticSummary {
 8387                                        path: project_path.path.as_ref().to_proto(),
 8388                                        language_server_id: server_id.0 as u64,
 8389                                        error_count: new_summary.error_count,
 8390                                        warning_count: new_summary.warning_count,
 8391                                    })
 8392                            }
 8393                            None => {
 8394                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8395                                    project_id,
 8396                                    worktree_id: worktree_id.to_proto(),
 8397                                    summary: Some(proto::DiagnosticSummary {
 8398                                        path: project_path.path.as_ref().to_proto(),
 8399                                        language_server_id: server_id.0 as u64,
 8400                                        error_count: new_summary.error_count,
 8401                                        warning_count: new_summary.warning_count,
 8402                                    }),
 8403                                    more_summaries: Vec::new(),
 8404                                })
 8405                            }
 8406                        }
 8407                    }
 8408                    updated_diagnostics_paths
 8409                        .entry(server_id)
 8410                        .or_insert_with(Vec::new)
 8411                        .push(project_path);
 8412                }
 8413                ControlFlow::Break(()) => {}
 8414            }
 8415        }
 8416
 8417        if let Some((diagnostics_summary, (downstream_client, _))) =
 8418            diagnostics_summary.zip(self.downstream_client.as_ref())
 8419        {
 8420            downstream_client.send(diagnostics_summary).log_err();
 8421        }
 8422        for (server_id, paths) in updated_diagnostics_paths {
 8423            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8424        }
 8425        Ok(())
 8426    }
 8427
 8428    fn update_worktree_diagnostics(
 8429        &mut self,
 8430        worktree_id: WorktreeId,
 8431        server_id: LanguageServerId,
 8432        path_in_worktree: Arc<RelPath>,
 8433        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8434        _: &mut Context<Worktree>,
 8435    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8436        let local = match &mut self.mode {
 8437            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8438            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8439        };
 8440
 8441        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8442        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8443        let summaries_by_server_id = summaries_for_tree
 8444            .entry(path_in_worktree.clone())
 8445            .or_default();
 8446
 8447        let old_summary = summaries_by_server_id
 8448            .remove(&server_id)
 8449            .unwrap_or_default();
 8450
 8451        let new_summary = DiagnosticSummary::new(&diagnostics);
 8452        if diagnostics.is_empty() {
 8453            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8454            {
 8455                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8456                    diagnostics_by_server_id.remove(ix);
 8457                }
 8458                if diagnostics_by_server_id.is_empty() {
 8459                    diagnostics_for_tree.remove(&path_in_worktree);
 8460                }
 8461            }
 8462        } else {
 8463            summaries_by_server_id.insert(server_id, new_summary);
 8464            let diagnostics_by_server_id = diagnostics_for_tree
 8465                .entry(path_in_worktree.clone())
 8466                .or_default();
 8467            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8468                Ok(ix) => {
 8469                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8470                }
 8471                Err(ix) => {
 8472                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8473                }
 8474            }
 8475        }
 8476
 8477        if !old_summary.is_empty() || !new_summary.is_empty() {
 8478            if let Some((_, project_id)) = &self.downstream_client {
 8479                Ok(ControlFlow::Continue(Some((
 8480                    *project_id,
 8481                    proto::DiagnosticSummary {
 8482                        path: path_in_worktree.to_proto(),
 8483                        language_server_id: server_id.0 as u64,
 8484                        error_count: new_summary.error_count as u32,
 8485                        warning_count: new_summary.warning_count as u32,
 8486                    },
 8487                ))))
 8488            } else {
 8489                Ok(ControlFlow::Continue(None))
 8490            }
 8491        } else {
 8492            Ok(ControlFlow::Break(()))
 8493        }
 8494    }
 8495
 8496    pub fn open_buffer_for_symbol(
 8497        &mut self,
 8498        symbol: &Symbol,
 8499        cx: &mut Context<Self>,
 8500    ) -> Task<Result<Entity<Buffer>>> {
 8501        if let Some((client, project_id)) = self.upstream_client() {
 8502            let request = client.request(proto::OpenBufferForSymbol {
 8503                project_id,
 8504                symbol: Some(Self::serialize_symbol(symbol)),
 8505            });
 8506            cx.spawn(async move |this, cx| {
 8507                let response = request.await?;
 8508                let buffer_id = BufferId::new(response.buffer_id)?;
 8509                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8510                    .await
 8511            })
 8512        } else if let Some(local) = self.as_local() {
 8513            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8514                seed.worktree_id == symbol.source_worktree_id
 8515                    && state.id == symbol.source_language_server_id
 8516                    && symbol.language_server_name == seed.name
 8517            });
 8518            if !is_valid {
 8519                return Task::ready(Err(anyhow!(
 8520                    "language server for worktree and language not found"
 8521                )));
 8522            };
 8523
 8524            let symbol_abs_path = match &symbol.path {
 8525                SymbolLocation::InProject(project_path) => self
 8526                    .worktree_store
 8527                    .read(cx)
 8528                    .absolutize(&project_path, cx)
 8529                    .context("no such worktree"),
 8530                SymbolLocation::OutsideProject {
 8531                    abs_path,
 8532                    signature: _,
 8533                } => Ok(abs_path.to_path_buf()),
 8534            };
 8535            let symbol_abs_path = match symbol_abs_path {
 8536                Ok(abs_path) => abs_path,
 8537                Err(err) => return Task::ready(Err(err)),
 8538            };
 8539            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8540                uri
 8541            } else {
 8542                return Task::ready(Err(anyhow!("invalid symbol path")));
 8543            };
 8544
 8545            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8546        } else {
 8547            Task::ready(Err(anyhow!("no upstream client or local store")))
 8548        }
 8549    }
 8550
 8551    pub(crate) fn open_local_buffer_via_lsp(
 8552        &mut self,
 8553        abs_path: lsp::Uri,
 8554        language_server_id: LanguageServerId,
 8555        cx: &mut Context<Self>,
 8556    ) -> Task<Result<Entity<Buffer>>> {
 8557        cx.spawn(async move |lsp_store, cx| {
 8558            // Escape percent-encoded string.
 8559            let current_scheme = abs_path.scheme().to_owned();
 8560            // Uri is immutable, so we can't modify the scheme
 8561
 8562            let abs_path = abs_path
 8563                .to_file_path()
 8564                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8565            let p = abs_path.clone();
 8566            let yarn_worktree = lsp_store
 8567                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8568                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8569                        cx.spawn(async move |this, cx| {
 8570                            let t = this
 8571                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8572                                .ok()?;
 8573                            t.await
 8574                        })
 8575                    }),
 8576                    None => Task::ready(None),
 8577                })?
 8578                .await;
 8579            let (worktree_root_target, known_relative_path) =
 8580                if let Some((zip_root, relative_path)) = yarn_worktree {
 8581                    (zip_root, Some(relative_path))
 8582                } else {
 8583                    (Arc::<Path>::from(abs_path.as_path()), None)
 8584                };
 8585            let (worktree, relative_path) = if let Some(result) =
 8586                lsp_store.update(cx, |lsp_store, cx| {
 8587                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8588                        worktree_store.find_worktree(&worktree_root_target, cx)
 8589                    })
 8590                })? {
 8591                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8592                (result.0, relative_path)
 8593            } else {
 8594                let worktree = lsp_store
 8595                    .update(cx, |lsp_store, cx| {
 8596                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8597                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8598                        })
 8599                    })?
 8600                    .await?;
 8601                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8602                    lsp_store
 8603                        .update(cx, |lsp_store, cx| {
 8604                            if let Some(local) = lsp_store.as_local_mut() {
 8605                                local.register_language_server_for_invisible_worktree(
 8606                                    &worktree,
 8607                                    language_server_id,
 8608                                    cx,
 8609                                )
 8610                            }
 8611                        })
 8612                        .ok();
 8613                }
 8614                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8615                let relative_path = if let Some(known_path) = known_relative_path {
 8616                    known_path
 8617                } else {
 8618                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8619                        .into_arc()
 8620                };
 8621                (worktree, relative_path)
 8622            };
 8623            let project_path = ProjectPath {
 8624                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8625                path: relative_path,
 8626            };
 8627            lsp_store
 8628                .update(cx, |lsp_store, cx| {
 8629                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8630                        buffer_store.open_buffer(project_path, cx)
 8631                    })
 8632                })?
 8633                .await
 8634        })
 8635    }
 8636
 8637    fn request_multiple_lsp_locally<P, R>(
 8638        &mut self,
 8639        buffer: &Entity<Buffer>,
 8640        position: Option<P>,
 8641        request: R,
 8642        cx: &mut Context<Self>,
 8643    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8644    where
 8645        P: ToOffset,
 8646        R: LspCommand + Clone,
 8647        <R::LspRequest as lsp::request::Request>::Result: Send,
 8648        <R::LspRequest as lsp::request::Request>::Params: Send,
 8649    {
 8650        let Some(local) = self.as_local() else {
 8651            return Task::ready(Vec::new());
 8652        };
 8653
 8654        let snapshot = buffer.read(cx).snapshot();
 8655        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8656
 8657        let server_ids = buffer.update(cx, |buffer, cx| {
 8658            local
 8659                .language_servers_for_buffer(buffer, cx)
 8660                .filter(|(adapter, _)| {
 8661                    scope
 8662                        .as_ref()
 8663                        .map(|scope| scope.language_allowed(&adapter.name))
 8664                        .unwrap_or(true)
 8665                })
 8666                .map(|(_, server)| server.server_id())
 8667                .filter(|server_id| {
 8668                    self.as_local().is_none_or(|local| {
 8669                        local
 8670                            .buffers_opened_in_servers
 8671                            .get(&snapshot.remote_id())
 8672                            .is_some_and(|servers| servers.contains(server_id))
 8673                    })
 8674                })
 8675                .collect::<Vec<_>>()
 8676        });
 8677
 8678        let mut response_results = server_ids
 8679            .into_iter()
 8680            .map(|server_id| {
 8681                let task = self.request_lsp(
 8682                    buffer.clone(),
 8683                    LanguageServerToQuery::Other(server_id),
 8684                    request.clone(),
 8685                    cx,
 8686                );
 8687                async move { (server_id, task.await) }
 8688            })
 8689            .collect::<FuturesUnordered<_>>();
 8690
 8691        cx.background_spawn(async move {
 8692            let mut responses = Vec::with_capacity(response_results.len());
 8693            while let Some((server_id, response_result)) = response_results.next().await {
 8694                match response_result {
 8695                    Ok(response) => responses.push((server_id, response)),
 8696                    // rust-analyzer likes to error with this when its still loading up
 8697                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8698                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8699                }
 8700            }
 8701            responses
 8702        })
 8703    }
 8704
 8705    async fn handle_lsp_get_completions(
 8706        this: Entity<Self>,
 8707        envelope: TypedEnvelope<proto::GetCompletions>,
 8708        mut cx: AsyncApp,
 8709    ) -> Result<proto::GetCompletionsResponse> {
 8710        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8711
 8712        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8713        let buffer_handle = this.update(&mut cx, |this, cx| {
 8714            this.buffer_store.read(cx).get_existing(buffer_id)
 8715        })??;
 8716        let request = GetCompletions::from_proto(
 8717            envelope.payload,
 8718            this.clone(),
 8719            buffer_handle.clone(),
 8720            cx.clone(),
 8721        )
 8722        .await?;
 8723
 8724        let server_to_query = match request.server_id {
 8725            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8726            None => LanguageServerToQuery::FirstCapable,
 8727        };
 8728
 8729        let response = this
 8730            .update(&mut cx, |this, cx| {
 8731                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8732            })?
 8733            .await?;
 8734        this.update(&mut cx, |this, cx| {
 8735            Ok(GetCompletions::response_to_proto(
 8736                response,
 8737                this,
 8738                sender_id,
 8739                &buffer_handle.read(cx).version(),
 8740                cx,
 8741            ))
 8742        })?
 8743    }
 8744
 8745    async fn handle_lsp_command<T: LspCommand>(
 8746        this: Entity<Self>,
 8747        envelope: TypedEnvelope<T::ProtoRequest>,
 8748        mut cx: AsyncApp,
 8749    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8750    where
 8751        <T::LspRequest as lsp::request::Request>::Params: Send,
 8752        <T::LspRequest as lsp::request::Request>::Result: Send,
 8753    {
 8754        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8755        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8756        let buffer_handle = this.update(&mut cx, |this, cx| {
 8757            this.buffer_store.read(cx).get_existing(buffer_id)
 8758        })??;
 8759        let request = T::from_proto(
 8760            envelope.payload,
 8761            this.clone(),
 8762            buffer_handle.clone(),
 8763            cx.clone(),
 8764        )
 8765        .await?;
 8766        let response = this
 8767            .update(&mut cx, |this, cx| {
 8768                this.request_lsp(
 8769                    buffer_handle.clone(),
 8770                    LanguageServerToQuery::FirstCapable,
 8771                    request,
 8772                    cx,
 8773                )
 8774            })?
 8775            .await?;
 8776        this.update(&mut cx, |this, cx| {
 8777            Ok(T::response_to_proto(
 8778                response,
 8779                this,
 8780                sender_id,
 8781                &buffer_handle.read(cx).version(),
 8782                cx,
 8783            ))
 8784        })?
 8785    }
 8786
 8787    async fn handle_lsp_query(
 8788        lsp_store: Entity<Self>,
 8789        envelope: TypedEnvelope<proto::LspQuery>,
 8790        mut cx: AsyncApp,
 8791    ) -> Result<proto::Ack> {
 8792        use proto::lsp_query::Request;
 8793        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8794        let lsp_query = envelope.payload;
 8795        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8796        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8797        match lsp_query.request.context("invalid LSP query request")? {
 8798            Request::GetReferences(get_references) => {
 8799                let position = get_references.position.clone().and_then(deserialize_anchor);
 8800                Self::query_lsp_locally::<GetReferences>(
 8801                    lsp_store,
 8802                    server_id,
 8803                    sender_id,
 8804                    lsp_request_id,
 8805                    get_references,
 8806                    position,
 8807                    &mut cx,
 8808                )
 8809                .await?;
 8810            }
 8811            Request::GetDocumentColor(get_document_color) => {
 8812                Self::query_lsp_locally::<GetDocumentColor>(
 8813                    lsp_store,
 8814                    server_id,
 8815                    sender_id,
 8816                    lsp_request_id,
 8817                    get_document_color,
 8818                    None,
 8819                    &mut cx,
 8820                )
 8821                .await?;
 8822            }
 8823            Request::GetHover(get_hover) => {
 8824                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8825                Self::query_lsp_locally::<GetHover>(
 8826                    lsp_store,
 8827                    server_id,
 8828                    sender_id,
 8829                    lsp_request_id,
 8830                    get_hover,
 8831                    position,
 8832                    &mut cx,
 8833                )
 8834                .await?;
 8835            }
 8836            Request::GetCodeActions(get_code_actions) => {
 8837                Self::query_lsp_locally::<GetCodeActions>(
 8838                    lsp_store,
 8839                    server_id,
 8840                    sender_id,
 8841                    lsp_request_id,
 8842                    get_code_actions,
 8843                    None,
 8844                    &mut cx,
 8845                )
 8846                .await?;
 8847            }
 8848            Request::GetSignatureHelp(get_signature_help) => {
 8849                let position = get_signature_help
 8850                    .position
 8851                    .clone()
 8852                    .and_then(deserialize_anchor);
 8853                Self::query_lsp_locally::<GetSignatureHelp>(
 8854                    lsp_store,
 8855                    server_id,
 8856                    sender_id,
 8857                    lsp_request_id,
 8858                    get_signature_help,
 8859                    position,
 8860                    &mut cx,
 8861                )
 8862                .await?;
 8863            }
 8864            Request::GetCodeLens(get_code_lens) => {
 8865                Self::query_lsp_locally::<GetCodeLens>(
 8866                    lsp_store,
 8867                    server_id,
 8868                    sender_id,
 8869                    lsp_request_id,
 8870                    get_code_lens,
 8871                    None,
 8872                    &mut cx,
 8873                )
 8874                .await?;
 8875            }
 8876            Request::GetDefinition(get_definition) => {
 8877                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8878                Self::query_lsp_locally::<GetDefinitions>(
 8879                    lsp_store,
 8880                    server_id,
 8881                    sender_id,
 8882                    lsp_request_id,
 8883                    get_definition,
 8884                    position,
 8885                    &mut cx,
 8886                )
 8887                .await?;
 8888            }
 8889            Request::GetDeclaration(get_declaration) => {
 8890                let position = get_declaration
 8891                    .position
 8892                    .clone()
 8893                    .and_then(deserialize_anchor);
 8894                Self::query_lsp_locally::<GetDeclarations>(
 8895                    lsp_store,
 8896                    server_id,
 8897                    sender_id,
 8898                    lsp_request_id,
 8899                    get_declaration,
 8900                    position,
 8901                    &mut cx,
 8902                )
 8903                .await?;
 8904            }
 8905            Request::GetTypeDefinition(get_type_definition) => {
 8906                let position = get_type_definition
 8907                    .position
 8908                    .clone()
 8909                    .and_then(deserialize_anchor);
 8910                Self::query_lsp_locally::<GetTypeDefinitions>(
 8911                    lsp_store,
 8912                    server_id,
 8913                    sender_id,
 8914                    lsp_request_id,
 8915                    get_type_definition,
 8916                    position,
 8917                    &mut cx,
 8918                )
 8919                .await?;
 8920            }
 8921            Request::GetImplementation(get_implementation) => {
 8922                let position = get_implementation
 8923                    .position
 8924                    .clone()
 8925                    .and_then(deserialize_anchor);
 8926                Self::query_lsp_locally::<GetImplementations>(
 8927                    lsp_store,
 8928                    server_id,
 8929                    sender_id,
 8930                    lsp_request_id,
 8931                    get_implementation,
 8932                    position,
 8933                    &mut cx,
 8934                )
 8935                .await?;
 8936            }
 8937            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8938                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8939                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8940                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8941                    this.buffer_store.read(cx).get_existing(buffer_id)
 8942                })??;
 8943                buffer
 8944                    .update(&mut cx, |buffer, _| {
 8945                        buffer.wait_for_version(version.clone())
 8946                    })?
 8947                    .await?;
 8948                lsp_store.update(&mut cx, |lsp_store, cx| {
 8949                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8950                    let key = LspKey {
 8951                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8952                        server_queried: server_id,
 8953                    };
 8954                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8955                    ) {
 8956                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8957                            lsp_requests.clear();
 8958                        };
 8959                    }
 8960
 8961                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8962                    existing_queries.insert(
 8963                        lsp_request_id,
 8964                        cx.spawn(async move |lsp_store, cx| {
 8965                            let diagnostics_pull = lsp_store
 8966                                .update(cx, |lsp_store, cx| {
 8967                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8968                                })
 8969                                .ok();
 8970                            if let Some(diagnostics_pull) = diagnostics_pull {
 8971                                match diagnostics_pull.await {
 8972                                    Ok(()) => {}
 8973                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8974                                };
 8975                            }
 8976                        }),
 8977                    );
 8978                })?;
 8979            }
 8980            Request::InlayHints(inlay_hints) => {
 8981                let query_start = inlay_hints
 8982                    .start
 8983                    .clone()
 8984                    .and_then(deserialize_anchor)
 8985                    .context("invalid inlay hints range start")?;
 8986                let query_end = inlay_hints
 8987                    .end
 8988                    .clone()
 8989                    .and_then(deserialize_anchor)
 8990                    .context("invalid inlay hints range end")?;
 8991                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8992                    &lsp_store,
 8993                    server_id,
 8994                    lsp_request_id,
 8995                    &inlay_hints,
 8996                    query_start..query_end,
 8997                    &mut cx,
 8998                )
 8999                .await
 9000                .context("preparing inlay hints request")?;
 9001                Self::query_lsp_locally::<InlayHints>(
 9002                    lsp_store,
 9003                    server_id,
 9004                    sender_id,
 9005                    lsp_request_id,
 9006                    inlay_hints,
 9007                    None,
 9008                    &mut cx,
 9009                )
 9010                .await
 9011                .context("querying for inlay hints")?
 9012            }
 9013        }
 9014        Ok(proto::Ack {})
 9015    }
 9016
 9017    async fn handle_lsp_query_response(
 9018        lsp_store: Entity<Self>,
 9019        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9020        cx: AsyncApp,
 9021    ) -> Result<()> {
 9022        lsp_store.read_with(&cx, |lsp_store, _| {
 9023            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9024                upstream_client.handle_lsp_response(envelope.clone());
 9025            }
 9026        })?;
 9027        Ok(())
 9028    }
 9029
 9030    async fn handle_apply_code_action(
 9031        this: Entity<Self>,
 9032        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9033        mut cx: AsyncApp,
 9034    ) -> Result<proto::ApplyCodeActionResponse> {
 9035        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9036        let action =
 9037            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9038        let apply_code_action = this.update(&mut cx, |this, cx| {
 9039            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9040            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9041            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9042        })??;
 9043
 9044        let project_transaction = apply_code_action.await?;
 9045        let project_transaction = this.update(&mut cx, |this, cx| {
 9046            this.buffer_store.update(cx, |buffer_store, cx| {
 9047                buffer_store.serialize_project_transaction_for_peer(
 9048                    project_transaction,
 9049                    sender_id,
 9050                    cx,
 9051                )
 9052            })
 9053        })?;
 9054        Ok(proto::ApplyCodeActionResponse {
 9055            transaction: Some(project_transaction),
 9056        })
 9057    }
 9058
 9059    async fn handle_register_buffer_with_language_servers(
 9060        this: Entity<Self>,
 9061        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9062        mut cx: AsyncApp,
 9063    ) -> Result<proto::Ack> {
 9064        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9065        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9066        this.update(&mut cx, |this, cx| {
 9067            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9068                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9069                    project_id: upstream_project_id,
 9070                    buffer_id: buffer_id.to_proto(),
 9071                    only_servers: envelope.payload.only_servers,
 9072                });
 9073            }
 9074
 9075            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9076                anyhow::bail!("buffer is not open");
 9077            };
 9078
 9079            let handle = this.register_buffer_with_language_servers(
 9080                &buffer,
 9081                envelope
 9082                    .payload
 9083                    .only_servers
 9084                    .into_iter()
 9085                    .filter_map(|selector| {
 9086                        Some(match selector.selector? {
 9087                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9088                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9089                            }
 9090                            proto::language_server_selector::Selector::Name(name) => {
 9091                                LanguageServerSelector::Name(LanguageServerName(
 9092                                    SharedString::from(name),
 9093                                ))
 9094                            }
 9095                        })
 9096                    })
 9097                    .collect(),
 9098                false,
 9099                cx,
 9100            );
 9101            this.buffer_store().update(cx, |buffer_store, _| {
 9102                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9103            });
 9104
 9105            Ok(())
 9106        })??;
 9107        Ok(proto::Ack {})
 9108    }
 9109
 9110    async fn handle_rename_project_entry(
 9111        this: Entity<Self>,
 9112        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9113        mut cx: AsyncApp,
 9114    ) -> Result<proto::ProjectEntryResponse> {
 9115        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9116        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9117        let new_path =
 9118            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9119
 9120        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9121            .update(&mut cx, |this, cx| {
 9122                let (worktree, entry) = this
 9123                    .worktree_store
 9124                    .read(cx)
 9125                    .worktree_and_entry_for_id(entry_id, cx)?;
 9126                let new_worktree = this
 9127                    .worktree_store
 9128                    .read(cx)
 9129                    .worktree_for_id(new_worktree_id, cx)?;
 9130                Some((
 9131                    this.worktree_store.clone(),
 9132                    worktree,
 9133                    new_worktree,
 9134                    entry.clone(),
 9135                ))
 9136            })?
 9137            .context("worktree not found")?;
 9138        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9139            (worktree.absolutize(&old_entry.path), worktree.id())
 9140        })?;
 9141        let new_abs_path =
 9142            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9143
 9144        let _transaction = Self::will_rename_entry(
 9145            this.downgrade(),
 9146            old_worktree_id,
 9147            &old_abs_path,
 9148            &new_abs_path,
 9149            old_entry.is_dir(),
 9150            cx.clone(),
 9151        )
 9152        .await;
 9153        let response = WorktreeStore::handle_rename_project_entry(
 9154            worktree_store,
 9155            envelope.payload,
 9156            cx.clone(),
 9157        )
 9158        .await;
 9159        this.read_with(&cx, |this, _| {
 9160            this.did_rename_entry(
 9161                old_worktree_id,
 9162                &old_abs_path,
 9163                &new_abs_path,
 9164                old_entry.is_dir(),
 9165            );
 9166        })
 9167        .ok();
 9168        response
 9169    }
 9170
 9171    async fn handle_update_diagnostic_summary(
 9172        this: Entity<Self>,
 9173        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9174        mut cx: AsyncApp,
 9175    ) -> Result<()> {
 9176        this.update(&mut cx, |lsp_store, cx| {
 9177            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9178            let mut updated_diagnostics_paths = HashMap::default();
 9179            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9180            for message_summary in envelope
 9181                .payload
 9182                .summary
 9183                .into_iter()
 9184                .chain(envelope.payload.more_summaries)
 9185            {
 9186                let project_path = ProjectPath {
 9187                    worktree_id,
 9188                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9189                };
 9190                let path = project_path.path.clone();
 9191                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9192                let summary = DiagnosticSummary {
 9193                    error_count: message_summary.error_count as usize,
 9194                    warning_count: message_summary.warning_count as usize,
 9195                };
 9196
 9197                if summary.is_empty() {
 9198                    if let Some(worktree_summaries) =
 9199                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9200                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9201                    {
 9202                        summaries.remove(&server_id);
 9203                        if summaries.is_empty() {
 9204                            worktree_summaries.remove(&path);
 9205                        }
 9206                    }
 9207                } else {
 9208                    lsp_store
 9209                        .diagnostic_summaries
 9210                        .entry(worktree_id)
 9211                        .or_default()
 9212                        .entry(path)
 9213                        .or_default()
 9214                        .insert(server_id, summary);
 9215                }
 9216
 9217                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9218                    match &mut diagnostics_summary {
 9219                        Some(diagnostics_summary) => {
 9220                            diagnostics_summary
 9221                                .more_summaries
 9222                                .push(proto::DiagnosticSummary {
 9223                                    path: project_path.path.as_ref().to_proto(),
 9224                                    language_server_id: server_id.0 as u64,
 9225                                    error_count: summary.error_count as u32,
 9226                                    warning_count: summary.warning_count as u32,
 9227                                })
 9228                        }
 9229                        None => {
 9230                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9231                                project_id: *project_id,
 9232                                worktree_id: worktree_id.to_proto(),
 9233                                summary: Some(proto::DiagnosticSummary {
 9234                                    path: project_path.path.as_ref().to_proto(),
 9235                                    language_server_id: server_id.0 as u64,
 9236                                    error_count: summary.error_count as u32,
 9237                                    warning_count: summary.warning_count as u32,
 9238                                }),
 9239                                more_summaries: Vec::new(),
 9240                            })
 9241                        }
 9242                    }
 9243                }
 9244                updated_diagnostics_paths
 9245                    .entry(server_id)
 9246                    .or_insert_with(Vec::new)
 9247                    .push(project_path);
 9248            }
 9249
 9250            if let Some((diagnostics_summary, (downstream_client, _))) =
 9251                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9252            {
 9253                downstream_client.send(diagnostics_summary).log_err();
 9254            }
 9255            for (server_id, paths) in updated_diagnostics_paths {
 9256                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9257            }
 9258            Ok(())
 9259        })?
 9260    }
 9261
 9262    async fn handle_start_language_server(
 9263        lsp_store: Entity<Self>,
 9264        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9265        mut cx: AsyncApp,
 9266    ) -> Result<()> {
 9267        let server = envelope.payload.server.context("invalid server")?;
 9268        let server_capabilities =
 9269            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9270                .with_context(|| {
 9271                    format!(
 9272                        "incorrect server capabilities {}",
 9273                        envelope.payload.capabilities
 9274                    )
 9275                })?;
 9276        lsp_store.update(&mut cx, |lsp_store, cx| {
 9277            let server_id = LanguageServerId(server.id as usize);
 9278            let server_name = LanguageServerName::from_proto(server.name.clone());
 9279            lsp_store
 9280                .lsp_server_capabilities
 9281                .insert(server_id, server_capabilities);
 9282            lsp_store.language_server_statuses.insert(
 9283                server_id,
 9284                LanguageServerStatus {
 9285                    name: server_name.clone(),
 9286                    pending_work: Default::default(),
 9287                    has_pending_diagnostic_updates: false,
 9288                    progress_tokens: Default::default(),
 9289                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9290                    binary: None,
 9291                    configuration: None,
 9292                    workspace_folders: BTreeSet::new(),
 9293                },
 9294            );
 9295            cx.emit(LspStoreEvent::LanguageServerAdded(
 9296                server_id,
 9297                server_name,
 9298                server.worktree_id.map(WorktreeId::from_proto),
 9299            ));
 9300            cx.notify();
 9301        })?;
 9302        Ok(())
 9303    }
 9304
 9305    async fn handle_update_language_server(
 9306        lsp_store: Entity<Self>,
 9307        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9308        mut cx: AsyncApp,
 9309    ) -> Result<()> {
 9310        lsp_store.update(&mut cx, |lsp_store, cx| {
 9311            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9312
 9313            match envelope.payload.variant.context("invalid variant")? {
 9314                proto::update_language_server::Variant::WorkStart(payload) => {
 9315                    lsp_store.on_lsp_work_start(
 9316                        language_server_id,
 9317                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9318                            .context("invalid progress token value")?,
 9319                        LanguageServerProgress {
 9320                            title: payload.title,
 9321                            is_disk_based_diagnostics_progress: false,
 9322                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9323                            message: payload.message,
 9324                            percentage: payload.percentage.map(|p| p as usize),
 9325                            last_update_at: cx.background_executor().now(),
 9326                        },
 9327                        cx,
 9328                    );
 9329                }
 9330                proto::update_language_server::Variant::WorkProgress(payload) => {
 9331                    lsp_store.on_lsp_work_progress(
 9332                        language_server_id,
 9333                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9334                            .context("invalid progress token value")?,
 9335                        LanguageServerProgress {
 9336                            title: None,
 9337                            is_disk_based_diagnostics_progress: false,
 9338                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9339                            message: payload.message,
 9340                            percentage: payload.percentage.map(|p| p as usize),
 9341                            last_update_at: cx.background_executor().now(),
 9342                        },
 9343                        cx,
 9344                    );
 9345                }
 9346
 9347                proto::update_language_server::Variant::WorkEnd(payload) => {
 9348                    lsp_store.on_lsp_work_end(
 9349                        language_server_id,
 9350                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9351                            .context("invalid progress token value")?,
 9352                        cx,
 9353                    );
 9354                }
 9355
 9356                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9357                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9358                }
 9359
 9360                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9361                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9362                }
 9363
 9364                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9365                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9366                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9367                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9368                        language_server_id,
 9369                        name: envelope
 9370                            .payload
 9371                            .server_name
 9372                            .map(SharedString::new)
 9373                            .map(LanguageServerName),
 9374                        message: non_lsp,
 9375                    });
 9376                }
 9377            }
 9378
 9379            Ok(())
 9380        })?
 9381    }
 9382
 9383    async fn handle_language_server_log(
 9384        this: Entity<Self>,
 9385        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9386        mut cx: AsyncApp,
 9387    ) -> Result<()> {
 9388        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9389        let log_type = envelope
 9390            .payload
 9391            .log_type
 9392            .map(LanguageServerLogType::from_proto)
 9393            .context("invalid language server log type")?;
 9394
 9395        let message = envelope.payload.message;
 9396
 9397        this.update(&mut cx, |_, cx| {
 9398            cx.emit(LspStoreEvent::LanguageServerLog(
 9399                language_server_id,
 9400                log_type,
 9401                message,
 9402            ));
 9403        })
 9404    }
 9405
 9406    async fn handle_lsp_ext_cancel_flycheck(
 9407        lsp_store: Entity<Self>,
 9408        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9409        cx: AsyncApp,
 9410    ) -> Result<proto::Ack> {
 9411        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9412        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9413            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9414                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9415            } else {
 9416                None
 9417            }
 9418        })?;
 9419        if let Some(task) = task {
 9420            task.context("handling lsp ext cancel flycheck")?;
 9421        }
 9422
 9423        Ok(proto::Ack {})
 9424    }
 9425
 9426    async fn handle_lsp_ext_run_flycheck(
 9427        lsp_store: Entity<Self>,
 9428        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9429        mut cx: AsyncApp,
 9430    ) -> Result<proto::Ack> {
 9431        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9432        lsp_store.update(&mut cx, |lsp_store, cx| {
 9433            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9434                let text_document = if envelope.payload.current_file_only {
 9435                    let buffer_id = envelope
 9436                        .payload
 9437                        .buffer_id
 9438                        .map(|id| BufferId::new(id))
 9439                        .transpose()?;
 9440                    buffer_id
 9441                        .and_then(|buffer_id| {
 9442                            lsp_store
 9443                                .buffer_store()
 9444                                .read(cx)
 9445                                .get(buffer_id)
 9446                                .and_then(|buffer| {
 9447                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9448                                })
 9449                                .map(|path| make_text_document_identifier(&path))
 9450                        })
 9451                        .transpose()?
 9452                } else {
 9453                    None
 9454                };
 9455                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9456                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9457                )?;
 9458            }
 9459            anyhow::Ok(())
 9460        })??;
 9461
 9462        Ok(proto::Ack {})
 9463    }
 9464
 9465    async fn handle_lsp_ext_clear_flycheck(
 9466        lsp_store: Entity<Self>,
 9467        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9468        cx: AsyncApp,
 9469    ) -> Result<proto::Ack> {
 9470        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9471        lsp_store
 9472            .read_with(&cx, |lsp_store, _| {
 9473                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9474                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9475                } else {
 9476                    None
 9477                }
 9478            })
 9479            .context("handling lsp ext clear flycheck")?;
 9480
 9481        Ok(proto::Ack {})
 9482    }
 9483
 9484    pub fn disk_based_diagnostics_started(
 9485        &mut self,
 9486        language_server_id: LanguageServerId,
 9487        cx: &mut Context<Self>,
 9488    ) {
 9489        if let Some(language_server_status) =
 9490            self.language_server_statuses.get_mut(&language_server_id)
 9491        {
 9492            language_server_status.has_pending_diagnostic_updates = true;
 9493        }
 9494
 9495        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9496        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9497            language_server_id,
 9498            name: self
 9499                .language_server_adapter_for_id(language_server_id)
 9500                .map(|adapter| adapter.name()),
 9501            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9502                Default::default(),
 9503            ),
 9504        })
 9505    }
 9506
 9507    pub fn disk_based_diagnostics_finished(
 9508        &mut self,
 9509        language_server_id: LanguageServerId,
 9510        cx: &mut Context<Self>,
 9511    ) {
 9512        if let Some(language_server_status) =
 9513            self.language_server_statuses.get_mut(&language_server_id)
 9514        {
 9515            language_server_status.has_pending_diagnostic_updates = false;
 9516        }
 9517
 9518        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9519        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9520            language_server_id,
 9521            name: self
 9522                .language_server_adapter_for_id(language_server_id)
 9523                .map(|adapter| adapter.name()),
 9524            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9525                Default::default(),
 9526            ),
 9527        })
 9528    }
 9529
 9530    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9531    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9532    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9533    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9534    // the language server might take some time to publish diagnostics.
 9535    fn simulate_disk_based_diagnostics_events_if_needed(
 9536        &mut self,
 9537        language_server_id: LanguageServerId,
 9538        cx: &mut Context<Self>,
 9539    ) {
 9540        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9541
 9542        let Some(LanguageServerState::Running {
 9543            simulate_disk_based_diagnostics_completion,
 9544            adapter,
 9545            ..
 9546        }) = self
 9547            .as_local_mut()
 9548            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9549        else {
 9550            return;
 9551        };
 9552
 9553        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9554            return;
 9555        }
 9556
 9557        let prev_task =
 9558            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9559                cx.background_executor()
 9560                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9561                    .await;
 9562
 9563                this.update(cx, |this, cx| {
 9564                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9565
 9566                    if let Some(LanguageServerState::Running {
 9567                        simulate_disk_based_diagnostics_completion,
 9568                        ..
 9569                    }) = this.as_local_mut().and_then(|local_store| {
 9570                        local_store.language_servers.get_mut(&language_server_id)
 9571                    }) {
 9572                        *simulate_disk_based_diagnostics_completion = None;
 9573                    }
 9574                })
 9575                .ok();
 9576            }));
 9577
 9578        if prev_task.is_none() {
 9579            self.disk_based_diagnostics_started(language_server_id, cx);
 9580        }
 9581    }
 9582
 9583    pub fn language_server_statuses(
 9584        &self,
 9585    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9586        self.language_server_statuses
 9587            .iter()
 9588            .map(|(key, value)| (*key, value))
 9589    }
 9590
 9591    pub(super) fn did_rename_entry(
 9592        &self,
 9593        worktree_id: WorktreeId,
 9594        old_path: &Path,
 9595        new_path: &Path,
 9596        is_dir: bool,
 9597    ) {
 9598        maybe!({
 9599            let local_store = self.as_local()?;
 9600
 9601            let old_uri = lsp::Uri::from_file_path(old_path)
 9602                .ok()
 9603                .map(|uri| uri.to_string())?;
 9604            let new_uri = lsp::Uri::from_file_path(new_path)
 9605                .ok()
 9606                .map(|uri| uri.to_string())?;
 9607
 9608            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9609                let Some(filter) = local_store
 9610                    .language_server_paths_watched_for_rename
 9611                    .get(&language_server.server_id())
 9612                else {
 9613                    continue;
 9614                };
 9615
 9616                if filter.should_send_did_rename(&old_uri, is_dir) {
 9617                    language_server
 9618                        .notify::<DidRenameFiles>(RenameFilesParams {
 9619                            files: vec![FileRename {
 9620                                old_uri: old_uri.clone(),
 9621                                new_uri: new_uri.clone(),
 9622                            }],
 9623                        })
 9624                        .ok();
 9625                }
 9626            }
 9627            Some(())
 9628        });
 9629    }
 9630
 9631    pub(super) fn will_rename_entry(
 9632        this: WeakEntity<Self>,
 9633        worktree_id: WorktreeId,
 9634        old_path: &Path,
 9635        new_path: &Path,
 9636        is_dir: bool,
 9637        cx: AsyncApp,
 9638    ) -> Task<ProjectTransaction> {
 9639        let old_uri = lsp::Uri::from_file_path(old_path)
 9640            .ok()
 9641            .map(|uri| uri.to_string());
 9642        let new_uri = lsp::Uri::from_file_path(new_path)
 9643            .ok()
 9644            .map(|uri| uri.to_string());
 9645        cx.spawn(async move |cx| {
 9646            let mut tasks = vec![];
 9647            this.update(cx, |this, cx| {
 9648                let local_store = this.as_local()?;
 9649                let old_uri = old_uri?;
 9650                let new_uri = new_uri?;
 9651                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9652                    let Some(filter) = local_store
 9653                        .language_server_paths_watched_for_rename
 9654                        .get(&language_server.server_id())
 9655                    else {
 9656                        continue;
 9657                    };
 9658
 9659                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9660                        let apply_edit = cx.spawn({
 9661                            let old_uri = old_uri.clone();
 9662                            let new_uri = new_uri.clone();
 9663                            let language_server = language_server.clone();
 9664                            async move |this, cx| {
 9665                                let edit = language_server
 9666                                    .request::<WillRenameFiles>(RenameFilesParams {
 9667                                        files: vec![FileRename { old_uri, new_uri }],
 9668                                    })
 9669                                    .await
 9670                                    .into_response()
 9671                                    .context("will rename files")
 9672                                    .log_err()
 9673                                    .flatten()?;
 9674
 9675                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9676                                    this.upgrade()?,
 9677                                    edit,
 9678                                    false,
 9679                                    language_server.clone(),
 9680                                    cx,
 9681                                )
 9682                                .await
 9683                                .ok()?;
 9684                                Some(transaction)
 9685                            }
 9686                        });
 9687                        tasks.push(apply_edit);
 9688                    }
 9689                }
 9690                Some(())
 9691            })
 9692            .ok()
 9693            .flatten();
 9694            let mut merged_transaction = ProjectTransaction::default();
 9695            for task in tasks {
 9696                // Await on tasks sequentially so that the order of application of edits is deterministic
 9697                // (at least with regards to the order of registration of language servers)
 9698                if let Some(transaction) = task.await {
 9699                    for (buffer, buffer_transaction) in transaction.0 {
 9700                        merged_transaction.0.insert(buffer, buffer_transaction);
 9701                    }
 9702                }
 9703            }
 9704            merged_transaction
 9705        })
 9706    }
 9707
 9708    fn lsp_notify_abs_paths_changed(
 9709        &mut self,
 9710        server_id: LanguageServerId,
 9711        changes: Vec<PathEvent>,
 9712    ) {
 9713        maybe!({
 9714            let server = self.language_server_for_id(server_id)?;
 9715            let changes = changes
 9716                .into_iter()
 9717                .filter_map(|event| {
 9718                    let typ = match event.kind? {
 9719                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9720                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9721                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9722                    };
 9723                    Some(lsp::FileEvent {
 9724                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9725                        typ,
 9726                    })
 9727                })
 9728                .collect::<Vec<_>>();
 9729            if !changes.is_empty() {
 9730                server
 9731                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9732                        lsp::DidChangeWatchedFilesParams { changes },
 9733                    )
 9734                    .ok();
 9735            }
 9736            Some(())
 9737        });
 9738    }
 9739
 9740    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9741        self.as_local()?.language_server_for_id(id)
 9742    }
 9743
 9744    fn on_lsp_progress(
 9745        &mut self,
 9746        progress_params: lsp::ProgressParams,
 9747        language_server_id: LanguageServerId,
 9748        disk_based_diagnostics_progress_token: Option<String>,
 9749        cx: &mut Context<Self>,
 9750    ) {
 9751        match progress_params.value {
 9752            lsp::ProgressParamsValue::WorkDone(progress) => {
 9753                self.handle_work_done_progress(
 9754                    progress,
 9755                    language_server_id,
 9756                    disk_based_diagnostics_progress_token,
 9757                    ProgressToken::from_lsp(progress_params.token),
 9758                    cx,
 9759                );
 9760            }
 9761            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9762                let registration_id = match progress_params.token {
 9763                    lsp::NumberOrString::Number(_) => None,
 9764                    lsp::NumberOrString::String(token) => token
 9765                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9766                        .map(|(_, id)| id.to_owned()),
 9767                };
 9768                if let Some(LanguageServerState::Running {
 9769                    workspace_diagnostics_refresh_tasks,
 9770                    ..
 9771                }) = self
 9772                    .as_local_mut()
 9773                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9774                    && let Some(workspace_diagnostics) =
 9775                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9776                {
 9777                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9778                    self.apply_workspace_diagnostic_report(
 9779                        language_server_id,
 9780                        report,
 9781                        registration_id.map(SharedString::from),
 9782                        cx,
 9783                    )
 9784                }
 9785            }
 9786        }
 9787    }
 9788
 9789    fn handle_work_done_progress(
 9790        &mut self,
 9791        progress: lsp::WorkDoneProgress,
 9792        language_server_id: LanguageServerId,
 9793        disk_based_diagnostics_progress_token: Option<String>,
 9794        token: ProgressToken,
 9795        cx: &mut Context<Self>,
 9796    ) {
 9797        let language_server_status =
 9798            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9799                status
 9800            } else {
 9801                return;
 9802            };
 9803
 9804        if !language_server_status.progress_tokens.contains(&token) {
 9805            return;
 9806        }
 9807
 9808        let is_disk_based_diagnostics_progress =
 9809            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9810                (&disk_based_diagnostics_progress_token, &token)
 9811            {
 9812                token.starts_with(disk_based_token)
 9813            } else {
 9814                false
 9815            };
 9816
 9817        match progress {
 9818            lsp::WorkDoneProgress::Begin(report) => {
 9819                if is_disk_based_diagnostics_progress {
 9820                    self.disk_based_diagnostics_started(language_server_id, cx);
 9821                }
 9822                self.on_lsp_work_start(
 9823                    language_server_id,
 9824                    token.clone(),
 9825                    LanguageServerProgress {
 9826                        title: Some(report.title),
 9827                        is_disk_based_diagnostics_progress,
 9828                        is_cancellable: report.cancellable.unwrap_or(false),
 9829                        message: report.message.clone(),
 9830                        percentage: report.percentage.map(|p| p as usize),
 9831                        last_update_at: cx.background_executor().now(),
 9832                    },
 9833                    cx,
 9834                );
 9835            }
 9836            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9837                language_server_id,
 9838                token,
 9839                LanguageServerProgress {
 9840                    title: None,
 9841                    is_disk_based_diagnostics_progress,
 9842                    is_cancellable: report.cancellable.unwrap_or(false),
 9843                    message: report.message,
 9844                    percentage: report.percentage.map(|p| p as usize),
 9845                    last_update_at: cx.background_executor().now(),
 9846                },
 9847                cx,
 9848            ),
 9849            lsp::WorkDoneProgress::End(_) => {
 9850                language_server_status.progress_tokens.remove(&token);
 9851                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9852                if is_disk_based_diagnostics_progress {
 9853                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9854                }
 9855            }
 9856        }
 9857    }
 9858
 9859    fn on_lsp_work_start(
 9860        &mut self,
 9861        language_server_id: LanguageServerId,
 9862        token: ProgressToken,
 9863        progress: LanguageServerProgress,
 9864        cx: &mut Context<Self>,
 9865    ) {
 9866        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9867            status.pending_work.insert(token.clone(), progress.clone());
 9868            cx.notify();
 9869        }
 9870        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9871            language_server_id,
 9872            name: self
 9873                .language_server_adapter_for_id(language_server_id)
 9874                .map(|adapter| adapter.name()),
 9875            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9876                token: Some(token.to_proto()),
 9877                title: progress.title,
 9878                message: progress.message,
 9879                percentage: progress.percentage.map(|p| p as u32),
 9880                is_cancellable: Some(progress.is_cancellable),
 9881            }),
 9882        })
 9883    }
 9884
 9885    fn on_lsp_work_progress(
 9886        &mut self,
 9887        language_server_id: LanguageServerId,
 9888        token: ProgressToken,
 9889        progress: LanguageServerProgress,
 9890        cx: &mut Context<Self>,
 9891    ) {
 9892        let mut did_update = false;
 9893        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9894            match status.pending_work.entry(token.clone()) {
 9895                btree_map::Entry::Vacant(entry) => {
 9896                    entry.insert(progress.clone());
 9897                    did_update = true;
 9898                }
 9899                btree_map::Entry::Occupied(mut entry) => {
 9900                    let entry = entry.get_mut();
 9901                    if (progress.last_update_at - entry.last_update_at)
 9902                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9903                    {
 9904                        entry.last_update_at = progress.last_update_at;
 9905                        if progress.message.is_some() {
 9906                            entry.message = progress.message.clone();
 9907                        }
 9908                        if progress.percentage.is_some() {
 9909                            entry.percentage = progress.percentage;
 9910                        }
 9911                        if progress.is_cancellable != entry.is_cancellable {
 9912                            entry.is_cancellable = progress.is_cancellable;
 9913                        }
 9914                        did_update = true;
 9915                    }
 9916                }
 9917            }
 9918        }
 9919
 9920        if did_update {
 9921            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9922                language_server_id,
 9923                name: self
 9924                    .language_server_adapter_for_id(language_server_id)
 9925                    .map(|adapter| adapter.name()),
 9926                message: proto::update_language_server::Variant::WorkProgress(
 9927                    proto::LspWorkProgress {
 9928                        token: Some(token.to_proto()),
 9929                        message: progress.message,
 9930                        percentage: progress.percentage.map(|p| p as u32),
 9931                        is_cancellable: Some(progress.is_cancellable),
 9932                    },
 9933                ),
 9934            })
 9935        }
 9936    }
 9937
 9938    fn on_lsp_work_end(
 9939        &mut self,
 9940        language_server_id: LanguageServerId,
 9941        token: ProgressToken,
 9942        cx: &mut Context<Self>,
 9943    ) {
 9944        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9945            if let Some(work) = status.pending_work.remove(&token)
 9946                && !work.is_disk_based_diagnostics_progress
 9947            {
 9948                cx.emit(LspStoreEvent::RefreshInlayHints {
 9949                    server_id: language_server_id,
 9950                    request_id: None,
 9951                });
 9952            }
 9953            cx.notify();
 9954        }
 9955
 9956        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9957            language_server_id,
 9958            name: self
 9959                .language_server_adapter_for_id(language_server_id)
 9960                .map(|adapter| adapter.name()),
 9961            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9962                token: Some(token.to_proto()),
 9963            }),
 9964        })
 9965    }
 9966
 9967    pub async fn handle_resolve_completion_documentation(
 9968        this: Entity<Self>,
 9969        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9970        mut cx: AsyncApp,
 9971    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9972        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9973
 9974        let completion = this
 9975            .read_with(&cx, |this, cx| {
 9976                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9977                let server = this
 9978                    .language_server_for_id(id)
 9979                    .with_context(|| format!("No language server {id}"))?;
 9980
 9981                anyhow::Ok(cx.background_spawn(async move {
 9982                    let can_resolve = server
 9983                        .capabilities()
 9984                        .completion_provider
 9985                        .as_ref()
 9986                        .and_then(|options| options.resolve_provider)
 9987                        .unwrap_or(false);
 9988                    if can_resolve {
 9989                        server
 9990                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9991                            .await
 9992                            .into_response()
 9993                            .context("resolve completion item")
 9994                    } else {
 9995                        anyhow::Ok(lsp_completion)
 9996                    }
 9997                }))
 9998            })??
 9999            .await?;
10000
10001        let mut documentation_is_markdown = false;
10002        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10003        let documentation = match completion.documentation {
10004            Some(lsp::Documentation::String(text)) => text,
10005
10006            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10007                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10008                value
10009            }
10010
10011            _ => String::new(),
10012        };
10013
10014        // If we have a new buffer_id, that means we're talking to a new client
10015        // and want to check for new text_edits in the completion too.
10016        let mut old_replace_start = None;
10017        let mut old_replace_end = None;
10018        let mut old_insert_start = None;
10019        let mut old_insert_end = None;
10020        let mut new_text = String::default();
10021        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10022            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10023                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10024                anyhow::Ok(buffer.read(cx).snapshot())
10025            })??;
10026
10027            if let Some(text_edit) = completion.text_edit.as_ref() {
10028                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10029
10030                if let Some(mut edit) = edit {
10031                    LineEnding::normalize(&mut edit.new_text);
10032
10033                    new_text = edit.new_text;
10034                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10035                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10036                    if let Some(insert_range) = edit.insert_range {
10037                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10038                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10039                    }
10040                }
10041            }
10042        }
10043
10044        Ok(proto::ResolveCompletionDocumentationResponse {
10045            documentation,
10046            documentation_is_markdown,
10047            old_replace_start,
10048            old_replace_end,
10049            new_text,
10050            lsp_completion,
10051            old_insert_start,
10052            old_insert_end,
10053        })
10054    }
10055
10056    async fn handle_on_type_formatting(
10057        this: Entity<Self>,
10058        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10059        mut cx: AsyncApp,
10060    ) -> Result<proto::OnTypeFormattingResponse> {
10061        let on_type_formatting = this.update(&mut cx, |this, cx| {
10062            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10063            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10064            let position = envelope
10065                .payload
10066                .position
10067                .and_then(deserialize_anchor)
10068                .context("invalid position")?;
10069            anyhow::Ok(this.apply_on_type_formatting(
10070                buffer,
10071                position,
10072                envelope.payload.trigger.clone(),
10073                cx,
10074            ))
10075        })??;
10076
10077        let transaction = on_type_formatting
10078            .await?
10079            .as_ref()
10080            .map(language::proto::serialize_transaction);
10081        Ok(proto::OnTypeFormattingResponse { transaction })
10082    }
10083
10084    async fn handle_refresh_inlay_hints(
10085        lsp_store: Entity<Self>,
10086        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10087        mut cx: AsyncApp,
10088    ) -> Result<proto::Ack> {
10089        lsp_store.update(&mut cx, |_, cx| {
10090            cx.emit(LspStoreEvent::RefreshInlayHints {
10091                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10092                request_id: envelope.payload.request_id.map(|id| id as usize),
10093            });
10094        })?;
10095        Ok(proto::Ack {})
10096    }
10097
10098    async fn handle_pull_workspace_diagnostics(
10099        lsp_store: Entity<Self>,
10100        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10101        mut cx: AsyncApp,
10102    ) -> Result<proto::Ack> {
10103        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10104        lsp_store.update(&mut cx, |lsp_store, _| {
10105            lsp_store.pull_workspace_diagnostics(server_id);
10106        })?;
10107        Ok(proto::Ack {})
10108    }
10109
10110    async fn handle_get_color_presentation(
10111        lsp_store: Entity<Self>,
10112        envelope: TypedEnvelope<proto::GetColorPresentation>,
10113        mut cx: AsyncApp,
10114    ) -> Result<proto::GetColorPresentationResponse> {
10115        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10116        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10117            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10118        })??;
10119
10120        let color = envelope
10121            .payload
10122            .color
10123            .context("invalid color resolve request")?;
10124        let start = color
10125            .lsp_range_start
10126            .context("invalid color resolve request")?;
10127        let end = color
10128            .lsp_range_end
10129            .context("invalid color resolve request")?;
10130
10131        let color = DocumentColor {
10132            lsp_range: lsp::Range {
10133                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10134                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10135            },
10136            color: lsp::Color {
10137                red: color.red,
10138                green: color.green,
10139                blue: color.blue,
10140                alpha: color.alpha,
10141            },
10142            resolved: false,
10143            color_presentations: Vec::new(),
10144        };
10145        let resolved_color = lsp_store
10146            .update(&mut cx, |lsp_store, cx| {
10147                lsp_store.resolve_color_presentation(
10148                    color,
10149                    buffer.clone(),
10150                    LanguageServerId(envelope.payload.server_id as usize),
10151                    cx,
10152                )
10153            })?
10154            .await
10155            .context("resolving color presentation")?;
10156
10157        Ok(proto::GetColorPresentationResponse {
10158            presentations: resolved_color
10159                .color_presentations
10160                .into_iter()
10161                .map(|presentation| proto::ColorPresentation {
10162                    label: presentation.label.to_string(),
10163                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10164                    additional_text_edits: presentation
10165                        .additional_text_edits
10166                        .into_iter()
10167                        .map(serialize_lsp_edit)
10168                        .collect(),
10169                })
10170                .collect(),
10171        })
10172    }
10173
10174    async fn handle_resolve_inlay_hint(
10175        lsp_store: Entity<Self>,
10176        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10177        mut cx: AsyncApp,
10178    ) -> Result<proto::ResolveInlayHintResponse> {
10179        let proto_hint = envelope
10180            .payload
10181            .hint
10182            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10183        let hint = InlayHints::proto_to_project_hint(proto_hint)
10184            .context("resolved proto inlay hint conversion")?;
10185        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10186            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10187            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10188        })??;
10189        let response_hint = lsp_store
10190            .update(&mut cx, |lsp_store, cx| {
10191                lsp_store.resolve_inlay_hint(
10192                    hint,
10193                    buffer,
10194                    LanguageServerId(envelope.payload.language_server_id as usize),
10195                    cx,
10196                )
10197            })?
10198            .await
10199            .context("inlay hints fetch")?;
10200        Ok(proto::ResolveInlayHintResponse {
10201            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10202        })
10203    }
10204
10205    async fn handle_refresh_code_lens(
10206        this: Entity<Self>,
10207        _: TypedEnvelope<proto::RefreshCodeLens>,
10208        mut cx: AsyncApp,
10209    ) -> Result<proto::Ack> {
10210        this.update(&mut cx, |_, cx| {
10211            cx.emit(LspStoreEvent::RefreshCodeLens);
10212        })?;
10213        Ok(proto::Ack {})
10214    }
10215
10216    async fn handle_open_buffer_for_symbol(
10217        this: Entity<Self>,
10218        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10219        mut cx: AsyncApp,
10220    ) -> Result<proto::OpenBufferForSymbolResponse> {
10221        let peer_id = envelope.original_sender_id().unwrap_or_default();
10222        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10223        let symbol = Self::deserialize_symbol(symbol)?;
10224        this.read_with(&cx, |this, _| {
10225            if let SymbolLocation::OutsideProject {
10226                abs_path,
10227                signature,
10228            } = &symbol.path
10229            {
10230                let new_signature = this.symbol_signature(&abs_path);
10231                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10232            }
10233            Ok(())
10234        })??;
10235        let buffer = this
10236            .update(&mut cx, |this, cx| {
10237                this.open_buffer_for_symbol(
10238                    &Symbol {
10239                        language_server_name: symbol.language_server_name,
10240                        source_worktree_id: symbol.source_worktree_id,
10241                        source_language_server_id: symbol.source_language_server_id,
10242                        path: symbol.path,
10243                        name: symbol.name,
10244                        kind: symbol.kind,
10245                        range: symbol.range,
10246                        label: CodeLabel::default(),
10247                    },
10248                    cx,
10249                )
10250            })?
10251            .await?;
10252
10253        this.update(&mut cx, |this, cx| {
10254            let is_private = buffer
10255                .read(cx)
10256                .file()
10257                .map(|f| f.is_private())
10258                .unwrap_or_default();
10259            if is_private {
10260                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10261            } else {
10262                this.buffer_store
10263                    .update(cx, |buffer_store, cx| {
10264                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10265                    })
10266                    .detach_and_log_err(cx);
10267                let buffer_id = buffer.read(cx).remote_id().to_proto();
10268                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10269            }
10270        })?
10271    }
10272
10273    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10274        let mut hasher = Sha256::new();
10275        hasher.update(abs_path.to_string_lossy().as_bytes());
10276        hasher.update(self.nonce.to_be_bytes());
10277        hasher.finalize().as_slice().try_into().unwrap()
10278    }
10279
10280    pub async fn handle_get_project_symbols(
10281        this: Entity<Self>,
10282        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10283        mut cx: AsyncApp,
10284    ) -> Result<proto::GetProjectSymbolsResponse> {
10285        let symbols = this
10286            .update(&mut cx, |this, cx| {
10287                this.symbols(&envelope.payload.query, cx)
10288            })?
10289            .await?;
10290
10291        Ok(proto::GetProjectSymbolsResponse {
10292            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10293        })
10294    }
10295
10296    pub async fn handle_restart_language_servers(
10297        this: Entity<Self>,
10298        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10299        mut cx: AsyncApp,
10300    ) -> Result<proto::Ack> {
10301        this.update(&mut cx, |lsp_store, cx| {
10302            let buffers =
10303                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10304            lsp_store.restart_language_servers_for_buffers(
10305                buffers,
10306                envelope
10307                    .payload
10308                    .only_servers
10309                    .into_iter()
10310                    .filter_map(|selector| {
10311                        Some(match selector.selector? {
10312                            proto::language_server_selector::Selector::ServerId(server_id) => {
10313                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10314                            }
10315                            proto::language_server_selector::Selector::Name(name) => {
10316                                LanguageServerSelector::Name(LanguageServerName(
10317                                    SharedString::from(name),
10318                                ))
10319                            }
10320                        })
10321                    })
10322                    .collect(),
10323                cx,
10324            );
10325        })?;
10326
10327        Ok(proto::Ack {})
10328    }
10329
10330    pub async fn handle_stop_language_servers(
10331        lsp_store: Entity<Self>,
10332        envelope: TypedEnvelope<proto::StopLanguageServers>,
10333        mut cx: AsyncApp,
10334    ) -> Result<proto::Ack> {
10335        lsp_store.update(&mut cx, |lsp_store, cx| {
10336            if envelope.payload.all
10337                && envelope.payload.also_servers.is_empty()
10338                && envelope.payload.buffer_ids.is_empty()
10339            {
10340                lsp_store.stop_all_language_servers(cx);
10341            } else {
10342                let buffers =
10343                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10344                lsp_store
10345                    .stop_language_servers_for_buffers(
10346                        buffers,
10347                        envelope
10348                            .payload
10349                            .also_servers
10350                            .into_iter()
10351                            .filter_map(|selector| {
10352                                Some(match selector.selector? {
10353                                    proto::language_server_selector::Selector::ServerId(
10354                                        server_id,
10355                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10356                                        server_id,
10357                                    )),
10358                                    proto::language_server_selector::Selector::Name(name) => {
10359                                        LanguageServerSelector::Name(LanguageServerName(
10360                                            SharedString::from(name),
10361                                        ))
10362                                    }
10363                                })
10364                            })
10365                            .collect(),
10366                        cx,
10367                    )
10368                    .detach_and_log_err(cx);
10369            }
10370        })?;
10371
10372        Ok(proto::Ack {})
10373    }
10374
10375    pub async fn handle_cancel_language_server_work(
10376        lsp_store: Entity<Self>,
10377        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10378        mut cx: AsyncApp,
10379    ) -> Result<proto::Ack> {
10380        lsp_store.update(&mut cx, |lsp_store, cx| {
10381            if let Some(work) = envelope.payload.work {
10382                match work {
10383                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10384                        let buffers =
10385                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10386                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10387                    }
10388                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10389                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10390                        let token = work
10391                            .token
10392                            .map(|token| {
10393                                ProgressToken::from_proto(token)
10394                                    .context("invalid work progress token")
10395                            })
10396                            .transpose()?;
10397                        lsp_store.cancel_language_server_work(server_id, token, cx);
10398                    }
10399                }
10400            }
10401            anyhow::Ok(())
10402        })??;
10403
10404        Ok(proto::Ack {})
10405    }
10406
10407    fn buffer_ids_to_buffers(
10408        &mut self,
10409        buffer_ids: impl Iterator<Item = u64>,
10410        cx: &mut Context<Self>,
10411    ) -> Vec<Entity<Buffer>> {
10412        buffer_ids
10413            .into_iter()
10414            .flat_map(|buffer_id| {
10415                self.buffer_store
10416                    .read(cx)
10417                    .get(BufferId::new(buffer_id).log_err()?)
10418            })
10419            .collect::<Vec<_>>()
10420    }
10421
10422    async fn handle_apply_additional_edits_for_completion(
10423        this: Entity<Self>,
10424        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10425        mut cx: AsyncApp,
10426    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10427        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10428            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10429            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10430            let completion = Self::deserialize_completion(
10431                envelope.payload.completion.context("invalid completion")?,
10432            )?;
10433            anyhow::Ok((buffer, completion))
10434        })??;
10435
10436        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10437            this.apply_additional_edits_for_completion(
10438                buffer,
10439                Rc::new(RefCell::new(Box::new([Completion {
10440                    replace_range: completion.replace_range,
10441                    new_text: completion.new_text,
10442                    source: completion.source,
10443                    documentation: None,
10444                    label: CodeLabel::default(),
10445                    match_start: None,
10446                    snippet_deduplication_key: None,
10447                    insert_text_mode: None,
10448                    icon_path: None,
10449                    confirm: None,
10450                }]))),
10451                0,
10452                false,
10453                cx,
10454            )
10455        })?;
10456
10457        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10458            transaction: apply_additional_edits
10459                .await?
10460                .as_ref()
10461                .map(language::proto::serialize_transaction),
10462        })
10463    }
10464
10465    pub fn last_formatting_failure(&self) -> Option<&str> {
10466        self.last_formatting_failure.as_deref()
10467    }
10468
10469    pub fn reset_last_formatting_failure(&mut self) {
10470        self.last_formatting_failure = None;
10471    }
10472
10473    pub fn environment_for_buffer(
10474        &self,
10475        buffer: &Entity<Buffer>,
10476        cx: &mut Context<Self>,
10477    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10478        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10479            environment.update(cx, |env, cx| {
10480                env.buffer_environment(buffer, &self.worktree_store, cx)
10481            })
10482        } else {
10483            Task::ready(None).shared()
10484        }
10485    }
10486
10487    pub fn format(
10488        &mut self,
10489        buffers: HashSet<Entity<Buffer>>,
10490        target: LspFormatTarget,
10491        push_to_history: bool,
10492        trigger: FormatTrigger,
10493        cx: &mut Context<Self>,
10494    ) -> Task<anyhow::Result<ProjectTransaction>> {
10495        let logger = zlog::scoped!("format");
10496        if self.as_local().is_some() {
10497            zlog::trace!(logger => "Formatting locally");
10498            let logger = zlog::scoped!(logger => "local");
10499            let buffers = buffers
10500                .into_iter()
10501                .map(|buffer_handle| {
10502                    let buffer = buffer_handle.read(cx);
10503                    let buffer_abs_path = File::from_dyn(buffer.file())
10504                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10505
10506                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10507                })
10508                .collect::<Vec<_>>();
10509
10510            cx.spawn(async move |lsp_store, cx| {
10511                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10512
10513                for (handle, abs_path, id) in buffers {
10514                    let env = lsp_store
10515                        .update(cx, |lsp_store, cx| {
10516                            lsp_store.environment_for_buffer(&handle, cx)
10517                        })?
10518                        .await;
10519
10520                    let ranges = match &target {
10521                        LspFormatTarget::Buffers => None,
10522                        LspFormatTarget::Ranges(ranges) => {
10523                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10524                        }
10525                    };
10526
10527                    formattable_buffers.push(FormattableBuffer {
10528                        handle,
10529                        abs_path,
10530                        env,
10531                        ranges,
10532                    });
10533                }
10534                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10535
10536                let format_timer = zlog::time!(logger => "Formatting buffers");
10537                let result = LocalLspStore::format_locally(
10538                    lsp_store.clone(),
10539                    formattable_buffers,
10540                    push_to_history,
10541                    trigger,
10542                    logger,
10543                    cx,
10544                )
10545                .await;
10546                format_timer.end();
10547
10548                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10549
10550                lsp_store.update(cx, |lsp_store, _| {
10551                    lsp_store.update_last_formatting_failure(&result);
10552                })?;
10553
10554                result
10555            })
10556        } else if let Some((client, project_id)) = self.upstream_client() {
10557            zlog::trace!(logger => "Formatting remotely");
10558            let logger = zlog::scoped!(logger => "remote");
10559            // Don't support formatting ranges via remote
10560            match target {
10561                LspFormatTarget::Buffers => {}
10562                LspFormatTarget::Ranges(_) => {
10563                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10564                    return Task::ready(Ok(ProjectTransaction::default()));
10565                }
10566            }
10567
10568            let buffer_store = self.buffer_store();
10569            cx.spawn(async move |lsp_store, cx| {
10570                zlog::trace!(logger => "Sending remote format request");
10571                let request_timer = zlog::time!(logger => "remote format request");
10572                let result = client
10573                    .request(proto::FormatBuffers {
10574                        project_id,
10575                        trigger: trigger as i32,
10576                        buffer_ids: buffers
10577                            .iter()
10578                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10579                            .collect::<Result<_>>()?,
10580                    })
10581                    .await
10582                    .and_then(|result| result.transaction.context("missing transaction"));
10583                request_timer.end();
10584
10585                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10586
10587                lsp_store.update(cx, |lsp_store, _| {
10588                    lsp_store.update_last_formatting_failure(&result);
10589                })?;
10590
10591                let transaction_response = result?;
10592                let _timer = zlog::time!(logger => "deserializing project transaction");
10593                buffer_store
10594                    .update(cx, |buffer_store, cx| {
10595                        buffer_store.deserialize_project_transaction(
10596                            transaction_response,
10597                            push_to_history,
10598                            cx,
10599                        )
10600                    })?
10601                    .await
10602            })
10603        } else {
10604            zlog::trace!(logger => "Not formatting");
10605            Task::ready(Ok(ProjectTransaction::default()))
10606        }
10607    }
10608
10609    async fn handle_format_buffers(
10610        this: Entity<Self>,
10611        envelope: TypedEnvelope<proto::FormatBuffers>,
10612        mut cx: AsyncApp,
10613    ) -> Result<proto::FormatBuffersResponse> {
10614        let sender_id = envelope.original_sender_id().unwrap_or_default();
10615        let format = this.update(&mut cx, |this, cx| {
10616            let mut buffers = HashSet::default();
10617            for buffer_id in &envelope.payload.buffer_ids {
10618                let buffer_id = BufferId::new(*buffer_id)?;
10619                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10620            }
10621            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10622            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10623        })??;
10624
10625        let project_transaction = format.await?;
10626        let project_transaction = this.update(&mut cx, |this, cx| {
10627            this.buffer_store.update(cx, |buffer_store, cx| {
10628                buffer_store.serialize_project_transaction_for_peer(
10629                    project_transaction,
10630                    sender_id,
10631                    cx,
10632                )
10633            })
10634        })?;
10635        Ok(proto::FormatBuffersResponse {
10636            transaction: Some(project_transaction),
10637        })
10638    }
10639
10640    async fn handle_apply_code_action_kind(
10641        this: Entity<Self>,
10642        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10643        mut cx: AsyncApp,
10644    ) -> Result<proto::ApplyCodeActionKindResponse> {
10645        let sender_id = envelope.original_sender_id().unwrap_or_default();
10646        let format = this.update(&mut cx, |this, cx| {
10647            let mut buffers = HashSet::default();
10648            for buffer_id in &envelope.payload.buffer_ids {
10649                let buffer_id = BufferId::new(*buffer_id)?;
10650                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10651            }
10652            let kind = match envelope.payload.kind.as_str() {
10653                "" => CodeActionKind::EMPTY,
10654                "quickfix" => CodeActionKind::QUICKFIX,
10655                "refactor" => CodeActionKind::REFACTOR,
10656                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10657                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10658                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10659                "source" => CodeActionKind::SOURCE,
10660                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10661                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10662                _ => anyhow::bail!(
10663                    "Invalid code action kind {}",
10664                    envelope.payload.kind.as_str()
10665                ),
10666            };
10667            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10668        })??;
10669
10670        let project_transaction = format.await?;
10671        let project_transaction = this.update(&mut cx, |this, cx| {
10672            this.buffer_store.update(cx, |buffer_store, cx| {
10673                buffer_store.serialize_project_transaction_for_peer(
10674                    project_transaction,
10675                    sender_id,
10676                    cx,
10677                )
10678            })
10679        })?;
10680        Ok(proto::ApplyCodeActionKindResponse {
10681            transaction: Some(project_transaction),
10682        })
10683    }
10684
10685    async fn shutdown_language_server(
10686        server_state: Option<LanguageServerState>,
10687        name: LanguageServerName,
10688        cx: &mut AsyncApp,
10689    ) {
10690        let server = match server_state {
10691            Some(LanguageServerState::Starting { startup, .. }) => {
10692                let mut timer = cx
10693                    .background_executor()
10694                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10695                    .fuse();
10696
10697                select! {
10698                    server = startup.fuse() => server,
10699                    () = timer => {
10700                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10701                        None
10702                    },
10703                }
10704            }
10705
10706            Some(LanguageServerState::Running { server, .. }) => Some(server),
10707
10708            None => None,
10709        };
10710
10711        if let Some(server) = server
10712            && let Some(shutdown) = server.shutdown()
10713        {
10714            shutdown.await;
10715        }
10716    }
10717
10718    // Returns a list of all of the worktrees which no longer have a language server and the root path
10719    // for the stopped server
10720    fn stop_local_language_server(
10721        &mut self,
10722        server_id: LanguageServerId,
10723        cx: &mut Context<Self>,
10724    ) -> Task<()> {
10725        let local = match &mut self.mode {
10726            LspStoreMode::Local(local) => local,
10727            _ => {
10728                return Task::ready(());
10729            }
10730        };
10731
10732        // Remove this server ID from all entries in the given worktree.
10733        local
10734            .language_server_ids
10735            .retain(|_, state| state.id != server_id);
10736        self.buffer_store.update(cx, |buffer_store, cx| {
10737            for buffer in buffer_store.buffers() {
10738                buffer.update(cx, |buffer, cx| {
10739                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10740                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10741                });
10742            }
10743        });
10744
10745        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10746            summaries.retain(|path, summaries_by_server_id| {
10747                if summaries_by_server_id.remove(&server_id).is_some() {
10748                    if let Some((client, project_id)) = self.downstream_client.clone() {
10749                        client
10750                            .send(proto::UpdateDiagnosticSummary {
10751                                project_id,
10752                                worktree_id: worktree_id.to_proto(),
10753                                summary: Some(proto::DiagnosticSummary {
10754                                    path: path.as_ref().to_proto(),
10755                                    language_server_id: server_id.0 as u64,
10756                                    error_count: 0,
10757                                    warning_count: 0,
10758                                }),
10759                                more_summaries: Vec::new(),
10760                            })
10761                            .log_err();
10762                    }
10763                    !summaries_by_server_id.is_empty()
10764                } else {
10765                    true
10766                }
10767            });
10768        }
10769
10770        let local = self.as_local_mut().unwrap();
10771        for diagnostics in local.diagnostics.values_mut() {
10772            diagnostics.retain(|_, diagnostics_by_server_id| {
10773                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10774                    diagnostics_by_server_id.remove(ix);
10775                    !diagnostics_by_server_id.is_empty()
10776                } else {
10777                    true
10778                }
10779            });
10780        }
10781        local.language_server_watched_paths.remove(&server_id);
10782
10783        let server_state = local.language_servers.remove(&server_id);
10784        self.cleanup_lsp_data(server_id);
10785        let name = self
10786            .language_server_statuses
10787            .remove(&server_id)
10788            .map(|status| status.name)
10789            .or_else(|| {
10790                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10791                    Some(adapter.name())
10792                } else {
10793                    None
10794                }
10795            });
10796
10797        if let Some(name) = name {
10798            log::info!("stopping language server {name}");
10799            self.languages
10800                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10801            cx.notify();
10802
10803            return cx.spawn(async move |lsp_store, cx| {
10804                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10805                lsp_store
10806                    .update(cx, |lsp_store, cx| {
10807                        lsp_store
10808                            .languages
10809                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10810                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10811                        cx.notify();
10812                    })
10813                    .ok();
10814            });
10815        }
10816
10817        if server_state.is_some() {
10818            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10819        }
10820        Task::ready(())
10821    }
10822
10823    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10824        if let Some((client, project_id)) = self.upstream_client() {
10825            let request = client.request(proto::StopLanguageServers {
10826                project_id,
10827                buffer_ids: Vec::new(),
10828                also_servers: Vec::new(),
10829                all: true,
10830            });
10831            cx.background_spawn(request).detach_and_log_err(cx);
10832        } else {
10833            let Some(local) = self.as_local_mut() else {
10834                return;
10835            };
10836            let language_servers_to_stop = local
10837                .language_server_ids
10838                .values()
10839                .map(|state| state.id)
10840                .collect();
10841            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10842            let tasks = language_servers_to_stop
10843                .into_iter()
10844                .map(|server| self.stop_local_language_server(server, cx))
10845                .collect::<Vec<_>>();
10846            cx.background_spawn(async move {
10847                futures::future::join_all(tasks).await;
10848            })
10849            .detach();
10850        }
10851    }
10852
10853    pub fn restart_language_servers_for_buffers(
10854        &mut self,
10855        buffers: Vec<Entity<Buffer>>,
10856        only_restart_servers: HashSet<LanguageServerSelector>,
10857        cx: &mut Context<Self>,
10858    ) {
10859        if let Some((client, project_id)) = self.upstream_client() {
10860            let request = client.request(proto::RestartLanguageServers {
10861                project_id,
10862                buffer_ids: buffers
10863                    .into_iter()
10864                    .map(|b| b.read(cx).remote_id().to_proto())
10865                    .collect(),
10866                only_servers: only_restart_servers
10867                    .into_iter()
10868                    .map(|selector| {
10869                        let selector = match selector {
10870                            LanguageServerSelector::Id(language_server_id) => {
10871                                proto::language_server_selector::Selector::ServerId(
10872                                    language_server_id.to_proto(),
10873                                )
10874                            }
10875                            LanguageServerSelector::Name(language_server_name) => {
10876                                proto::language_server_selector::Selector::Name(
10877                                    language_server_name.to_string(),
10878                                )
10879                            }
10880                        };
10881                        proto::LanguageServerSelector {
10882                            selector: Some(selector),
10883                        }
10884                    })
10885                    .collect(),
10886                all: false,
10887            });
10888            cx.background_spawn(request).detach_and_log_err(cx);
10889        } else {
10890            let stop_task = if only_restart_servers.is_empty() {
10891                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10892            } else {
10893                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10894            };
10895            cx.spawn(async move |lsp_store, cx| {
10896                stop_task.await;
10897                lsp_store
10898                    .update(cx, |lsp_store, cx| {
10899                        for buffer in buffers {
10900                            lsp_store.register_buffer_with_language_servers(
10901                                &buffer,
10902                                only_restart_servers.clone(),
10903                                true,
10904                                cx,
10905                            );
10906                        }
10907                    })
10908                    .ok()
10909            })
10910            .detach();
10911        }
10912    }
10913
10914    pub fn stop_language_servers_for_buffers(
10915        &mut self,
10916        buffers: Vec<Entity<Buffer>>,
10917        also_stop_servers: HashSet<LanguageServerSelector>,
10918        cx: &mut Context<Self>,
10919    ) -> Task<Result<()>> {
10920        if let Some((client, project_id)) = self.upstream_client() {
10921            let request = client.request(proto::StopLanguageServers {
10922                project_id,
10923                buffer_ids: buffers
10924                    .into_iter()
10925                    .map(|b| b.read(cx).remote_id().to_proto())
10926                    .collect(),
10927                also_servers: also_stop_servers
10928                    .into_iter()
10929                    .map(|selector| {
10930                        let selector = match selector {
10931                            LanguageServerSelector::Id(language_server_id) => {
10932                                proto::language_server_selector::Selector::ServerId(
10933                                    language_server_id.to_proto(),
10934                                )
10935                            }
10936                            LanguageServerSelector::Name(language_server_name) => {
10937                                proto::language_server_selector::Selector::Name(
10938                                    language_server_name.to_string(),
10939                                )
10940                            }
10941                        };
10942                        proto::LanguageServerSelector {
10943                            selector: Some(selector),
10944                        }
10945                    })
10946                    .collect(),
10947                all: false,
10948            });
10949            cx.background_spawn(async move {
10950                let _ = request.await?;
10951                Ok(())
10952            })
10953        } else {
10954            let task =
10955                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10956            cx.background_spawn(async move {
10957                task.await;
10958                Ok(())
10959            })
10960        }
10961    }
10962
10963    fn stop_local_language_servers_for_buffers(
10964        &mut self,
10965        buffers: &[Entity<Buffer>],
10966        also_stop_servers: HashSet<LanguageServerSelector>,
10967        cx: &mut Context<Self>,
10968    ) -> Task<()> {
10969        let Some(local) = self.as_local_mut() else {
10970            return Task::ready(());
10971        };
10972        let mut language_server_names_to_stop = BTreeSet::default();
10973        let mut language_servers_to_stop = also_stop_servers
10974            .into_iter()
10975            .flat_map(|selector| match selector {
10976                LanguageServerSelector::Id(id) => Some(id),
10977                LanguageServerSelector::Name(name) => {
10978                    language_server_names_to_stop.insert(name);
10979                    None
10980                }
10981            })
10982            .collect::<BTreeSet<_>>();
10983
10984        let mut covered_worktrees = HashSet::default();
10985        for buffer in buffers {
10986            buffer.update(cx, |buffer, cx| {
10987                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10988                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10989                    && covered_worktrees.insert(worktree_id)
10990                {
10991                    language_server_names_to_stop.retain(|name| {
10992                        let old_ids_count = language_servers_to_stop.len();
10993                        let all_language_servers_with_this_name = local
10994                            .language_server_ids
10995                            .iter()
10996                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10997                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10998                        old_ids_count == language_servers_to_stop.len()
10999                    });
11000                }
11001            });
11002        }
11003        for name in language_server_names_to_stop {
11004            language_servers_to_stop.extend(
11005                local
11006                    .language_server_ids
11007                    .iter()
11008                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11009            );
11010        }
11011
11012        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11013        let tasks = language_servers_to_stop
11014            .into_iter()
11015            .map(|server| self.stop_local_language_server(server, cx))
11016            .collect::<Vec<_>>();
11017
11018        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11019    }
11020
11021    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11022        let (worktree, relative_path) =
11023            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11024
11025        let project_path = ProjectPath {
11026            worktree_id: worktree.read(cx).id(),
11027            path: relative_path,
11028        };
11029
11030        Some(
11031            self.buffer_store()
11032                .read(cx)
11033                .get_by_path(&project_path)?
11034                .read(cx),
11035        )
11036    }
11037
11038    #[cfg(any(test, feature = "test-support"))]
11039    pub fn update_diagnostics(
11040        &mut self,
11041        server_id: LanguageServerId,
11042        diagnostics: lsp::PublishDiagnosticsParams,
11043        result_id: Option<SharedString>,
11044        source_kind: DiagnosticSourceKind,
11045        disk_based_sources: &[String],
11046        cx: &mut Context<Self>,
11047    ) -> Result<()> {
11048        self.merge_lsp_diagnostics(
11049            source_kind,
11050            vec![DocumentDiagnosticsUpdate {
11051                diagnostics,
11052                result_id,
11053                server_id,
11054                disk_based_sources: Cow::Borrowed(disk_based_sources),
11055                registration_id: None,
11056            }],
11057            |_, _, _| false,
11058            cx,
11059        )
11060    }
11061
11062    pub fn merge_lsp_diagnostics(
11063        &mut self,
11064        source_kind: DiagnosticSourceKind,
11065        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11066        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11067        cx: &mut Context<Self>,
11068    ) -> Result<()> {
11069        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11070        let updates = lsp_diagnostics
11071            .into_iter()
11072            .filter_map(|update| {
11073                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11074                Some(DocumentDiagnosticsUpdate {
11075                    diagnostics: self.lsp_to_document_diagnostics(
11076                        abs_path,
11077                        source_kind,
11078                        update.server_id,
11079                        update.diagnostics,
11080                        &update.disk_based_sources,
11081                        update.registration_id.clone(),
11082                    ),
11083                    result_id: update.result_id,
11084                    server_id: update.server_id,
11085                    disk_based_sources: update.disk_based_sources,
11086                    registration_id: update.registration_id,
11087                })
11088            })
11089            .collect();
11090        self.merge_diagnostic_entries(updates, merge, cx)?;
11091        Ok(())
11092    }
11093
11094    fn lsp_to_document_diagnostics(
11095        &mut self,
11096        document_abs_path: PathBuf,
11097        source_kind: DiagnosticSourceKind,
11098        server_id: LanguageServerId,
11099        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11100        disk_based_sources: &[String],
11101        registration_id: Option<SharedString>,
11102    ) -> DocumentDiagnostics {
11103        let mut diagnostics = Vec::default();
11104        let mut primary_diagnostic_group_ids = HashMap::default();
11105        let mut sources_by_group_id = HashMap::default();
11106        let mut supporting_diagnostics = HashMap::default();
11107
11108        let adapter = self.language_server_adapter_for_id(server_id);
11109
11110        // Ensure that primary diagnostics are always the most severe
11111        lsp_diagnostics
11112            .diagnostics
11113            .sort_by_key(|item| item.severity);
11114
11115        for diagnostic in &lsp_diagnostics.diagnostics {
11116            let source = diagnostic.source.as_ref();
11117            let range = range_from_lsp(diagnostic.range);
11118            let is_supporting = diagnostic
11119                .related_information
11120                .as_ref()
11121                .is_some_and(|infos| {
11122                    infos.iter().any(|info| {
11123                        primary_diagnostic_group_ids.contains_key(&(
11124                            source,
11125                            diagnostic.code.clone(),
11126                            range_from_lsp(info.location.range),
11127                        ))
11128                    })
11129                });
11130
11131            let is_unnecessary = diagnostic
11132                .tags
11133                .as_ref()
11134                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11135
11136            let underline = self
11137                .language_server_adapter_for_id(server_id)
11138                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11139
11140            if is_supporting {
11141                supporting_diagnostics.insert(
11142                    (source, diagnostic.code.clone(), range),
11143                    (diagnostic.severity, is_unnecessary),
11144                );
11145            } else {
11146                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11147                let is_disk_based =
11148                    source.is_some_and(|source| disk_based_sources.contains(source));
11149
11150                sources_by_group_id.insert(group_id, source);
11151                primary_diagnostic_group_ids
11152                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11153
11154                diagnostics.push(DiagnosticEntry {
11155                    range,
11156                    diagnostic: Diagnostic {
11157                        source: diagnostic.source.clone(),
11158                        source_kind,
11159                        code: diagnostic.code.clone(),
11160                        code_description: diagnostic
11161                            .code_description
11162                            .as_ref()
11163                            .and_then(|d| d.href.clone()),
11164                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11165                        markdown: adapter.as_ref().and_then(|adapter| {
11166                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11167                        }),
11168                        message: diagnostic.message.trim().to_string(),
11169                        group_id,
11170                        is_primary: true,
11171                        is_disk_based,
11172                        is_unnecessary,
11173                        underline,
11174                        data: diagnostic.data.clone(),
11175                        registration_id: registration_id.clone(),
11176                    },
11177                });
11178                if let Some(infos) = &diagnostic.related_information {
11179                    for info in infos {
11180                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11181                            let range = range_from_lsp(info.location.range);
11182                            diagnostics.push(DiagnosticEntry {
11183                                range,
11184                                diagnostic: Diagnostic {
11185                                    source: diagnostic.source.clone(),
11186                                    source_kind,
11187                                    code: diagnostic.code.clone(),
11188                                    code_description: diagnostic
11189                                        .code_description
11190                                        .as_ref()
11191                                        .and_then(|d| d.href.clone()),
11192                                    severity: DiagnosticSeverity::INFORMATION,
11193                                    markdown: adapter.as_ref().and_then(|adapter| {
11194                                        adapter.diagnostic_message_to_markdown(&info.message)
11195                                    }),
11196                                    message: info.message.trim().to_string(),
11197                                    group_id,
11198                                    is_primary: false,
11199                                    is_disk_based,
11200                                    is_unnecessary: false,
11201                                    underline,
11202                                    data: diagnostic.data.clone(),
11203                                    registration_id: registration_id.clone(),
11204                                },
11205                            });
11206                        }
11207                    }
11208                }
11209            }
11210        }
11211
11212        for entry in &mut diagnostics {
11213            let diagnostic = &mut entry.diagnostic;
11214            if !diagnostic.is_primary {
11215                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11216                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11217                    source,
11218                    diagnostic.code.clone(),
11219                    entry.range.clone(),
11220                )) {
11221                    if let Some(severity) = severity {
11222                        diagnostic.severity = severity;
11223                    }
11224                    diagnostic.is_unnecessary = is_unnecessary;
11225                }
11226            }
11227        }
11228
11229        DocumentDiagnostics {
11230            diagnostics,
11231            document_abs_path,
11232            version: lsp_diagnostics.version,
11233        }
11234    }
11235
11236    fn insert_newly_running_language_server(
11237        &mut self,
11238        adapter: Arc<CachedLspAdapter>,
11239        language_server: Arc<LanguageServer>,
11240        server_id: LanguageServerId,
11241        key: LanguageServerSeed,
11242        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11243        cx: &mut Context<Self>,
11244    ) {
11245        let Some(local) = self.as_local_mut() else {
11246            return;
11247        };
11248        // If the language server for this key doesn't match the server id, don't store the
11249        // server. Which will cause it to be dropped, killing the process
11250        if local
11251            .language_server_ids
11252            .get(&key)
11253            .map(|state| state.id != server_id)
11254            .unwrap_or(false)
11255        {
11256            return;
11257        }
11258
11259        // Update language_servers collection with Running variant of LanguageServerState
11260        // indicating that the server is up and running and ready
11261        let workspace_folders = workspace_folders.lock().clone();
11262        language_server.set_workspace_folders(workspace_folders);
11263
11264        let workspace_diagnostics_refresh_tasks = language_server
11265            .capabilities()
11266            .diagnostic_provider
11267            .and_then(|provider| {
11268                local
11269                    .language_server_dynamic_registrations
11270                    .entry(server_id)
11271                    .or_default()
11272                    .diagnostics
11273                    .entry(None)
11274                    .or_insert(provider.clone());
11275                let workspace_refresher =
11276                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11277
11278                Some((None, workspace_refresher))
11279            })
11280            .into_iter()
11281            .collect();
11282        local.language_servers.insert(
11283            server_id,
11284            LanguageServerState::Running {
11285                workspace_diagnostics_refresh_tasks,
11286                adapter: adapter.clone(),
11287                server: language_server.clone(),
11288                simulate_disk_based_diagnostics_completion: None,
11289            },
11290        );
11291        local
11292            .languages
11293            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11294        if let Some(file_ops_caps) = language_server
11295            .capabilities()
11296            .workspace
11297            .as_ref()
11298            .and_then(|ws| ws.file_operations.as_ref())
11299        {
11300            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11301            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11302            if did_rename_caps.or(will_rename_caps).is_some() {
11303                let watcher = RenamePathsWatchedForServer::default()
11304                    .with_did_rename_patterns(did_rename_caps)
11305                    .with_will_rename_patterns(will_rename_caps);
11306                local
11307                    .language_server_paths_watched_for_rename
11308                    .insert(server_id, watcher);
11309            }
11310        }
11311
11312        self.language_server_statuses.insert(
11313            server_id,
11314            LanguageServerStatus {
11315                name: language_server.name(),
11316                pending_work: Default::default(),
11317                has_pending_diagnostic_updates: false,
11318                progress_tokens: Default::default(),
11319                worktree: Some(key.worktree_id),
11320                binary: Some(language_server.binary().clone()),
11321                configuration: Some(language_server.configuration().clone()),
11322                workspace_folders: language_server.workspace_folders(),
11323            },
11324        );
11325
11326        cx.emit(LspStoreEvent::LanguageServerAdded(
11327            server_id,
11328            language_server.name(),
11329            Some(key.worktree_id),
11330        ));
11331
11332        let server_capabilities = language_server.capabilities();
11333        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11334            downstream_client
11335                .send(proto::StartLanguageServer {
11336                    project_id: *project_id,
11337                    server: Some(proto::LanguageServer {
11338                        id: server_id.to_proto(),
11339                        name: language_server.name().to_string(),
11340                        worktree_id: Some(key.worktree_id.to_proto()),
11341                    }),
11342                    capabilities: serde_json::to_string(&server_capabilities)
11343                        .expect("serializing server LSP capabilities"),
11344                })
11345                .log_err();
11346        }
11347        self.lsp_server_capabilities
11348            .insert(server_id, server_capabilities);
11349
11350        // Tell the language server about every open buffer in the worktree that matches the language.
11351        // Also check for buffers in worktrees that reused this server
11352        let mut worktrees_using_server = vec![key.worktree_id];
11353        if let Some(local) = self.as_local() {
11354            // Find all worktrees that have this server in their language server tree
11355            for (worktree_id, servers) in &local.lsp_tree.instances {
11356                if *worktree_id != key.worktree_id {
11357                    for server_map in servers.roots.values() {
11358                        if server_map
11359                            .values()
11360                            .any(|(node, _)| node.id() == Some(server_id))
11361                        {
11362                            worktrees_using_server.push(*worktree_id);
11363                        }
11364                    }
11365                }
11366            }
11367        }
11368
11369        let mut buffer_paths_registered = Vec::new();
11370        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11371            let mut lsp_adapters = HashMap::default();
11372            for buffer_handle in buffer_store.buffers() {
11373                let buffer = buffer_handle.read(cx);
11374                let file = match File::from_dyn(buffer.file()) {
11375                    Some(file) => file,
11376                    None => continue,
11377                };
11378                let language = match buffer.language() {
11379                    Some(language) => language,
11380                    None => continue,
11381                };
11382
11383                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11384                    || !lsp_adapters
11385                        .entry(language.name())
11386                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11387                        .iter()
11388                        .any(|a| a.name == key.name)
11389                {
11390                    continue;
11391                }
11392                // didOpen
11393                let file = match file.as_local() {
11394                    Some(file) => file,
11395                    None => continue,
11396                };
11397
11398                let local = self.as_local_mut().unwrap();
11399
11400                let buffer_id = buffer.remote_id();
11401                if local.registered_buffers.contains_key(&buffer_id) {
11402                    let versions = local
11403                        .buffer_snapshots
11404                        .entry(buffer_id)
11405                        .or_default()
11406                        .entry(server_id)
11407                        .and_modify(|_| {
11408                            assert!(
11409                            false,
11410                            "There should not be an existing snapshot for a newly inserted buffer"
11411                        )
11412                        })
11413                        .or_insert_with(|| {
11414                            vec![LspBufferSnapshot {
11415                                version: 0,
11416                                snapshot: buffer.text_snapshot(),
11417                            }]
11418                        });
11419
11420                    let snapshot = versions.last().unwrap();
11421                    let version = snapshot.version;
11422                    let initial_snapshot = &snapshot.snapshot;
11423                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11424                    language_server.register_buffer(
11425                        uri,
11426                        adapter.language_id(&language.name()),
11427                        version,
11428                        initial_snapshot.text(),
11429                    );
11430                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11431                    local
11432                        .buffers_opened_in_servers
11433                        .entry(buffer_id)
11434                        .or_default()
11435                        .insert(server_id);
11436                }
11437                buffer_handle.update(cx, |buffer, cx| {
11438                    buffer.set_completion_triggers(
11439                        server_id,
11440                        language_server
11441                            .capabilities()
11442                            .completion_provider
11443                            .as_ref()
11444                            .and_then(|provider| {
11445                                provider
11446                                    .trigger_characters
11447                                    .as_ref()
11448                                    .map(|characters| characters.iter().cloned().collect())
11449                            })
11450                            .unwrap_or_default(),
11451                        cx,
11452                    )
11453                });
11454            }
11455        });
11456
11457        for (buffer_id, abs_path) in buffer_paths_registered {
11458            cx.emit(LspStoreEvent::LanguageServerUpdate {
11459                language_server_id: server_id,
11460                name: Some(adapter.name()),
11461                message: proto::update_language_server::Variant::RegisteredForBuffer(
11462                    proto::RegisteredForBuffer {
11463                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11464                        buffer_id: buffer_id.to_proto(),
11465                    },
11466                ),
11467            });
11468        }
11469
11470        cx.notify();
11471    }
11472
11473    pub fn language_servers_running_disk_based_diagnostics(
11474        &self,
11475    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11476        self.language_server_statuses
11477            .iter()
11478            .filter_map(|(id, status)| {
11479                if status.has_pending_diagnostic_updates {
11480                    Some(*id)
11481                } else {
11482                    None
11483                }
11484            })
11485    }
11486
11487    pub(crate) fn cancel_language_server_work_for_buffers(
11488        &mut self,
11489        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11490        cx: &mut Context<Self>,
11491    ) {
11492        if let Some((client, project_id)) = self.upstream_client() {
11493            let request = client.request(proto::CancelLanguageServerWork {
11494                project_id,
11495                work: Some(proto::cancel_language_server_work::Work::Buffers(
11496                    proto::cancel_language_server_work::Buffers {
11497                        buffer_ids: buffers
11498                            .into_iter()
11499                            .map(|b| b.read(cx).remote_id().to_proto())
11500                            .collect(),
11501                    },
11502                )),
11503            });
11504            cx.background_spawn(request).detach_and_log_err(cx);
11505        } else if let Some(local) = self.as_local() {
11506            let servers = buffers
11507                .into_iter()
11508                .flat_map(|buffer| {
11509                    buffer.update(cx, |buffer, cx| {
11510                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11511                    })
11512                })
11513                .collect::<HashSet<_>>();
11514            for server_id in servers {
11515                self.cancel_language_server_work(server_id, None, cx);
11516            }
11517        }
11518    }
11519
11520    pub(crate) fn cancel_language_server_work(
11521        &mut self,
11522        server_id: LanguageServerId,
11523        token_to_cancel: Option<ProgressToken>,
11524        cx: &mut Context<Self>,
11525    ) {
11526        if let Some(local) = self.as_local() {
11527            let status = self.language_server_statuses.get(&server_id);
11528            let server = local.language_servers.get(&server_id);
11529            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11530            {
11531                for (token, progress) in &status.pending_work {
11532                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11533                        && token != token_to_cancel
11534                    {
11535                        continue;
11536                    }
11537                    if progress.is_cancellable {
11538                        server
11539                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11540                                WorkDoneProgressCancelParams {
11541                                    token: token.to_lsp(),
11542                                },
11543                            )
11544                            .ok();
11545                    }
11546                }
11547            }
11548        } else if let Some((client, project_id)) = self.upstream_client() {
11549            let request = client.request(proto::CancelLanguageServerWork {
11550                project_id,
11551                work: Some(
11552                    proto::cancel_language_server_work::Work::LanguageServerWork(
11553                        proto::cancel_language_server_work::LanguageServerWork {
11554                            language_server_id: server_id.to_proto(),
11555                            token: token_to_cancel.map(|token| token.to_proto()),
11556                        },
11557                    ),
11558                ),
11559            });
11560            cx.background_spawn(request).detach_and_log_err(cx);
11561        }
11562    }
11563
11564    fn register_supplementary_language_server(
11565        &mut self,
11566        id: LanguageServerId,
11567        name: LanguageServerName,
11568        server: Arc<LanguageServer>,
11569        cx: &mut Context<Self>,
11570    ) {
11571        if let Some(local) = self.as_local_mut() {
11572            local
11573                .supplementary_language_servers
11574                .insert(id, (name.clone(), server));
11575            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11576        }
11577    }
11578
11579    fn unregister_supplementary_language_server(
11580        &mut self,
11581        id: LanguageServerId,
11582        cx: &mut Context<Self>,
11583    ) {
11584        if let Some(local) = self.as_local_mut() {
11585            local.supplementary_language_servers.remove(&id);
11586            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11587        }
11588    }
11589
11590    pub(crate) fn supplementary_language_servers(
11591        &self,
11592    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11593        self.as_local().into_iter().flat_map(|local| {
11594            local
11595                .supplementary_language_servers
11596                .iter()
11597                .map(|(id, (name, _))| (*id, name.clone()))
11598        })
11599    }
11600
11601    pub fn language_server_adapter_for_id(
11602        &self,
11603        id: LanguageServerId,
11604    ) -> Option<Arc<CachedLspAdapter>> {
11605        self.as_local()
11606            .and_then(|local| local.language_servers.get(&id))
11607            .and_then(|language_server_state| match language_server_state {
11608                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11609                _ => None,
11610            })
11611    }
11612
11613    pub(super) fn update_local_worktree_language_servers(
11614        &mut self,
11615        worktree_handle: &Entity<Worktree>,
11616        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11617        cx: &mut Context<Self>,
11618    ) {
11619        if changes.is_empty() {
11620            return;
11621        }
11622
11623        let Some(local) = self.as_local() else { return };
11624
11625        local.prettier_store.update(cx, |prettier_store, cx| {
11626            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11627        });
11628
11629        let worktree_id = worktree_handle.read(cx).id();
11630        let mut language_server_ids = local
11631            .language_server_ids
11632            .iter()
11633            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11634            .collect::<Vec<_>>();
11635        language_server_ids.sort();
11636        language_server_ids.dedup();
11637
11638        // let abs_path = worktree_handle.read(cx).abs_path();
11639        for server_id in &language_server_ids {
11640            if let Some(LanguageServerState::Running { server, .. }) =
11641                local.language_servers.get(server_id)
11642                && let Some(watched_paths) = local
11643                    .language_server_watched_paths
11644                    .get(server_id)
11645                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11646            {
11647                let params = lsp::DidChangeWatchedFilesParams {
11648                    changes: changes
11649                        .iter()
11650                        .filter_map(|(path, _, change)| {
11651                            if !watched_paths.is_match(path.as_std_path()) {
11652                                return None;
11653                            }
11654                            let typ = match change {
11655                                PathChange::Loaded => return None,
11656                                PathChange::Added => lsp::FileChangeType::CREATED,
11657                                PathChange::Removed => lsp::FileChangeType::DELETED,
11658                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11659                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11660                            };
11661                            let uri = lsp::Uri::from_file_path(
11662                                worktree_handle.read(cx).absolutize(&path),
11663                            )
11664                            .ok()?;
11665                            Some(lsp::FileEvent { uri, typ })
11666                        })
11667                        .collect(),
11668                };
11669                if !params.changes.is_empty() {
11670                    server
11671                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11672                        .ok();
11673                }
11674            }
11675        }
11676        for (path, _, _) in changes {
11677            if let Some(file_name) = path.file_name()
11678                && local.watched_manifest_filenames.contains(file_name)
11679            {
11680                self.request_workspace_config_refresh();
11681                break;
11682            }
11683        }
11684    }
11685
11686    pub fn wait_for_remote_buffer(
11687        &mut self,
11688        id: BufferId,
11689        cx: &mut Context<Self>,
11690    ) -> Task<Result<Entity<Buffer>>> {
11691        self.buffer_store.update(cx, |buffer_store, cx| {
11692            buffer_store.wait_for_remote_buffer(id, cx)
11693        })
11694    }
11695
11696    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11697        let mut result = proto::Symbol {
11698            language_server_name: symbol.language_server_name.0.to_string(),
11699            source_worktree_id: symbol.source_worktree_id.to_proto(),
11700            language_server_id: symbol.source_language_server_id.to_proto(),
11701            name: symbol.name.clone(),
11702            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11703            start: Some(proto::PointUtf16 {
11704                row: symbol.range.start.0.row,
11705                column: symbol.range.start.0.column,
11706            }),
11707            end: Some(proto::PointUtf16 {
11708                row: symbol.range.end.0.row,
11709                column: symbol.range.end.0.column,
11710            }),
11711            worktree_id: Default::default(),
11712            path: Default::default(),
11713            signature: Default::default(),
11714        };
11715        match &symbol.path {
11716            SymbolLocation::InProject(path) => {
11717                result.worktree_id = path.worktree_id.to_proto();
11718                result.path = path.path.to_proto();
11719            }
11720            SymbolLocation::OutsideProject {
11721                abs_path,
11722                signature,
11723            } => {
11724                result.path = abs_path.to_string_lossy().into_owned();
11725                result.signature = signature.to_vec();
11726            }
11727        }
11728        result
11729    }
11730
11731    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11732        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11733        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11734        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11735
11736        let path = if serialized_symbol.signature.is_empty() {
11737            SymbolLocation::InProject(ProjectPath {
11738                worktree_id,
11739                path: RelPath::from_proto(&serialized_symbol.path)
11740                    .context("invalid symbol path")?,
11741            })
11742        } else {
11743            SymbolLocation::OutsideProject {
11744                abs_path: Path::new(&serialized_symbol.path).into(),
11745                signature: serialized_symbol
11746                    .signature
11747                    .try_into()
11748                    .map_err(|_| anyhow!("invalid signature"))?,
11749            }
11750        };
11751
11752        let start = serialized_symbol.start.context("invalid start")?;
11753        let end = serialized_symbol.end.context("invalid end")?;
11754        Ok(CoreSymbol {
11755            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11756            source_worktree_id,
11757            source_language_server_id: LanguageServerId::from_proto(
11758                serialized_symbol.language_server_id,
11759            ),
11760            path,
11761            name: serialized_symbol.name,
11762            range: Unclipped(PointUtf16::new(start.row, start.column))
11763                ..Unclipped(PointUtf16::new(end.row, end.column)),
11764            kind,
11765        })
11766    }
11767
11768    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11769        let mut serialized_completion = proto::Completion {
11770            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11771            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11772            new_text: completion.new_text.clone(),
11773            ..proto::Completion::default()
11774        };
11775        match &completion.source {
11776            CompletionSource::Lsp {
11777                insert_range,
11778                server_id,
11779                lsp_completion,
11780                lsp_defaults,
11781                resolved,
11782            } => {
11783                let (old_insert_start, old_insert_end) = insert_range
11784                    .as_ref()
11785                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11786                    .unzip();
11787
11788                serialized_completion.old_insert_start = old_insert_start;
11789                serialized_completion.old_insert_end = old_insert_end;
11790                serialized_completion.source = proto::completion::Source::Lsp as i32;
11791                serialized_completion.server_id = server_id.0 as u64;
11792                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11793                serialized_completion.lsp_defaults = lsp_defaults
11794                    .as_deref()
11795                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11796                serialized_completion.resolved = *resolved;
11797            }
11798            CompletionSource::BufferWord {
11799                word_range,
11800                resolved,
11801            } => {
11802                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11803                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11804                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11805                serialized_completion.resolved = *resolved;
11806            }
11807            CompletionSource::Custom => {
11808                serialized_completion.source = proto::completion::Source::Custom as i32;
11809                serialized_completion.resolved = true;
11810            }
11811            CompletionSource::Dap { sort_text } => {
11812                serialized_completion.source = proto::completion::Source::Dap as i32;
11813                serialized_completion.sort_text = Some(sort_text.clone());
11814            }
11815        }
11816
11817        serialized_completion
11818    }
11819
11820    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11821        let old_replace_start = completion
11822            .old_replace_start
11823            .and_then(deserialize_anchor)
11824            .context("invalid old start")?;
11825        let old_replace_end = completion
11826            .old_replace_end
11827            .and_then(deserialize_anchor)
11828            .context("invalid old end")?;
11829        let insert_range = {
11830            match completion.old_insert_start.zip(completion.old_insert_end) {
11831                Some((start, end)) => {
11832                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11833                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11834                    Some(start..end)
11835                }
11836                None => None,
11837            }
11838        };
11839        Ok(CoreCompletion {
11840            replace_range: old_replace_start..old_replace_end,
11841            new_text: completion.new_text,
11842            source: match proto::completion::Source::from_i32(completion.source) {
11843                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11844                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11845                    insert_range,
11846                    server_id: LanguageServerId::from_proto(completion.server_id),
11847                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11848                    lsp_defaults: completion
11849                        .lsp_defaults
11850                        .as_deref()
11851                        .map(serde_json::from_slice)
11852                        .transpose()?,
11853                    resolved: completion.resolved,
11854                },
11855                Some(proto::completion::Source::BufferWord) => {
11856                    let word_range = completion
11857                        .buffer_word_start
11858                        .and_then(deserialize_anchor)
11859                        .context("invalid buffer word start")?
11860                        ..completion
11861                            .buffer_word_end
11862                            .and_then(deserialize_anchor)
11863                            .context("invalid buffer word end")?;
11864                    CompletionSource::BufferWord {
11865                        word_range,
11866                        resolved: completion.resolved,
11867                    }
11868                }
11869                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11870                    sort_text: completion
11871                        .sort_text
11872                        .context("expected sort text to exist")?,
11873                },
11874                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11875            },
11876        })
11877    }
11878
11879    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11880        let (kind, lsp_action) = match &action.lsp_action {
11881            LspAction::Action(code_action) => (
11882                proto::code_action::Kind::Action as i32,
11883                serde_json::to_vec(code_action).unwrap(),
11884            ),
11885            LspAction::Command(command) => (
11886                proto::code_action::Kind::Command as i32,
11887                serde_json::to_vec(command).unwrap(),
11888            ),
11889            LspAction::CodeLens(code_lens) => (
11890                proto::code_action::Kind::CodeLens as i32,
11891                serde_json::to_vec(code_lens).unwrap(),
11892            ),
11893        };
11894
11895        proto::CodeAction {
11896            server_id: action.server_id.0 as u64,
11897            start: Some(serialize_anchor(&action.range.start)),
11898            end: Some(serialize_anchor(&action.range.end)),
11899            lsp_action,
11900            kind,
11901            resolved: action.resolved,
11902        }
11903    }
11904
11905    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11906        let start = action
11907            .start
11908            .and_then(deserialize_anchor)
11909            .context("invalid start")?;
11910        let end = action
11911            .end
11912            .and_then(deserialize_anchor)
11913            .context("invalid end")?;
11914        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11915            Some(proto::code_action::Kind::Action) => {
11916                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11917            }
11918            Some(proto::code_action::Kind::Command) => {
11919                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11920            }
11921            Some(proto::code_action::Kind::CodeLens) => {
11922                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11923            }
11924            None => anyhow::bail!("Unknown action kind {}", action.kind),
11925        };
11926        Ok(CodeAction {
11927            server_id: LanguageServerId(action.server_id as usize),
11928            range: start..end,
11929            resolved: action.resolved,
11930            lsp_action,
11931        })
11932    }
11933
11934    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11935        match &formatting_result {
11936            Ok(_) => self.last_formatting_failure = None,
11937            Err(error) => {
11938                let error_string = format!("{error:#}");
11939                log::error!("Formatting failed: {error_string}");
11940                self.last_formatting_failure
11941                    .replace(error_string.lines().join(" "));
11942            }
11943        }
11944    }
11945
11946    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11947        self.lsp_server_capabilities.remove(&for_server);
11948        for lsp_data in self.lsp_data.values_mut() {
11949            lsp_data.remove_server_data(for_server);
11950        }
11951        if let Some(local) = self.as_local_mut() {
11952            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11953            local
11954                .workspace_pull_diagnostics_result_ids
11955                .remove(&for_server);
11956            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11957                buffer_servers.remove(&for_server);
11958            }
11959        }
11960    }
11961
11962    pub fn result_id_for_buffer_pull(
11963        &self,
11964        server_id: LanguageServerId,
11965        buffer_id: BufferId,
11966        registration_id: &Option<SharedString>,
11967        cx: &App,
11968    ) -> Option<SharedString> {
11969        let abs_path = self
11970            .buffer_store
11971            .read(cx)
11972            .get(buffer_id)
11973            .and_then(|b| File::from_dyn(b.read(cx).file()))
11974            .map(|f| f.abs_path(cx))?;
11975        self.as_local()?
11976            .buffer_pull_diagnostics_result_ids
11977            .get(&server_id)?
11978            .get(registration_id)?
11979            .get(&abs_path)?
11980            .clone()
11981    }
11982
11983    /// Gets all result_ids for a workspace diagnostics pull request.
11984    /// 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.
11985    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
11986    pub fn result_ids_for_workspace_refresh(
11987        &self,
11988        server_id: LanguageServerId,
11989        registration_id: &Option<SharedString>,
11990    ) -> HashMap<PathBuf, SharedString> {
11991        let Some(local) = self.as_local() else {
11992            return HashMap::default();
11993        };
11994        local
11995            .workspace_pull_diagnostics_result_ids
11996            .get(&server_id)
11997            .into_iter()
11998            .filter_map(|diagnostics| diagnostics.get(registration_id))
11999            .flatten()
12000            .filter_map(|(abs_path, result_id)| {
12001                let result_id = local
12002                    .buffer_pull_diagnostics_result_ids
12003                    .get(&server_id)
12004                    .and_then(|buffer_ids_result_ids| {
12005                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12006                    })
12007                    .cloned()
12008                    .flatten()
12009                    .or_else(|| result_id.clone())?;
12010                Some((abs_path.clone(), result_id))
12011            })
12012            .collect()
12013    }
12014
12015    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12016        if let Some(LanguageServerState::Running {
12017            workspace_diagnostics_refresh_tasks,
12018            ..
12019        }) = self
12020            .as_local_mut()
12021            .and_then(|local| local.language_servers.get_mut(&server_id))
12022        {
12023            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12024                diagnostics.refresh_tx.try_send(()).ok();
12025            }
12026        }
12027    }
12028
12029    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12030        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12031            return;
12032        };
12033        let Some(local) = self.as_local_mut() else {
12034            return;
12035        };
12036
12037        for server_id in buffer.update(cx, |buffer, cx| {
12038            local.language_server_ids_for_buffer(buffer, cx)
12039        }) {
12040            if let Some(LanguageServerState::Running {
12041                workspace_diagnostics_refresh_tasks,
12042                ..
12043            }) = local.language_servers.get_mut(&server_id)
12044            {
12045                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12046                    diagnostics.refresh_tx.try_send(()).ok();
12047                }
12048            }
12049        }
12050    }
12051
12052    fn apply_workspace_diagnostic_report(
12053        &mut self,
12054        server_id: LanguageServerId,
12055        report: lsp::WorkspaceDiagnosticReportResult,
12056        registration_id: Option<SharedString>,
12057        cx: &mut Context<Self>,
12058    ) {
12059        let workspace_diagnostics =
12060            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12061                report,
12062                server_id,
12063                registration_id,
12064            );
12065        let mut unchanged_buffers = HashMap::default();
12066        let workspace_diagnostics_updates = workspace_diagnostics
12067            .into_iter()
12068            .filter_map(
12069                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12070                    LspPullDiagnostics::Response {
12071                        server_id,
12072                        uri,
12073                        diagnostics,
12074                        registration_id,
12075                    } => Some((
12076                        server_id,
12077                        uri,
12078                        diagnostics,
12079                        workspace_diagnostics.version,
12080                        registration_id,
12081                    )),
12082                    LspPullDiagnostics::Default => None,
12083                },
12084            )
12085            .fold(
12086                HashMap::default(),
12087                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12088                    let (result_id, diagnostics) = match diagnostics {
12089                        PulledDiagnostics::Unchanged { result_id } => {
12090                            unchanged_buffers
12091                                .entry(new_registration_id.clone())
12092                                .or_insert_with(HashSet::default)
12093                                .insert(uri.clone());
12094                            (Some(result_id), Vec::new())
12095                        }
12096                        PulledDiagnostics::Changed {
12097                            result_id,
12098                            diagnostics,
12099                        } => (result_id, diagnostics),
12100                    };
12101                    let disk_based_sources = Cow::Owned(
12102                        self.language_server_adapter_for_id(server_id)
12103                            .as_ref()
12104                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12105                            .unwrap_or(&[])
12106                            .to_vec(),
12107                    );
12108
12109                    let Some(abs_path) = uri.to_file_path().ok() else {
12110                        return acc;
12111                    };
12112                    let Some((worktree, relative_path)) =
12113                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12114                    else {
12115                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12116                        return acc;
12117                    };
12118                    let worktree_id = worktree.read(cx).id();
12119                    let project_path = ProjectPath {
12120                        worktree_id,
12121                        path: relative_path,
12122                    };
12123                    if let Some(local_lsp_store) = self.as_local_mut() {
12124                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12125                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12126                    }
12127                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12128                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12129                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12130                        acc.entry(server_id)
12131                            .or_insert_with(HashMap::default)
12132                            .entry(new_registration_id.clone())
12133                            .or_insert_with(Vec::new)
12134                            .push(DocumentDiagnosticsUpdate {
12135                                server_id,
12136                                diagnostics: lsp::PublishDiagnosticsParams {
12137                                    uri,
12138                                    diagnostics,
12139                                    version,
12140                                },
12141                                result_id,
12142                                disk_based_sources,
12143                                registration_id: new_registration_id,
12144                            });
12145                    }
12146                    acc
12147                },
12148            );
12149
12150        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12151            for (registration_id, diagnostic_updates) in diagnostic_updates {
12152                self.merge_lsp_diagnostics(
12153                    DiagnosticSourceKind::Pulled,
12154                    diagnostic_updates,
12155                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12156                        DiagnosticSourceKind::Pulled => {
12157                            old_diagnostic.registration_id != registration_id
12158                                || unchanged_buffers
12159                                    .get(&old_diagnostic.registration_id)
12160                                    .is_some_and(|unchanged_buffers| {
12161                                        unchanged_buffers.contains(&document_uri)
12162                                    })
12163                        }
12164                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12165                    },
12166                    cx,
12167                )
12168                .log_err();
12169            }
12170        }
12171    }
12172
12173    fn register_server_capabilities(
12174        &mut self,
12175        server_id: LanguageServerId,
12176        params: lsp::RegistrationParams,
12177        cx: &mut Context<Self>,
12178    ) -> anyhow::Result<()> {
12179        let server = self
12180            .language_server_for_id(server_id)
12181            .with_context(|| format!("no server {server_id} found"))?;
12182        for reg in params.registrations {
12183            match reg.method.as_str() {
12184                "workspace/didChangeWatchedFiles" => {
12185                    if let Some(options) = reg.register_options {
12186                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12187                            let caps = serde_json::from_value(options)?;
12188                            local_lsp_store
12189                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12190                            true
12191                        } else {
12192                            false
12193                        };
12194                        if notify {
12195                            notify_server_capabilities_updated(&server, cx);
12196                        }
12197                    }
12198                }
12199                "workspace/didChangeConfiguration" => {
12200                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12201                }
12202                "workspace/didChangeWorkspaceFolders" => {
12203                    // In this case register options is an empty object, we can ignore it
12204                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12205                        supported: Some(true),
12206                        change_notifications: Some(OneOf::Right(reg.id)),
12207                    };
12208                    server.update_capabilities(|capabilities| {
12209                        capabilities
12210                            .workspace
12211                            .get_or_insert_default()
12212                            .workspace_folders = Some(caps);
12213                    });
12214                    notify_server_capabilities_updated(&server, cx);
12215                }
12216                "workspace/symbol" => {
12217                    let options = parse_register_capabilities(reg)?;
12218                    server.update_capabilities(|capabilities| {
12219                        capabilities.workspace_symbol_provider = Some(options);
12220                    });
12221                    notify_server_capabilities_updated(&server, cx);
12222                }
12223                "workspace/fileOperations" => {
12224                    if let Some(options) = reg.register_options {
12225                        let caps = serde_json::from_value(options)?;
12226                        server.update_capabilities(|capabilities| {
12227                            capabilities
12228                                .workspace
12229                                .get_or_insert_default()
12230                                .file_operations = Some(caps);
12231                        });
12232                        notify_server_capabilities_updated(&server, cx);
12233                    }
12234                }
12235                "workspace/executeCommand" => {
12236                    if let Some(options) = reg.register_options {
12237                        let options = serde_json::from_value(options)?;
12238                        server.update_capabilities(|capabilities| {
12239                            capabilities.execute_command_provider = Some(options);
12240                        });
12241                        notify_server_capabilities_updated(&server, cx);
12242                    }
12243                }
12244                "textDocument/rangeFormatting" => {
12245                    let options = parse_register_capabilities(reg)?;
12246                    server.update_capabilities(|capabilities| {
12247                        capabilities.document_range_formatting_provider = Some(options);
12248                    });
12249                    notify_server_capabilities_updated(&server, cx);
12250                }
12251                "textDocument/onTypeFormatting" => {
12252                    if let Some(options) = reg
12253                        .register_options
12254                        .map(serde_json::from_value)
12255                        .transpose()?
12256                    {
12257                        server.update_capabilities(|capabilities| {
12258                            capabilities.document_on_type_formatting_provider = Some(options);
12259                        });
12260                        notify_server_capabilities_updated(&server, cx);
12261                    }
12262                }
12263                "textDocument/formatting" => {
12264                    let options = parse_register_capabilities(reg)?;
12265                    server.update_capabilities(|capabilities| {
12266                        capabilities.document_formatting_provider = Some(options);
12267                    });
12268                    notify_server_capabilities_updated(&server, cx);
12269                }
12270                "textDocument/rename" => {
12271                    let options = parse_register_capabilities(reg)?;
12272                    server.update_capabilities(|capabilities| {
12273                        capabilities.rename_provider = Some(options);
12274                    });
12275                    notify_server_capabilities_updated(&server, cx);
12276                }
12277                "textDocument/inlayHint" => {
12278                    let options = parse_register_capabilities(reg)?;
12279                    server.update_capabilities(|capabilities| {
12280                        capabilities.inlay_hint_provider = Some(options);
12281                    });
12282                    notify_server_capabilities_updated(&server, cx);
12283                }
12284                "textDocument/documentSymbol" => {
12285                    let options = parse_register_capabilities(reg)?;
12286                    server.update_capabilities(|capabilities| {
12287                        capabilities.document_symbol_provider = Some(options);
12288                    });
12289                    notify_server_capabilities_updated(&server, cx);
12290                }
12291                "textDocument/codeAction" => {
12292                    let options = parse_register_capabilities(reg)?;
12293                    let provider = match options {
12294                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12295                        OneOf::Right(caps) => caps,
12296                    };
12297                    server.update_capabilities(|capabilities| {
12298                        capabilities.code_action_provider = Some(provider);
12299                    });
12300                    notify_server_capabilities_updated(&server, cx);
12301                }
12302                "textDocument/definition" => {
12303                    let options = parse_register_capabilities(reg)?;
12304                    server.update_capabilities(|capabilities| {
12305                        capabilities.definition_provider = Some(options);
12306                    });
12307                    notify_server_capabilities_updated(&server, cx);
12308                }
12309                "textDocument/completion" => {
12310                    if let Some(caps) = reg
12311                        .register_options
12312                        .map(serde_json::from_value::<CompletionOptions>)
12313                        .transpose()?
12314                    {
12315                        server.update_capabilities(|capabilities| {
12316                            capabilities.completion_provider = Some(caps.clone());
12317                        });
12318
12319                        if let Some(local) = self.as_local() {
12320                            let mut buffers_with_language_server = Vec::new();
12321                            for handle in self.buffer_store.read(cx).buffers() {
12322                                let buffer_id = handle.read(cx).remote_id();
12323                                if local
12324                                    .buffers_opened_in_servers
12325                                    .get(&buffer_id)
12326                                    .filter(|s| s.contains(&server_id))
12327                                    .is_some()
12328                                {
12329                                    buffers_with_language_server.push(handle);
12330                                }
12331                            }
12332                            let triggers = caps
12333                                .trigger_characters
12334                                .unwrap_or_default()
12335                                .into_iter()
12336                                .collect::<BTreeSet<_>>();
12337                            for handle in buffers_with_language_server {
12338                                let triggers = triggers.clone();
12339                                let _ = handle.update(cx, move |buffer, cx| {
12340                                    buffer.set_completion_triggers(server_id, triggers, cx);
12341                                });
12342                            }
12343                        }
12344                        notify_server_capabilities_updated(&server, cx);
12345                    }
12346                }
12347                "textDocument/hover" => {
12348                    let options = parse_register_capabilities(reg)?;
12349                    let provider = match options {
12350                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12351                        OneOf::Right(caps) => caps,
12352                    };
12353                    server.update_capabilities(|capabilities| {
12354                        capabilities.hover_provider = Some(provider);
12355                    });
12356                    notify_server_capabilities_updated(&server, cx);
12357                }
12358                "textDocument/signatureHelp" => {
12359                    if let Some(caps) = reg
12360                        .register_options
12361                        .map(serde_json::from_value)
12362                        .transpose()?
12363                    {
12364                        server.update_capabilities(|capabilities| {
12365                            capabilities.signature_help_provider = Some(caps);
12366                        });
12367                        notify_server_capabilities_updated(&server, cx);
12368                    }
12369                }
12370                "textDocument/didChange" => {
12371                    if let Some(sync_kind) = reg
12372                        .register_options
12373                        .and_then(|opts| opts.get("syncKind").cloned())
12374                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12375                        .transpose()?
12376                    {
12377                        server.update_capabilities(|capabilities| {
12378                            let mut sync_options =
12379                                Self::take_text_document_sync_options(capabilities);
12380                            sync_options.change = Some(sync_kind);
12381                            capabilities.text_document_sync =
12382                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12383                        });
12384                        notify_server_capabilities_updated(&server, cx);
12385                    }
12386                }
12387                "textDocument/didSave" => {
12388                    if let Some(include_text) = reg
12389                        .register_options
12390                        .map(|opts| {
12391                            let transpose = opts
12392                                .get("includeText")
12393                                .cloned()
12394                                .map(serde_json::from_value::<Option<bool>>)
12395                                .transpose();
12396                            match transpose {
12397                                Ok(value) => Ok(value.flatten()),
12398                                Err(e) => Err(e),
12399                            }
12400                        })
12401                        .transpose()?
12402                    {
12403                        server.update_capabilities(|capabilities| {
12404                            let mut sync_options =
12405                                Self::take_text_document_sync_options(capabilities);
12406                            sync_options.save =
12407                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12408                                    include_text,
12409                                }));
12410                            capabilities.text_document_sync =
12411                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12412                        });
12413                        notify_server_capabilities_updated(&server, cx);
12414                    }
12415                }
12416                "textDocument/codeLens" => {
12417                    if let Some(caps) = reg
12418                        .register_options
12419                        .map(serde_json::from_value)
12420                        .transpose()?
12421                    {
12422                        server.update_capabilities(|capabilities| {
12423                            capabilities.code_lens_provider = Some(caps);
12424                        });
12425                        notify_server_capabilities_updated(&server, cx);
12426                    }
12427                }
12428                "textDocument/diagnostic" => {
12429                    if let Some(caps) = reg
12430                        .register_options
12431                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12432                        .transpose()?
12433                    {
12434                        let local = self
12435                            .as_local_mut()
12436                            .context("Expected LSP Store to be local")?;
12437                        let state = local
12438                            .language_servers
12439                            .get_mut(&server_id)
12440                            .context("Could not obtain Language Servers state")?;
12441                        local
12442                            .language_server_dynamic_registrations
12443                            .entry(server_id)
12444                            .or_default()
12445                            .diagnostics
12446                            .insert(Some(reg.id.clone()), caps.clone());
12447
12448                        let supports_workspace_diagnostics =
12449                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12450                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12451                                    diagnostic_options.workspace_diagnostics
12452                                }
12453                                DiagnosticServerCapabilities::RegistrationOptions(
12454                                    diagnostic_registration_options,
12455                                ) => {
12456                                    diagnostic_registration_options
12457                                        .diagnostic_options
12458                                        .workspace_diagnostics
12459                                }
12460                            };
12461
12462                        if supports_workspace_diagnostics(&caps) {
12463                            if let LanguageServerState::Running {
12464                                workspace_diagnostics_refresh_tasks,
12465                                ..
12466                            } = state
12467                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12468                                    Some(reg.id.clone()),
12469                                    caps.clone(),
12470                                    server.clone(),
12471                                    cx,
12472                                )
12473                            {
12474                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12475                            }
12476                        }
12477
12478                        server.update_capabilities(|capabilities| {
12479                            capabilities.diagnostic_provider = Some(caps);
12480                        });
12481
12482                        notify_server_capabilities_updated(&server, cx);
12483                    }
12484                }
12485                "textDocument/documentColor" => {
12486                    let options = parse_register_capabilities(reg)?;
12487                    let provider = match options {
12488                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12489                        OneOf::Right(caps) => caps,
12490                    };
12491                    server.update_capabilities(|capabilities| {
12492                        capabilities.color_provider = Some(provider);
12493                    });
12494                    notify_server_capabilities_updated(&server, cx);
12495                }
12496                _ => log::warn!("unhandled capability registration: {reg:?}"),
12497            }
12498        }
12499
12500        Ok(())
12501    }
12502
12503    fn unregister_server_capabilities(
12504        &mut self,
12505        server_id: LanguageServerId,
12506        params: lsp::UnregistrationParams,
12507        cx: &mut Context<Self>,
12508    ) -> anyhow::Result<()> {
12509        let server = self
12510            .language_server_for_id(server_id)
12511            .with_context(|| format!("no server {server_id} found"))?;
12512        for unreg in params.unregisterations.iter() {
12513            match unreg.method.as_str() {
12514                "workspace/didChangeWatchedFiles" => {
12515                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12516                        local_lsp_store
12517                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12518                        true
12519                    } else {
12520                        false
12521                    };
12522                    if notify {
12523                        notify_server_capabilities_updated(&server, cx);
12524                    }
12525                }
12526                "workspace/didChangeConfiguration" => {
12527                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12528                }
12529                "workspace/didChangeWorkspaceFolders" => {
12530                    server.update_capabilities(|capabilities| {
12531                        capabilities
12532                            .workspace
12533                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12534                                workspace_folders: None,
12535                                file_operations: None,
12536                            })
12537                            .workspace_folders = None;
12538                    });
12539                    notify_server_capabilities_updated(&server, cx);
12540                }
12541                "workspace/symbol" => {
12542                    server.update_capabilities(|capabilities| {
12543                        capabilities.workspace_symbol_provider = None
12544                    });
12545                    notify_server_capabilities_updated(&server, cx);
12546                }
12547                "workspace/fileOperations" => {
12548                    server.update_capabilities(|capabilities| {
12549                        capabilities
12550                            .workspace
12551                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12552                                workspace_folders: None,
12553                                file_operations: None,
12554                            })
12555                            .file_operations = None;
12556                    });
12557                    notify_server_capabilities_updated(&server, cx);
12558                }
12559                "workspace/executeCommand" => {
12560                    server.update_capabilities(|capabilities| {
12561                        capabilities.execute_command_provider = None;
12562                    });
12563                    notify_server_capabilities_updated(&server, cx);
12564                }
12565                "textDocument/rangeFormatting" => {
12566                    server.update_capabilities(|capabilities| {
12567                        capabilities.document_range_formatting_provider = None
12568                    });
12569                    notify_server_capabilities_updated(&server, cx);
12570                }
12571                "textDocument/onTypeFormatting" => {
12572                    server.update_capabilities(|capabilities| {
12573                        capabilities.document_on_type_formatting_provider = None;
12574                    });
12575                    notify_server_capabilities_updated(&server, cx);
12576                }
12577                "textDocument/formatting" => {
12578                    server.update_capabilities(|capabilities| {
12579                        capabilities.document_formatting_provider = None;
12580                    });
12581                    notify_server_capabilities_updated(&server, cx);
12582                }
12583                "textDocument/rename" => {
12584                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12585                    notify_server_capabilities_updated(&server, cx);
12586                }
12587                "textDocument/codeAction" => {
12588                    server.update_capabilities(|capabilities| {
12589                        capabilities.code_action_provider = None;
12590                    });
12591                    notify_server_capabilities_updated(&server, cx);
12592                }
12593                "textDocument/definition" => {
12594                    server.update_capabilities(|capabilities| {
12595                        capabilities.definition_provider = None;
12596                    });
12597                    notify_server_capabilities_updated(&server, cx);
12598                }
12599                "textDocument/completion" => {
12600                    server.update_capabilities(|capabilities| {
12601                        capabilities.completion_provider = None;
12602                    });
12603                    notify_server_capabilities_updated(&server, cx);
12604                }
12605                "textDocument/hover" => {
12606                    server.update_capabilities(|capabilities| {
12607                        capabilities.hover_provider = None;
12608                    });
12609                    notify_server_capabilities_updated(&server, cx);
12610                }
12611                "textDocument/signatureHelp" => {
12612                    server.update_capabilities(|capabilities| {
12613                        capabilities.signature_help_provider = None;
12614                    });
12615                    notify_server_capabilities_updated(&server, cx);
12616                }
12617                "textDocument/didChange" => {
12618                    server.update_capabilities(|capabilities| {
12619                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12620                        sync_options.change = None;
12621                        capabilities.text_document_sync =
12622                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12623                    });
12624                    notify_server_capabilities_updated(&server, cx);
12625                }
12626                "textDocument/didSave" => {
12627                    server.update_capabilities(|capabilities| {
12628                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12629                        sync_options.save = None;
12630                        capabilities.text_document_sync =
12631                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12632                    });
12633                    notify_server_capabilities_updated(&server, cx);
12634                }
12635                "textDocument/codeLens" => {
12636                    server.update_capabilities(|capabilities| {
12637                        capabilities.code_lens_provider = None;
12638                    });
12639                    notify_server_capabilities_updated(&server, cx);
12640                }
12641                "textDocument/diagnostic" => {
12642                    let local = self
12643                        .as_local_mut()
12644                        .context("Expected LSP Store to be local")?;
12645
12646                    let state = local
12647                        .language_servers
12648                        .get_mut(&server_id)
12649                        .context("Could not obtain Language Servers state")?;
12650                    local
12651                        .language_server_dynamic_registrations
12652                        .get_mut(&server_id)
12653                        .with_context(|| {
12654                            format!("Expected dynamic registration to exist for server {server_id}")
12655                        })?.diagnostics
12656                        .remove(&Some(unreg.id.clone()))
12657                        .with_context(|| format!(
12658                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12659                            unreg.id)
12660                        )?;
12661
12662                    let mut has_any_diagnostic_providers_still = true;
12663                    if let LanguageServerState::Running {
12664                        workspace_diagnostics_refresh_tasks,
12665                        ..
12666                    } = state
12667                    {
12668                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12669                        has_any_diagnostic_providers_still =
12670                            !workspace_diagnostics_refresh_tasks.is_empty();
12671                    }
12672
12673                    if !has_any_diagnostic_providers_still {
12674                        server.update_capabilities(|capabilities| {
12675                            debug_assert!(capabilities.diagnostic_provider.is_some());
12676                            capabilities.diagnostic_provider = None;
12677                        });
12678                    }
12679
12680                    notify_server_capabilities_updated(&server, cx);
12681                }
12682                "textDocument/documentColor" => {
12683                    server.update_capabilities(|capabilities| {
12684                        capabilities.color_provider = None;
12685                    });
12686                    notify_server_capabilities_updated(&server, cx);
12687                }
12688                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12689            }
12690        }
12691
12692        Ok(())
12693    }
12694
12695    async fn deduplicate_range_based_lsp_requests<T>(
12696        lsp_store: &Entity<Self>,
12697        server_id: Option<LanguageServerId>,
12698        lsp_request_id: LspRequestId,
12699        proto_request: &T::ProtoRequest,
12700        range: Range<Anchor>,
12701        cx: &mut AsyncApp,
12702    ) -> Result<()>
12703    where
12704        T: LspCommand,
12705        T::ProtoRequest: proto::LspRequestMessage,
12706    {
12707        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12708        let version = deserialize_version(proto_request.buffer_version());
12709        let buffer = lsp_store.update(cx, |this, cx| {
12710            this.buffer_store.read(cx).get_existing(buffer_id)
12711        })??;
12712        buffer
12713            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12714            .await?;
12715        lsp_store.update(cx, |lsp_store, cx| {
12716            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12717            let chunks_queried_for = lsp_data
12718                .inlay_hints
12719                .applicable_chunks(&[range])
12720                .collect::<Vec<_>>();
12721            match chunks_queried_for.as_slice() {
12722                &[chunk] => {
12723                    let key = LspKey {
12724                        request_type: TypeId::of::<T>(),
12725                        server_queried: server_id,
12726                    };
12727                    let previous_request = lsp_data
12728                        .chunk_lsp_requests
12729                        .entry(key)
12730                        .or_default()
12731                        .insert(chunk, lsp_request_id);
12732                    if let Some((previous_request, running_requests)) =
12733                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12734                    {
12735                        running_requests.remove(&previous_request);
12736                    }
12737                }
12738                _ambiguous_chunks => {
12739                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12740                    // there, a buffer version-based check will be performed and outdated requests discarded.
12741                }
12742            }
12743            anyhow::Ok(())
12744        })??;
12745
12746        Ok(())
12747    }
12748
12749    async fn query_lsp_locally<T>(
12750        lsp_store: Entity<Self>,
12751        for_server_id: Option<LanguageServerId>,
12752        sender_id: proto::PeerId,
12753        lsp_request_id: LspRequestId,
12754        proto_request: T::ProtoRequest,
12755        position: Option<Anchor>,
12756        cx: &mut AsyncApp,
12757    ) -> Result<()>
12758    where
12759        T: LspCommand + Clone,
12760        T::ProtoRequest: proto::LspRequestMessage,
12761        <T::ProtoRequest as proto::RequestMessage>::Response:
12762            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12763    {
12764        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12765        let version = deserialize_version(proto_request.buffer_version());
12766        let buffer = lsp_store.update(cx, |this, cx| {
12767            this.buffer_store.read(cx).get_existing(buffer_id)
12768        })??;
12769        buffer
12770            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12771            .await?;
12772        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12773        let request =
12774            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12775        let key = LspKey {
12776            request_type: TypeId::of::<T>(),
12777            server_queried: for_server_id,
12778        };
12779        lsp_store.update(cx, |lsp_store, cx| {
12780            let request_task = match for_server_id {
12781                Some(server_id) => {
12782                    let server_task = lsp_store.request_lsp(
12783                        buffer.clone(),
12784                        LanguageServerToQuery::Other(server_id),
12785                        request.clone(),
12786                        cx,
12787                    );
12788                    cx.background_spawn(async move {
12789                        let mut responses = Vec::new();
12790                        match server_task.await {
12791                            Ok(response) => responses.push((server_id, response)),
12792                            // rust-analyzer likes to error with this when its still loading up
12793                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12794                            Err(e) => log::error!(
12795                                "Error handling response for request {request:?}: {e:#}"
12796                            ),
12797                        }
12798                        responses
12799                    })
12800                }
12801                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12802            };
12803            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12804            if T::ProtoRequest::stop_previous_requests() {
12805                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12806                    lsp_requests.clear();
12807                }
12808            }
12809            lsp_data.lsp_requests.entry(key).or_default().insert(
12810                lsp_request_id,
12811                cx.spawn(async move |lsp_store, cx| {
12812                    let response = request_task.await;
12813                    lsp_store
12814                        .update(cx, |lsp_store, cx| {
12815                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12816                            {
12817                                let response = response
12818                                    .into_iter()
12819                                    .map(|(server_id, response)| {
12820                                        (
12821                                            server_id.to_proto(),
12822                                            T::response_to_proto(
12823                                                response,
12824                                                lsp_store,
12825                                                sender_id,
12826                                                &buffer_version,
12827                                                cx,
12828                                            )
12829                                            .into(),
12830                                        )
12831                                    })
12832                                    .collect::<HashMap<_, _>>();
12833                                match client.send_lsp_response::<T::ProtoRequest>(
12834                                    project_id,
12835                                    lsp_request_id,
12836                                    response,
12837                                ) {
12838                                    Ok(()) => {}
12839                                    Err(e) => {
12840                                        log::error!("Failed to send LSP response: {e:#}",)
12841                                    }
12842                                }
12843                            }
12844                        })
12845                        .ok();
12846                }),
12847            );
12848        })?;
12849        Ok(())
12850    }
12851
12852    fn take_text_document_sync_options(
12853        capabilities: &mut lsp::ServerCapabilities,
12854    ) -> lsp::TextDocumentSyncOptions {
12855        match capabilities.text_document_sync.take() {
12856            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12857            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12858                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12859                sync_options.change = Some(sync_kind);
12860                sync_options
12861            }
12862            None => lsp::TextDocumentSyncOptions::default(),
12863        }
12864    }
12865
12866    #[cfg(any(test, feature = "test-support"))]
12867    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12868        Some(
12869            self.lsp_data
12870                .get_mut(&buffer_id)?
12871                .code_lens
12872                .take()?
12873                .update
12874                .take()?
12875                .1,
12876        )
12877    }
12878
12879    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12880        self.downstream_client.clone()
12881    }
12882
12883    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12884        self.worktree_store.clone()
12885    }
12886
12887    /// Gets what's stored in the LSP data for the given buffer.
12888    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12889        self.lsp_data.get_mut(&buffer_id)
12890    }
12891
12892    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12893    /// new [`BufferLspData`] will be created to replace the previous state.
12894    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12895        let (buffer_id, buffer_version) =
12896            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12897        let lsp_data = self
12898            .lsp_data
12899            .entry(buffer_id)
12900            .or_insert_with(|| BufferLspData::new(buffer, cx));
12901        if buffer_version.changed_since(&lsp_data.buffer_version) {
12902            *lsp_data = BufferLspData::new(buffer, cx);
12903        }
12904        lsp_data
12905    }
12906}
12907
12908// Registration with registerOptions as null, should fallback to true.
12909// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12910fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12911    reg: lsp::Registration,
12912) -> Result<OneOf<bool, T>> {
12913    Ok(match reg.register_options {
12914        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12915        None => OneOf::Left(true),
12916    })
12917}
12918
12919fn subscribe_to_binary_statuses(
12920    languages: &Arc<LanguageRegistry>,
12921    cx: &mut Context<'_, LspStore>,
12922) -> Task<()> {
12923    let mut server_statuses = languages.language_server_binary_statuses();
12924    cx.spawn(async move |lsp_store, cx| {
12925        while let Some((server_name, binary_status)) = server_statuses.next().await {
12926            if lsp_store
12927                .update(cx, |_, cx| {
12928                    let mut message = None;
12929                    let binary_status = match binary_status {
12930                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12931                        BinaryStatus::CheckingForUpdate => {
12932                            proto::ServerBinaryStatus::CheckingForUpdate
12933                        }
12934                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12935                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12936                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12937                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12938                        BinaryStatus::Failed { error } => {
12939                            message = Some(error);
12940                            proto::ServerBinaryStatus::Failed
12941                        }
12942                    };
12943                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12944                        // Binary updates are about the binary that might not have any language server id at that point.
12945                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12946                        language_server_id: LanguageServerId(0),
12947                        name: Some(server_name),
12948                        message: proto::update_language_server::Variant::StatusUpdate(
12949                            proto::StatusUpdate {
12950                                message,
12951                                status: Some(proto::status_update::Status::Binary(
12952                                    binary_status as i32,
12953                                )),
12954                            },
12955                        ),
12956                    });
12957                })
12958                .is_err()
12959            {
12960                break;
12961            }
12962        }
12963    })
12964}
12965
12966fn lsp_workspace_diagnostics_refresh(
12967    registration_id: Option<String>,
12968    options: DiagnosticServerCapabilities,
12969    server: Arc<LanguageServer>,
12970    cx: &mut Context<'_, LspStore>,
12971) -> Option<WorkspaceRefreshTask> {
12972    let identifier = workspace_diagnostic_identifier(&options)?;
12973    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
12974
12975    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12976    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12977    refresh_tx.try_send(()).ok();
12978
12979    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12980        let mut attempts = 0;
12981        let max_attempts = 50;
12982        let mut requests = 0;
12983
12984        loop {
12985            let Some(()) = refresh_rx.recv().await else {
12986                return;
12987            };
12988
12989            'request: loop {
12990                requests += 1;
12991                if attempts > max_attempts {
12992                    log::error!(
12993                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12994                    );
12995                    return;
12996                }
12997                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12998                cx.background_executor()
12999                    .timer(Duration::from_millis(backoff_millis))
13000                    .await;
13001                attempts += 1;
13002
13003                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13004                    lsp_store
13005                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13006                        .into_iter()
13007                        .filter_map(|(abs_path, result_id)| {
13008                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13009                            Some(lsp::PreviousResultId {
13010                                uri,
13011                                value: result_id.to_string(),
13012                            })
13013                        })
13014                        .collect()
13015                }) else {
13016                    return;
13017                };
13018
13019                let token = if let Some(registration_id) = &registration_id {
13020                    format!(
13021                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13022                        server.server_id(),
13023                    )
13024                } else {
13025                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13026                };
13027
13028                progress_rx.try_recv().ok();
13029                let timer =
13030                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13031                let progress = pin!(progress_rx.recv().fuse());
13032                let response_result = server
13033                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13034                        lsp::WorkspaceDiagnosticParams {
13035                            previous_result_ids,
13036                            identifier: identifier.clone(),
13037                            work_done_progress_params: Default::default(),
13038                            partial_result_params: lsp::PartialResultParams {
13039                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13040                            },
13041                        },
13042                        select(timer, progress).then(|either| match either {
13043                            Either::Left((message, ..)) => ready(message).left_future(),
13044                            Either::Right(..) => pending::<String>().right_future(),
13045                        }),
13046                    )
13047                    .await;
13048
13049                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13050                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13051                match response_result {
13052                    ConnectionResult::Timeout => {
13053                        log::error!("Timeout during workspace diagnostics pull");
13054                        continue 'request;
13055                    }
13056                    ConnectionResult::ConnectionReset => {
13057                        log::error!("Server closed a workspace diagnostics pull request");
13058                        continue 'request;
13059                    }
13060                    ConnectionResult::Result(Err(e)) => {
13061                        log::error!("Error during workspace diagnostics pull: {e:#}");
13062                        break 'request;
13063                    }
13064                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13065                        attempts = 0;
13066                        if lsp_store
13067                            .update(cx, |lsp_store, cx| {
13068                                lsp_store.apply_workspace_diagnostic_report(
13069                                    server.server_id(),
13070                                    pulled_diagnostics,
13071                                    registration_id_shared.clone(),
13072                                    cx,
13073                                )
13074                            })
13075                            .is_err()
13076                        {
13077                            return;
13078                        }
13079                        break 'request;
13080                    }
13081                }
13082            }
13083        }
13084    });
13085
13086    Some(WorkspaceRefreshTask {
13087        refresh_tx,
13088        progress_tx,
13089        task: workspace_query_language_server,
13090    })
13091}
13092
13093fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13094    match &options {
13095        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13096            diagnostic_options.identifier.clone()
13097        }
13098        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13099            let diagnostic_options = &registration_options.diagnostic_options;
13100            diagnostic_options.identifier.clone()
13101        }
13102    }
13103}
13104
13105fn workspace_diagnostic_identifier(
13106    options: &DiagnosticServerCapabilities,
13107) -> Option<Option<String>> {
13108    match &options {
13109        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13110            if !diagnostic_options.workspace_diagnostics {
13111                return None;
13112            }
13113            Some(diagnostic_options.identifier.clone())
13114        }
13115        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13116            let diagnostic_options = &registration_options.diagnostic_options;
13117            if !diagnostic_options.workspace_diagnostics {
13118                return None;
13119            }
13120            Some(diagnostic_options.identifier.clone())
13121        }
13122    }
13123}
13124
13125fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13126    let CompletionSource::BufferWord {
13127        word_range,
13128        resolved,
13129    } = &mut completion.source
13130    else {
13131        return;
13132    };
13133    if *resolved {
13134        return;
13135    }
13136
13137    if completion.new_text
13138        != snapshot
13139            .text_for_range(word_range.clone())
13140            .collect::<String>()
13141    {
13142        return;
13143    }
13144
13145    let mut offset = 0;
13146    for chunk in snapshot.chunks(word_range.clone(), true) {
13147        let end_offset = offset + chunk.text.len();
13148        if let Some(highlight_id) = chunk.syntax_highlight_id {
13149            completion
13150                .label
13151                .runs
13152                .push((offset..end_offset, highlight_id));
13153        }
13154        offset = end_offset;
13155    }
13156    *resolved = true;
13157}
13158
13159impl EventEmitter<LspStoreEvent> for LspStore {}
13160
13161fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13162    hover
13163        .contents
13164        .retain(|hover_block| !hover_block.text.trim().is_empty());
13165    if hover.contents.is_empty() {
13166        None
13167    } else {
13168        Some(hover)
13169    }
13170}
13171
13172async fn populate_labels_for_completions(
13173    new_completions: Vec<CoreCompletion>,
13174    language: Option<Arc<Language>>,
13175    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13176) -> Vec<Completion> {
13177    let lsp_completions = new_completions
13178        .iter()
13179        .filter_map(|new_completion| {
13180            new_completion
13181                .source
13182                .lsp_completion(true)
13183                .map(|lsp_completion| lsp_completion.into_owned())
13184        })
13185        .collect::<Vec<_>>();
13186
13187    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13188        lsp_adapter
13189            .labels_for_completions(&lsp_completions, language)
13190            .await
13191            .log_err()
13192            .unwrap_or_default()
13193    } else {
13194        Vec::new()
13195    }
13196    .into_iter()
13197    .fuse();
13198
13199    let mut completions = Vec::new();
13200    for completion in new_completions {
13201        match completion.source.lsp_completion(true) {
13202            Some(lsp_completion) => {
13203                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13204
13205                let mut label = labels.next().flatten().unwrap_or_else(|| {
13206                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13207                });
13208                ensure_uniform_list_compatible_label(&mut label);
13209                completions.push(Completion {
13210                    label,
13211                    documentation,
13212                    replace_range: completion.replace_range,
13213                    new_text: completion.new_text,
13214                    insert_text_mode: lsp_completion.insert_text_mode,
13215                    source: completion.source,
13216                    icon_path: None,
13217                    confirm: None,
13218                    match_start: None,
13219                    snippet_deduplication_key: None,
13220                });
13221            }
13222            None => {
13223                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13224                ensure_uniform_list_compatible_label(&mut label);
13225                completions.push(Completion {
13226                    label,
13227                    documentation: None,
13228                    replace_range: completion.replace_range,
13229                    new_text: completion.new_text,
13230                    source: completion.source,
13231                    insert_text_mode: None,
13232                    icon_path: None,
13233                    confirm: None,
13234                    match_start: None,
13235                    snippet_deduplication_key: None,
13236                });
13237            }
13238        }
13239    }
13240    completions
13241}
13242
13243#[derive(Debug)]
13244pub enum LanguageServerToQuery {
13245    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13246    FirstCapable,
13247    /// Query a specific language server.
13248    Other(LanguageServerId),
13249}
13250
13251#[derive(Default)]
13252struct RenamePathsWatchedForServer {
13253    did_rename: Vec<RenameActionPredicate>,
13254    will_rename: Vec<RenameActionPredicate>,
13255}
13256
13257impl RenamePathsWatchedForServer {
13258    fn with_did_rename_patterns(
13259        mut self,
13260        did_rename: Option<&FileOperationRegistrationOptions>,
13261    ) -> Self {
13262        if let Some(did_rename) = did_rename {
13263            self.did_rename = did_rename
13264                .filters
13265                .iter()
13266                .filter_map(|filter| filter.try_into().log_err())
13267                .collect();
13268        }
13269        self
13270    }
13271    fn with_will_rename_patterns(
13272        mut self,
13273        will_rename: Option<&FileOperationRegistrationOptions>,
13274    ) -> Self {
13275        if let Some(will_rename) = will_rename {
13276            self.will_rename = will_rename
13277                .filters
13278                .iter()
13279                .filter_map(|filter| filter.try_into().log_err())
13280                .collect();
13281        }
13282        self
13283    }
13284
13285    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13286        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13287    }
13288    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13289        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13290    }
13291}
13292
13293impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13294    type Error = globset::Error;
13295    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13296        Ok(Self {
13297            kind: ops.pattern.matches.clone(),
13298            glob: GlobBuilder::new(&ops.pattern.glob)
13299                .case_insensitive(
13300                    ops.pattern
13301                        .options
13302                        .as_ref()
13303                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13304                )
13305                .build()?
13306                .compile_matcher(),
13307        })
13308    }
13309}
13310struct RenameActionPredicate {
13311    glob: GlobMatcher,
13312    kind: Option<FileOperationPatternKind>,
13313}
13314
13315impl RenameActionPredicate {
13316    // Returns true if language server should be notified
13317    fn eval(&self, path: &str, is_dir: bool) -> bool {
13318        self.kind.as_ref().is_none_or(|kind| {
13319            let expected_kind = if is_dir {
13320                FileOperationPatternKind::Folder
13321            } else {
13322                FileOperationPatternKind::File
13323            };
13324            kind == &expected_kind
13325        }) && self.glob.is_match(path)
13326    }
13327}
13328
13329#[derive(Default)]
13330struct LanguageServerWatchedPaths {
13331    worktree_paths: HashMap<WorktreeId, GlobSet>,
13332    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13333}
13334
13335#[derive(Default)]
13336struct LanguageServerWatchedPathsBuilder {
13337    worktree_paths: HashMap<WorktreeId, GlobSet>,
13338    abs_paths: HashMap<Arc<Path>, GlobSet>,
13339}
13340
13341impl LanguageServerWatchedPathsBuilder {
13342    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13343        self.worktree_paths.insert(worktree_id, glob_set);
13344    }
13345    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13346        self.abs_paths.insert(path, glob_set);
13347    }
13348    fn build(
13349        self,
13350        fs: Arc<dyn Fs>,
13351        language_server_id: LanguageServerId,
13352        cx: &mut Context<LspStore>,
13353    ) -> LanguageServerWatchedPaths {
13354        let lsp_store = cx.weak_entity();
13355
13356        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13357        let abs_paths = self
13358            .abs_paths
13359            .into_iter()
13360            .map(|(abs_path, globset)| {
13361                let task = cx.spawn({
13362                    let abs_path = abs_path.clone();
13363                    let fs = fs.clone();
13364
13365                    let lsp_store = lsp_store.clone();
13366                    async move |_, cx| {
13367                        maybe!(async move {
13368                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13369                            while let Some(update) = push_updates.0.next().await {
13370                                let action = lsp_store
13371                                    .update(cx, |this, _| {
13372                                        let Some(local) = this.as_local() else {
13373                                            return ControlFlow::Break(());
13374                                        };
13375                                        let Some(watcher) = local
13376                                            .language_server_watched_paths
13377                                            .get(&language_server_id)
13378                                        else {
13379                                            return ControlFlow::Break(());
13380                                        };
13381                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13382                                            "Watched abs path is not registered with a watcher",
13383                                        );
13384                                        let matching_entries = update
13385                                            .into_iter()
13386                                            .filter(|event| globs.is_match(&event.path))
13387                                            .collect::<Vec<_>>();
13388                                        this.lsp_notify_abs_paths_changed(
13389                                            language_server_id,
13390                                            matching_entries,
13391                                        );
13392                                        ControlFlow::Continue(())
13393                                    })
13394                                    .ok()?;
13395
13396                                if action.is_break() {
13397                                    break;
13398                                }
13399                            }
13400                            Some(())
13401                        })
13402                        .await;
13403                    }
13404                });
13405                (abs_path, (globset, task))
13406            })
13407            .collect();
13408        LanguageServerWatchedPaths {
13409            worktree_paths: self.worktree_paths,
13410            abs_paths,
13411        }
13412    }
13413}
13414
13415struct LspBufferSnapshot {
13416    version: i32,
13417    snapshot: TextBufferSnapshot,
13418}
13419
13420/// A prompt requested by LSP server.
13421#[derive(Clone, Debug)]
13422pub struct LanguageServerPromptRequest {
13423    pub level: PromptLevel,
13424    pub message: String,
13425    pub actions: Vec<MessageActionItem>,
13426    pub lsp_name: String,
13427    pub(crate) response_channel: Sender<MessageActionItem>,
13428}
13429
13430impl LanguageServerPromptRequest {
13431    pub async fn respond(self, index: usize) -> Option<()> {
13432        if let Some(response) = self.actions.into_iter().nth(index) {
13433            self.response_channel.send(response).await.ok()
13434        } else {
13435            None
13436        }
13437    }
13438}
13439impl PartialEq for LanguageServerPromptRequest {
13440    fn eq(&self, other: &Self) -> bool {
13441        self.message == other.message && self.actions == other.actions
13442    }
13443}
13444
13445#[derive(Clone, Debug, PartialEq)]
13446pub enum LanguageServerLogType {
13447    Log(MessageType),
13448    Trace { verbose_info: Option<String> },
13449    Rpc { received: bool },
13450}
13451
13452impl LanguageServerLogType {
13453    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13454        match self {
13455            Self::Log(log_type) => {
13456                use proto::log_message::LogLevel;
13457                let level = match *log_type {
13458                    MessageType::ERROR => LogLevel::Error,
13459                    MessageType::WARNING => LogLevel::Warning,
13460                    MessageType::INFO => LogLevel::Info,
13461                    MessageType::LOG => LogLevel::Log,
13462                    other => {
13463                        log::warn!("Unknown lsp log message type: {other:?}");
13464                        LogLevel::Log
13465                    }
13466                };
13467                proto::language_server_log::LogType::Log(proto::LogMessage {
13468                    level: level as i32,
13469                })
13470            }
13471            Self::Trace { verbose_info } => {
13472                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13473                    verbose_info: verbose_info.to_owned(),
13474                })
13475            }
13476            Self::Rpc { received } => {
13477                let kind = if *received {
13478                    proto::rpc_message::Kind::Received
13479                } else {
13480                    proto::rpc_message::Kind::Sent
13481                };
13482                let kind = kind as i32;
13483                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13484            }
13485        }
13486    }
13487
13488    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13489        use proto::log_message::LogLevel;
13490        use proto::rpc_message;
13491        match log_type {
13492            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13493                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13494                    LogLevel::Error => MessageType::ERROR,
13495                    LogLevel::Warning => MessageType::WARNING,
13496                    LogLevel::Info => MessageType::INFO,
13497                    LogLevel::Log => MessageType::LOG,
13498                },
13499            ),
13500            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13501                verbose_info: trace_message.verbose_info,
13502            },
13503            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13504                received: match rpc_message::Kind::from_i32(message.kind)
13505                    .unwrap_or(rpc_message::Kind::Received)
13506                {
13507                    rpc_message::Kind::Received => true,
13508                    rpc_message::Kind::Sent => false,
13509                },
13510            },
13511        }
13512    }
13513}
13514
13515pub struct WorkspaceRefreshTask {
13516    refresh_tx: mpsc::Sender<()>,
13517    progress_tx: mpsc::Sender<()>,
13518    #[allow(dead_code)]
13519    task: Task<()>,
13520}
13521
13522pub enum LanguageServerState {
13523    Starting {
13524        startup: Task<Option<Arc<LanguageServer>>>,
13525        /// List of language servers that will be added to the workspace once it's initialization completes.
13526        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13527    },
13528
13529    Running {
13530        adapter: Arc<CachedLspAdapter>,
13531        server: Arc<LanguageServer>,
13532        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13533        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13534    },
13535}
13536
13537impl LanguageServerState {
13538    fn add_workspace_folder(&self, uri: Uri) {
13539        match self {
13540            LanguageServerState::Starting {
13541                pending_workspace_folders,
13542                ..
13543            } => {
13544                pending_workspace_folders.lock().insert(uri);
13545            }
13546            LanguageServerState::Running { server, .. } => {
13547                server.add_workspace_folder(uri);
13548            }
13549        }
13550    }
13551    fn _remove_workspace_folder(&self, uri: Uri) {
13552        match self {
13553            LanguageServerState::Starting {
13554                pending_workspace_folders,
13555                ..
13556            } => {
13557                pending_workspace_folders.lock().remove(&uri);
13558            }
13559            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13560        }
13561    }
13562}
13563
13564impl std::fmt::Debug for LanguageServerState {
13565    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13566        match self {
13567            LanguageServerState::Starting { .. } => {
13568                f.debug_struct("LanguageServerState::Starting").finish()
13569            }
13570            LanguageServerState::Running { .. } => {
13571                f.debug_struct("LanguageServerState::Running").finish()
13572            }
13573        }
13574    }
13575}
13576
13577#[derive(Clone, Debug, Serialize)]
13578pub struct LanguageServerProgress {
13579    pub is_disk_based_diagnostics_progress: bool,
13580    pub is_cancellable: bool,
13581    pub title: Option<String>,
13582    pub message: Option<String>,
13583    pub percentage: Option<usize>,
13584    #[serde(skip_serializing)]
13585    pub last_update_at: Instant,
13586}
13587
13588#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13589pub struct DiagnosticSummary {
13590    pub error_count: usize,
13591    pub warning_count: usize,
13592}
13593
13594impl DiagnosticSummary {
13595    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13596        let mut this = Self {
13597            error_count: 0,
13598            warning_count: 0,
13599        };
13600
13601        for entry in diagnostics {
13602            if entry.diagnostic.is_primary {
13603                match entry.diagnostic.severity {
13604                    DiagnosticSeverity::ERROR => this.error_count += 1,
13605                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13606                    _ => {}
13607                }
13608            }
13609        }
13610
13611        this
13612    }
13613
13614    pub fn is_empty(&self) -> bool {
13615        self.error_count == 0 && self.warning_count == 0
13616    }
13617
13618    pub fn to_proto(
13619        self,
13620        language_server_id: LanguageServerId,
13621        path: &RelPath,
13622    ) -> proto::DiagnosticSummary {
13623        proto::DiagnosticSummary {
13624            path: path.to_proto(),
13625            language_server_id: language_server_id.0 as u64,
13626            error_count: self.error_count as u32,
13627            warning_count: self.warning_count as u32,
13628        }
13629    }
13630}
13631
13632#[derive(Clone, Debug)]
13633pub enum CompletionDocumentation {
13634    /// There is no documentation for this completion.
13635    Undocumented,
13636    /// A single line of documentation.
13637    SingleLine(SharedString),
13638    /// Multiple lines of plain text documentation.
13639    MultiLinePlainText(SharedString),
13640    /// Markdown documentation.
13641    MultiLineMarkdown(SharedString),
13642    /// Both single line and multiple lines of plain text documentation.
13643    SingleLineAndMultiLinePlainText {
13644        single_line: SharedString,
13645        plain_text: Option<SharedString>,
13646    },
13647}
13648
13649impl CompletionDocumentation {
13650    #[cfg(any(test, feature = "test-support"))]
13651    pub fn text(&self) -> SharedString {
13652        match self {
13653            CompletionDocumentation::Undocumented => "".into(),
13654            CompletionDocumentation::SingleLine(s) => s.clone(),
13655            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13656            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13657            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13658                single_line.clone()
13659            }
13660        }
13661    }
13662}
13663
13664impl From<lsp::Documentation> for CompletionDocumentation {
13665    fn from(docs: lsp::Documentation) -> Self {
13666        match docs {
13667            lsp::Documentation::String(text) => {
13668                if text.lines().count() <= 1 {
13669                    CompletionDocumentation::SingleLine(text.into())
13670                } else {
13671                    CompletionDocumentation::MultiLinePlainText(text.into())
13672                }
13673            }
13674
13675            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13676                lsp::MarkupKind::PlainText => {
13677                    if value.lines().count() <= 1 {
13678                        CompletionDocumentation::SingleLine(value.into())
13679                    } else {
13680                        CompletionDocumentation::MultiLinePlainText(value.into())
13681                    }
13682                }
13683
13684                lsp::MarkupKind::Markdown => {
13685                    CompletionDocumentation::MultiLineMarkdown(value.into())
13686                }
13687            },
13688        }
13689    }
13690}
13691
13692pub enum ResolvedHint {
13693    Resolved(InlayHint),
13694    Resolving(Shared<Task<()>>),
13695}
13696
13697fn glob_literal_prefix(glob: &Path) -> PathBuf {
13698    glob.components()
13699        .take_while(|component| match component {
13700            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13701            _ => true,
13702        })
13703        .collect()
13704}
13705
13706pub struct SshLspAdapter {
13707    name: LanguageServerName,
13708    binary: LanguageServerBinary,
13709    initialization_options: Option<String>,
13710    code_action_kinds: Option<Vec<CodeActionKind>>,
13711}
13712
13713impl SshLspAdapter {
13714    pub fn new(
13715        name: LanguageServerName,
13716        binary: LanguageServerBinary,
13717        initialization_options: Option<String>,
13718        code_action_kinds: Option<String>,
13719    ) -> Self {
13720        Self {
13721            name,
13722            binary,
13723            initialization_options,
13724            code_action_kinds: code_action_kinds
13725                .as_ref()
13726                .and_then(|c| serde_json::from_str(c).ok()),
13727        }
13728    }
13729}
13730
13731impl LspInstaller for SshLspAdapter {
13732    type BinaryVersion = ();
13733    async fn check_if_user_installed(
13734        &self,
13735        _: &dyn LspAdapterDelegate,
13736        _: Option<Toolchain>,
13737        _: &AsyncApp,
13738    ) -> Option<LanguageServerBinary> {
13739        Some(self.binary.clone())
13740    }
13741
13742    async fn cached_server_binary(
13743        &self,
13744        _: PathBuf,
13745        _: &dyn LspAdapterDelegate,
13746    ) -> Option<LanguageServerBinary> {
13747        None
13748    }
13749
13750    async fn fetch_latest_server_version(
13751        &self,
13752        _: &dyn LspAdapterDelegate,
13753        _: bool,
13754        _: &mut AsyncApp,
13755    ) -> Result<()> {
13756        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13757    }
13758
13759    async fn fetch_server_binary(
13760        &self,
13761        _: (),
13762        _: PathBuf,
13763        _: &dyn LspAdapterDelegate,
13764    ) -> Result<LanguageServerBinary> {
13765        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13766    }
13767}
13768
13769#[async_trait(?Send)]
13770impl LspAdapter for SshLspAdapter {
13771    fn name(&self) -> LanguageServerName {
13772        self.name.clone()
13773    }
13774
13775    async fn initialization_options(
13776        self: Arc<Self>,
13777        _: &Arc<dyn LspAdapterDelegate>,
13778    ) -> Result<Option<serde_json::Value>> {
13779        let Some(options) = &self.initialization_options else {
13780            return Ok(None);
13781        };
13782        let result = serde_json::from_str(options)?;
13783        Ok(result)
13784    }
13785
13786    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13787        self.code_action_kinds.clone()
13788    }
13789}
13790
13791pub fn language_server_settings<'a>(
13792    delegate: &'a dyn LspAdapterDelegate,
13793    language: &LanguageServerName,
13794    cx: &'a App,
13795) -> Option<&'a LspSettings> {
13796    language_server_settings_for(
13797        SettingsLocation {
13798            worktree_id: delegate.worktree_id(),
13799            path: RelPath::empty(),
13800        },
13801        language,
13802        cx,
13803    )
13804}
13805
13806pub fn language_server_settings_for<'a>(
13807    location: SettingsLocation<'a>,
13808    language: &LanguageServerName,
13809    cx: &'a App,
13810) -> Option<&'a LspSettings> {
13811    ProjectSettings::get(Some(location), cx).lsp.get(language)
13812}
13813
13814pub struct LocalLspAdapterDelegate {
13815    lsp_store: WeakEntity<LspStore>,
13816    worktree: worktree::Snapshot,
13817    fs: Arc<dyn Fs>,
13818    http_client: Arc<dyn HttpClient>,
13819    language_registry: Arc<LanguageRegistry>,
13820    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13821}
13822
13823impl LocalLspAdapterDelegate {
13824    pub fn new(
13825        language_registry: Arc<LanguageRegistry>,
13826        environment: &Entity<ProjectEnvironment>,
13827        lsp_store: WeakEntity<LspStore>,
13828        worktree: &Entity<Worktree>,
13829        http_client: Arc<dyn HttpClient>,
13830        fs: Arc<dyn Fs>,
13831        cx: &mut App,
13832    ) -> Arc<Self> {
13833        let load_shell_env_task =
13834            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13835
13836        Arc::new(Self {
13837            lsp_store,
13838            worktree: worktree.read(cx).snapshot(),
13839            fs,
13840            http_client,
13841            language_registry,
13842            load_shell_env_task,
13843        })
13844    }
13845
13846    fn from_local_lsp(
13847        local: &LocalLspStore,
13848        worktree: &Entity<Worktree>,
13849        cx: &mut App,
13850    ) -> Arc<Self> {
13851        Self::new(
13852            local.languages.clone(),
13853            &local.environment,
13854            local.weak.clone(),
13855            worktree,
13856            local.http_client.clone(),
13857            local.fs.clone(),
13858            cx,
13859        )
13860    }
13861}
13862
13863#[async_trait]
13864impl LspAdapterDelegate for LocalLspAdapterDelegate {
13865    fn show_notification(&self, message: &str, cx: &mut App) {
13866        self.lsp_store
13867            .update(cx, |_, cx| {
13868                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13869            })
13870            .ok();
13871    }
13872
13873    fn http_client(&self) -> Arc<dyn HttpClient> {
13874        self.http_client.clone()
13875    }
13876
13877    fn worktree_id(&self) -> WorktreeId {
13878        self.worktree.id()
13879    }
13880
13881    fn worktree_root_path(&self) -> &Path {
13882        self.worktree.abs_path().as_ref()
13883    }
13884
13885    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13886        self.worktree.resolve_executable_path(path)
13887    }
13888
13889    async fn shell_env(&self) -> HashMap<String, String> {
13890        let task = self.load_shell_env_task.clone();
13891        task.await.unwrap_or_default()
13892    }
13893
13894    async fn npm_package_installed_version(
13895        &self,
13896        package_name: &str,
13897    ) -> Result<Option<(PathBuf, String)>> {
13898        let local_package_directory = self.worktree_root_path();
13899        let node_modules_directory = local_package_directory.join("node_modules");
13900
13901        if let Some(version) =
13902            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13903        {
13904            return Ok(Some((node_modules_directory, version)));
13905        }
13906        let Some(npm) = self.which("npm".as_ref()).await else {
13907            log::warn!(
13908                "Failed to find npm executable for {:?}",
13909                local_package_directory
13910            );
13911            return Ok(None);
13912        };
13913
13914        let env = self.shell_env().await;
13915        let output = util::command::new_smol_command(&npm)
13916            .args(["root", "-g"])
13917            .envs(env)
13918            .current_dir(local_package_directory)
13919            .output()
13920            .await?;
13921        let global_node_modules =
13922            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13923
13924        if let Some(version) =
13925            read_package_installed_version(global_node_modules.clone(), package_name).await?
13926        {
13927            return Ok(Some((global_node_modules, version)));
13928        }
13929        return Ok(None);
13930    }
13931
13932    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13933        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13934        if self.fs.is_file(&worktree_abs_path).await {
13935            worktree_abs_path.pop();
13936        }
13937
13938        let env = self.shell_env().await;
13939
13940        let shell_path = env.get("PATH").cloned();
13941
13942        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13943    }
13944
13945    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13946        let mut working_dir = self.worktree_root_path().to_path_buf();
13947        if self.fs.is_file(&working_dir).await {
13948            working_dir.pop();
13949        }
13950        let output = util::command::new_smol_command(&command.path)
13951            .args(command.arguments)
13952            .envs(command.env.clone().unwrap_or_default())
13953            .current_dir(working_dir)
13954            .output()
13955            .await?;
13956
13957        anyhow::ensure!(
13958            output.status.success(),
13959            "{}, stdout: {:?}, stderr: {:?}",
13960            output.status,
13961            String::from_utf8_lossy(&output.stdout),
13962            String::from_utf8_lossy(&output.stderr)
13963        );
13964        Ok(())
13965    }
13966
13967    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13968        self.language_registry
13969            .update_lsp_binary_status(server_name, status);
13970    }
13971
13972    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13973        self.language_registry
13974            .all_lsp_adapters()
13975            .into_iter()
13976            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13977            .collect()
13978    }
13979
13980    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13981        let dir = self.language_registry.language_server_download_dir(name)?;
13982
13983        if !dir.exists() {
13984            smol::fs::create_dir_all(&dir)
13985                .await
13986                .context("failed to create container directory")
13987                .log_err()?;
13988        }
13989
13990        Some(dir)
13991    }
13992
13993    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13994        let entry = self
13995            .worktree
13996            .entry_for_path(path)
13997            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13998        let abs_path = self.worktree.absolutize(&entry.path);
13999        self.fs.load(&abs_path).await
14000    }
14001}
14002
14003async fn populate_labels_for_symbols(
14004    symbols: Vec<CoreSymbol>,
14005    language_registry: &Arc<LanguageRegistry>,
14006    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14007    output: &mut Vec<Symbol>,
14008) {
14009    #[allow(clippy::mutable_key_type)]
14010    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14011
14012    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14013    for symbol in symbols {
14014        let Some(file_name) = symbol.path.file_name() else {
14015            continue;
14016        };
14017        let language = language_registry
14018            .load_language_for_file_path(Path::new(file_name))
14019            .await
14020            .ok()
14021            .or_else(|| {
14022                unknown_paths.insert(file_name.into());
14023                None
14024            });
14025        symbols_by_language
14026            .entry(language)
14027            .or_default()
14028            .push(symbol);
14029    }
14030
14031    for unknown_path in unknown_paths {
14032        log::info!("no language found for symbol in file {unknown_path:?}");
14033    }
14034
14035    let mut label_params = Vec::new();
14036    for (language, mut symbols) in symbols_by_language {
14037        label_params.clear();
14038        label_params.extend(
14039            symbols
14040                .iter_mut()
14041                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14042        );
14043
14044        let mut labels = Vec::new();
14045        if let Some(language) = language {
14046            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14047                language_registry
14048                    .lsp_adapters(&language.name())
14049                    .first()
14050                    .cloned()
14051            });
14052            if let Some(lsp_adapter) = lsp_adapter {
14053                labels = lsp_adapter
14054                    .labels_for_symbols(&label_params, &language)
14055                    .await
14056                    .log_err()
14057                    .unwrap_or_default();
14058            }
14059        }
14060
14061        for ((symbol, (name, _)), label) in symbols
14062            .into_iter()
14063            .zip(label_params.drain(..))
14064            .zip(labels.into_iter().chain(iter::repeat(None)))
14065        {
14066            output.push(Symbol {
14067                language_server_name: symbol.language_server_name,
14068                source_worktree_id: symbol.source_worktree_id,
14069                source_language_server_id: symbol.source_language_server_id,
14070                path: symbol.path,
14071                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14072                name,
14073                kind: symbol.kind,
14074                range: symbol.range,
14075            });
14076        }
14077    }
14078}
14079
14080fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14081    match server.capabilities().text_document_sync.as_ref()? {
14082        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14083            // Server wants didSave but didn't specify includeText.
14084            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14085            // Server doesn't want didSave at all.
14086            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14087            // Server provided SaveOptions.
14088            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14089                Some(save_options.include_text.unwrap_or(false))
14090            }
14091        },
14092        // We do not have any save info. Kind affects didChange only.
14093        lsp::TextDocumentSyncCapability::Kind(_) => None,
14094    }
14095}
14096
14097/// Completion items are displayed in a `UniformList`.
14098/// Usually, those items are single-line strings, but in LSP responses,
14099/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14100/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14101/// 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,
14102/// breaking the completions menu presentation.
14103///
14104/// 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.
14105fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14106    let mut new_text = String::with_capacity(label.text.len());
14107    let mut offset_map = vec![0; label.text.len() + 1];
14108    let mut last_char_was_space = false;
14109    let mut new_idx = 0;
14110    let chars = label.text.char_indices().fuse();
14111    let mut newlines_removed = false;
14112
14113    for (idx, c) in chars {
14114        offset_map[idx] = new_idx;
14115
14116        match c {
14117            '\n' if last_char_was_space => {
14118                newlines_removed = true;
14119            }
14120            '\t' | ' ' if last_char_was_space => {}
14121            '\n' if !last_char_was_space => {
14122                new_text.push(' ');
14123                new_idx += 1;
14124                last_char_was_space = true;
14125                newlines_removed = true;
14126            }
14127            ' ' | '\t' => {
14128                new_text.push(' ');
14129                new_idx += 1;
14130                last_char_was_space = true;
14131            }
14132            _ => {
14133                new_text.push(c);
14134                new_idx += c.len_utf8();
14135                last_char_was_space = false;
14136            }
14137        }
14138    }
14139    offset_map[label.text.len()] = new_idx;
14140
14141    // Only modify the label if newlines were removed.
14142    if !newlines_removed {
14143        return;
14144    }
14145
14146    let last_index = new_idx;
14147    let mut run_ranges_errors = Vec::new();
14148    label.runs.retain_mut(|(range, _)| {
14149        match offset_map.get(range.start) {
14150            Some(&start) => range.start = start,
14151            None => {
14152                run_ranges_errors.push(range.clone());
14153                return false;
14154            }
14155        }
14156
14157        match offset_map.get(range.end) {
14158            Some(&end) => range.end = end,
14159            None => {
14160                run_ranges_errors.push(range.clone());
14161                range.end = last_index;
14162            }
14163        }
14164        true
14165    });
14166    if !run_ranges_errors.is_empty() {
14167        log::error!(
14168            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14169            label.text
14170        );
14171    }
14172
14173    let mut wrong_filter_range = None;
14174    if label.filter_range == (0..label.text.len()) {
14175        label.filter_range = 0..new_text.len();
14176    } else {
14177        let mut original_filter_range = Some(label.filter_range.clone());
14178        match offset_map.get(label.filter_range.start) {
14179            Some(&start) => label.filter_range.start = start,
14180            None => {
14181                wrong_filter_range = original_filter_range.take();
14182                label.filter_range.start = last_index;
14183            }
14184        }
14185
14186        match offset_map.get(label.filter_range.end) {
14187            Some(&end) => label.filter_range.end = end,
14188            None => {
14189                wrong_filter_range = original_filter_range.take();
14190                label.filter_range.end = last_index;
14191            }
14192        }
14193    }
14194    if let Some(wrong_filter_range) = wrong_filter_range {
14195        log::error!(
14196            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14197            label.text
14198        );
14199    }
14200
14201    label.text = new_text;
14202}
14203
14204#[cfg(test)]
14205mod tests {
14206    use language::HighlightId;
14207
14208    use super::*;
14209
14210    #[test]
14211    fn test_glob_literal_prefix() {
14212        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14213        assert_eq!(
14214            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14215            Path::new("node_modules")
14216        );
14217        assert_eq!(
14218            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14219            Path::new("foo")
14220        );
14221        assert_eq!(
14222            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14223            Path::new("foo/bar/baz.js")
14224        );
14225
14226        #[cfg(target_os = "windows")]
14227        {
14228            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14229            assert_eq!(
14230                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14231                Path::new("node_modules")
14232            );
14233            assert_eq!(
14234                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14235                Path::new("foo")
14236            );
14237            assert_eq!(
14238                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14239                Path::new("foo/bar/baz.js")
14240            );
14241        }
14242    }
14243
14244    #[test]
14245    fn test_multi_len_chars_normalization() {
14246        let mut label = CodeLabel::new(
14247            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14248            0..6,
14249            vec![(0..6, HighlightId(1))],
14250        );
14251        ensure_uniform_list_compatible_label(&mut label);
14252        assert_eq!(
14253            label,
14254            CodeLabel::new(
14255                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14256                0..6,
14257                vec![(0..6, HighlightId(1))],
14258            )
14259        );
14260    }
14261}