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};
  120use sum_tree::Dimensions;
  121use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  122
  123use util::{
  124    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  125    paths::{PathStyle, SanitizedPath},
  126    post_inc,
  127    rel_path::RelPath,
  128};
  129
  130pub use fs::*;
  131pub use language::Location;
  132pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  133#[cfg(any(test, feature = "test-support"))]
  134pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  135pub use worktree::{
  136    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  137    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  138};
  139
  140const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  141pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  142const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  143const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  144
  145#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  146pub enum ProgressToken {
  147    Number(i32),
  148    String(SharedString),
  149}
  150
  151impl std::fmt::Display for ProgressToken {
  152    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  153        match self {
  154            Self::Number(number) => write!(f, "{number}"),
  155            Self::String(string) => write!(f, "{string}"),
  156        }
  157    }
  158}
  159
  160impl ProgressToken {
  161    fn from_lsp(value: lsp::NumberOrString) -> Self {
  162        match value {
  163            lsp::NumberOrString::Number(number) => Self::Number(number),
  164            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  165        }
  166    }
  167
  168    fn to_lsp(&self) -> lsp::NumberOrString {
  169        match self {
  170            Self::Number(number) => lsp::NumberOrString::Number(*number),
  171            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  172        }
  173    }
  174
  175    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  176        Some(match value.value? {
  177            proto::progress_token::Value::Number(number) => Self::Number(number),
  178            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  179        })
  180    }
  181
  182    fn to_proto(&self) -> proto::ProgressToken {
  183        proto::ProgressToken {
  184            value: Some(match self {
  185                Self::Number(number) => proto::progress_token::Value::Number(*number),
  186                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  187            }),
  188        }
  189    }
  190}
  191
  192#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  193pub enum FormatTrigger {
  194    Save,
  195    Manual,
  196}
  197
  198pub enum LspFormatTarget {
  199    Buffers,
  200    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  201}
  202
  203pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  204
  205impl FormatTrigger {
  206    fn from_proto(value: i32) -> FormatTrigger {
  207        match value {
  208            0 => FormatTrigger::Save,
  209            1 => FormatTrigger::Manual,
  210            _ => FormatTrigger::Save,
  211        }
  212    }
  213}
  214
  215#[derive(Clone)]
  216struct UnifiedLanguageServer {
  217    id: LanguageServerId,
  218    project_roots: HashSet<Arc<RelPath>>,
  219}
  220
  221#[derive(Clone, Hash, PartialEq, Eq)]
  222struct LanguageServerSeed {
  223    worktree_id: WorktreeId,
  224    name: LanguageServerName,
  225    toolchain: Option<Toolchain>,
  226    settings: Arc<LspSettings>,
  227}
  228
  229#[derive(Debug)]
  230pub struct DocumentDiagnosticsUpdate<'a, D> {
  231    pub diagnostics: D,
  232    pub result_id: Option<String>,
  233    pub server_id: LanguageServerId,
  234    pub disk_based_sources: Cow<'a, [String]>,
  235}
  236
  237pub struct DocumentDiagnostics {
  238    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  239    document_abs_path: PathBuf,
  240    version: Option<i32>,
  241}
  242
  243#[derive(Default, Debug)]
  244struct DynamicRegistrations {
  245    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  246    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  247}
  248
  249pub struct LocalLspStore {
  250    weak: WeakEntity<LspStore>,
  251    worktree_store: Entity<WorktreeStore>,
  252    toolchain_store: Entity<LocalToolchainStore>,
  253    http_client: Arc<dyn HttpClient>,
  254    environment: Entity<ProjectEnvironment>,
  255    fs: Arc<dyn Fs>,
  256    languages: Arc<LanguageRegistry>,
  257    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  258    yarn: Entity<YarnPathStore>,
  259    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  260    buffers_being_formatted: HashSet<BufferId>,
  261    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  262    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  263    watched_manifest_filenames: HashSet<ManifestName>,
  264    language_server_paths_watched_for_rename:
  265        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  266    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  267    supplementary_language_servers:
  268        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  269    prettier_store: Entity<PrettierStore>,
  270    next_diagnostic_group_id: usize,
  271    diagnostics: HashMap<
  272        WorktreeId,
  273        HashMap<
  274            Arc<RelPath>,
  275            Vec<(
  276                LanguageServerId,
  277                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  278            )>,
  279        >,
  280    >,
  281    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  282    _subscription: gpui::Subscription,
  283    lsp_tree: LanguageServerTree,
  284    registered_buffers: HashMap<BufferId, usize>,
  285    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  286    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  287}
  288
  289impl LocalLspStore {
  290    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  291    pub fn running_language_server_for_id(
  292        &self,
  293        id: LanguageServerId,
  294    ) -> Option<&Arc<LanguageServer>> {
  295        let language_server_state = self.language_servers.get(&id)?;
  296
  297        match language_server_state {
  298            LanguageServerState::Running { server, .. } => Some(server),
  299            LanguageServerState::Starting { .. } => None,
  300        }
  301    }
  302
  303    fn get_or_insert_language_server(
  304        &mut self,
  305        worktree_handle: &Entity<Worktree>,
  306        delegate: Arc<LocalLspAdapterDelegate>,
  307        disposition: &Arc<LaunchDisposition>,
  308        language_name: &LanguageName,
  309        cx: &mut App,
  310    ) -> LanguageServerId {
  311        let key = LanguageServerSeed {
  312            worktree_id: worktree_handle.read(cx).id(),
  313            name: disposition.server_name.clone(),
  314            settings: disposition.settings.clone(),
  315            toolchain: disposition.toolchain.clone(),
  316        };
  317        if let Some(state) = self.language_server_ids.get_mut(&key) {
  318            state.project_roots.insert(disposition.path.path.clone());
  319            state.id
  320        } else {
  321            let adapter = self
  322                .languages
  323                .lsp_adapters(language_name)
  324                .into_iter()
  325                .find(|adapter| adapter.name() == disposition.server_name)
  326                .expect("To find LSP adapter");
  327            let new_language_server_id = self.start_language_server(
  328                worktree_handle,
  329                delegate,
  330                adapter,
  331                disposition.settings.clone(),
  332                key.clone(),
  333                cx,
  334            );
  335            if let Some(state) = self.language_server_ids.get_mut(&key) {
  336                state.project_roots.insert(disposition.path.path.clone());
  337            } else {
  338                debug_assert!(
  339                    false,
  340                    "Expected `start_language_server` to ensure that `key` exists in a map"
  341                );
  342            }
  343            new_language_server_id
  344        }
  345    }
  346
  347    fn start_language_server(
  348        &mut self,
  349        worktree_handle: &Entity<Worktree>,
  350        delegate: Arc<LocalLspAdapterDelegate>,
  351        adapter: Arc<CachedLspAdapter>,
  352        settings: Arc<LspSettings>,
  353        key: LanguageServerSeed,
  354        cx: &mut App,
  355    ) -> LanguageServerId {
  356        let worktree = worktree_handle.read(cx);
  357
  358        let root_path = worktree.abs_path();
  359        let toolchain = key.toolchain.clone();
  360        let override_options = settings.initialization_options.clone();
  361
  362        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  363
  364        let server_id = self.languages.next_language_server_id();
  365        log::trace!(
  366            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  367            adapter.name.0
  368        );
  369
  370        let binary = self.get_language_server_binary(
  371            adapter.clone(),
  372            settings,
  373            toolchain.clone(),
  374            delegate.clone(),
  375            true,
  376            cx,
  377        );
  378        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  379
  380        let pending_server = cx.spawn({
  381            let adapter = adapter.clone();
  382            let server_name = adapter.name.clone();
  383            let stderr_capture = stderr_capture.clone();
  384            #[cfg(any(test, feature = "test-support"))]
  385            let lsp_store = self.weak.clone();
  386            let pending_workspace_folders = pending_workspace_folders.clone();
  387            async move |cx| {
  388                let binary = binary.await?;
  389                #[cfg(any(test, feature = "test-support"))]
  390                if let Some(server) = lsp_store
  391                    .update(&mut cx.clone(), |this, cx| {
  392                        this.languages.create_fake_language_server(
  393                            server_id,
  394                            &server_name,
  395                            binary.clone(),
  396                            &mut cx.to_async(),
  397                        )
  398                    })
  399                    .ok()
  400                    .flatten()
  401                {
  402                    return Ok(server);
  403                }
  404
  405                let code_action_kinds = adapter.code_action_kinds();
  406                lsp::LanguageServer::new(
  407                    stderr_capture,
  408                    server_id,
  409                    server_name,
  410                    binary,
  411                    &root_path,
  412                    code_action_kinds,
  413                    Some(pending_workspace_folders),
  414                    cx,
  415                )
  416            }
  417        });
  418
  419        let startup = {
  420            let server_name = adapter.name.0.clone();
  421            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  422            let key = key.clone();
  423            let adapter = adapter.clone();
  424            let lsp_store = self.weak.clone();
  425            let pending_workspace_folders = pending_workspace_folders.clone();
  426
  427            let pull_diagnostics = ProjectSettings::get_global(cx)
  428                .diagnostics
  429                .lsp_pull_diagnostics
  430                .enabled;
  431            cx.spawn(async move |cx| {
  432                let result = async {
  433                    let language_server = pending_server.await?;
  434
  435                    let workspace_config = Self::workspace_configuration_for_adapter(
  436                        adapter.adapter.clone(),
  437                        &delegate,
  438                        toolchain,
  439                        None,
  440                        cx,
  441                    )
  442                    .await?;
  443
  444                    let mut initialization_options = Self::initialization_options_for_adapter(
  445                        adapter.adapter.clone(),
  446                        &delegate,
  447                    )
  448                    .await?;
  449
  450                    match (&mut initialization_options, override_options) {
  451                        (Some(initialization_options), Some(override_options)) => {
  452                            merge_json_value_into(override_options, initialization_options);
  453                        }
  454                        (None, override_options) => initialization_options = override_options,
  455                        _ => {}
  456                    }
  457
  458                    let initialization_params = cx.update(|cx| {
  459                        let mut params =
  460                            language_server.default_initialize_params(pull_diagnostics, cx);
  461                        params.initialization_options = initialization_options;
  462                        adapter.adapter.prepare_initialize_params(params, cx)
  463                    })??;
  464
  465                    Self::setup_lsp_messages(
  466                        lsp_store.clone(),
  467                        &language_server,
  468                        delegate.clone(),
  469                        adapter.clone(),
  470                    );
  471
  472                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  473                        settings: workspace_config,
  474                    };
  475                    let language_server = cx
  476                        .update(|cx| {
  477                            language_server.initialize(
  478                                initialization_params,
  479                                Arc::new(did_change_configuration_params.clone()),
  480                                cx,
  481                            )
  482                        })?
  483                        .await
  484                        .inspect_err(|_| {
  485                            if let Some(lsp_store) = lsp_store.upgrade() {
  486                                lsp_store
  487                                    .update(cx, |lsp_store, cx| {
  488                                        lsp_store.cleanup_lsp_data(server_id);
  489                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  490                                    })
  491                                    .ok();
  492                            }
  493                        })?;
  494
  495                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  496                        did_change_configuration_params,
  497                    )?;
  498
  499                    anyhow::Ok(language_server)
  500                }
  501                .await;
  502
  503                match result {
  504                    Ok(server) => {
  505                        lsp_store
  506                            .update(cx, |lsp_store, cx| {
  507                                lsp_store.insert_newly_running_language_server(
  508                                    adapter,
  509                                    server.clone(),
  510                                    server_id,
  511                                    key,
  512                                    pending_workspace_folders,
  513                                    cx,
  514                                );
  515                            })
  516                            .ok();
  517                        stderr_capture.lock().take();
  518                        Some(server)
  519                    }
  520
  521                    Err(err) => {
  522                        let log = stderr_capture.lock().take().unwrap_or_default();
  523                        delegate.update_status(
  524                            adapter.name(),
  525                            BinaryStatus::Failed {
  526                                error: if log.is_empty() {
  527                                    format!("{err:#}")
  528                                } else {
  529                                    format!("{err:#}\n-- stderr --\n{log}")
  530                                },
  531                            },
  532                        );
  533                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  534                        if !log.is_empty() {
  535                            log::error!("server stderr: {log}");
  536                        }
  537                        None
  538                    }
  539                }
  540            })
  541        };
  542        let state = LanguageServerState::Starting {
  543            startup,
  544            pending_workspace_folders,
  545        };
  546
  547        self.languages
  548            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  549
  550        self.language_servers.insert(server_id, state);
  551        self.language_server_ids
  552            .entry(key)
  553            .or_insert(UnifiedLanguageServer {
  554                id: server_id,
  555                project_roots: Default::default(),
  556            });
  557        server_id
  558    }
  559
  560    fn get_language_server_binary(
  561        &self,
  562        adapter: Arc<CachedLspAdapter>,
  563        settings: Arc<LspSettings>,
  564        toolchain: Option<Toolchain>,
  565        delegate: Arc<dyn LspAdapterDelegate>,
  566        allow_binary_download: bool,
  567        cx: &mut App,
  568    ) -> Task<Result<LanguageServerBinary>> {
  569        if let Some(settings) = &settings.binary
  570            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  571        {
  572            let settings = settings.clone();
  573
  574            return cx.background_spawn(async move {
  575                let mut env = delegate.shell_env().await;
  576                env.extend(settings.env.unwrap_or_default());
  577
  578                Ok(LanguageServerBinary {
  579                    path: delegate.resolve_executable_path(path),
  580                    env: Some(env),
  581                    arguments: settings
  582                        .arguments
  583                        .unwrap_or_default()
  584                        .iter()
  585                        .map(Into::into)
  586                        .collect(),
  587                })
  588            });
  589        }
  590        let lsp_binary_options = LanguageServerBinaryOptions {
  591            allow_path_lookup: !settings
  592                .binary
  593                .as_ref()
  594                .and_then(|b| b.ignore_system_version)
  595                .unwrap_or_default(),
  596            allow_binary_download,
  597            pre_release: settings
  598                .fetch
  599                .as_ref()
  600                .and_then(|f| f.pre_release)
  601                .unwrap_or(false),
  602        };
  603
  604        cx.spawn(async move |cx| {
  605            let (existing_binary, maybe_download_binary) = adapter
  606                .clone()
  607                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  608                .await
  609                .await;
  610
  611            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  612
  613            let mut binary = match (existing_binary, maybe_download_binary) {
  614                (binary, None) => binary?,
  615                (Err(_), Some(downloader)) => downloader.await?,
  616                (Ok(existing_binary), Some(downloader)) => {
  617                    let mut download_timeout = cx
  618                        .background_executor()
  619                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  620                        .fuse();
  621                    let mut downloader = downloader.fuse();
  622                    futures::select! {
  623                        _ = download_timeout => {
  624                            // Return existing binary and kick the existing work to the background.
  625                            cx.spawn(async move |_| downloader.await).detach();
  626                            Ok(existing_binary)
  627                        },
  628                        downloaded_or_existing_binary = downloader => {
  629                            // If download fails, this results in the existing binary.
  630                            downloaded_or_existing_binary
  631                        }
  632                    }?
  633                }
  634            };
  635            let mut shell_env = delegate.shell_env().await;
  636
  637            shell_env.extend(binary.env.unwrap_or_default());
  638
  639            if let Some(settings) = settings.binary.as_ref() {
  640                if let Some(arguments) = &settings.arguments {
  641                    binary.arguments = arguments.iter().map(Into::into).collect();
  642                }
  643                if let Some(env) = &settings.env {
  644                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  645                }
  646            }
  647
  648            binary.env = Some(shell_env);
  649            Ok(binary)
  650        })
  651    }
  652
  653    fn setup_lsp_messages(
  654        lsp_store: WeakEntity<LspStore>,
  655        language_server: &LanguageServer,
  656        delegate: Arc<dyn LspAdapterDelegate>,
  657        adapter: Arc<CachedLspAdapter>,
  658    ) {
  659        let name = language_server.name();
  660        let server_id = language_server.server_id();
  661        language_server
  662            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  663                let adapter = adapter.clone();
  664                let this = lsp_store.clone();
  665                move |mut params, cx| {
  666                    let adapter = adapter.clone();
  667                    if let Some(this) = this.upgrade() {
  668                        this.update(cx, |this, cx| {
  669                            {
  670                                let buffer = params
  671                                    .uri
  672                                    .to_file_path()
  673                                    .map(|file_path| this.get_buffer(&file_path, cx))
  674                                    .ok()
  675                                    .flatten();
  676                                adapter.process_diagnostics(&mut params, server_id, buffer);
  677                            }
  678
  679                            this.merge_lsp_diagnostics(
  680                                DiagnosticSourceKind::Pushed,
  681                                vec![DocumentDiagnosticsUpdate {
  682                                    server_id,
  683                                    diagnostics: params,
  684                                    result_id: None,
  685                                    disk_based_sources: Cow::Borrowed(
  686                                        &adapter.disk_based_diagnostic_sources,
  687                                    ),
  688                                }],
  689                                |_, diagnostic, cx| match diagnostic.source_kind {
  690                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  691                                        adapter.retain_old_diagnostic(diagnostic, cx)
  692                                    }
  693                                    DiagnosticSourceKind::Pulled => true,
  694                                },
  695                                cx,
  696                            )
  697                            .log_err();
  698                        })
  699                        .ok();
  700                    }
  701                }
  702            })
  703            .detach();
  704        language_server
  705            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  706                let adapter = adapter.adapter.clone();
  707                let delegate = delegate.clone();
  708                let this = lsp_store.clone();
  709                move |params, cx| {
  710                    let adapter = adapter.clone();
  711                    let delegate = delegate.clone();
  712                    let this = this.clone();
  713                    let mut cx = cx.clone();
  714                    async move {
  715                        let toolchain_for_id = this
  716                            .update(&mut cx, |this, _| {
  717                                this.as_local()?.language_server_ids.iter().find_map(
  718                                    |(seed, value)| {
  719                                        (value.id == server_id).then(|| seed.toolchain.clone())
  720                                    },
  721                                )
  722                            })?
  723                            .context("Expected the LSP store to be in a local mode")?;
  724
  725                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  726                        for item in &params.items {
  727                            let scope_uri = item.scope_uri.clone();
  728                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  729                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  730                            else {
  731                                // We've already queried workspace configuration of this URI.
  732                                continue;
  733                            };
  734                            let workspace_config = Self::workspace_configuration_for_adapter(
  735                                adapter.clone(),
  736                                &delegate,
  737                                toolchain_for_id.clone(),
  738                                scope_uri,
  739                                &mut cx,
  740                            )
  741                            .await?;
  742                            new_scope_uri.insert(workspace_config);
  743                        }
  744
  745                        Ok(params
  746                            .items
  747                            .into_iter()
  748                            .filter_map(|item| {
  749                                let workspace_config =
  750                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  751                                if let Some(section) = &item.section {
  752                                    Some(
  753                                        workspace_config
  754                                            .get(section)
  755                                            .cloned()
  756                                            .unwrap_or(serde_json::Value::Null),
  757                                    )
  758                                } else {
  759                                    Some(workspace_config.clone())
  760                                }
  761                            })
  762                            .collect())
  763                    }
  764                }
  765            })
  766            .detach();
  767
  768        language_server
  769            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  770                let this = lsp_store.clone();
  771                move |_, cx| {
  772                    let this = this.clone();
  773                    let cx = cx.clone();
  774                    async move {
  775                        let Some(server) =
  776                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  777                        else {
  778                            return Ok(None);
  779                        };
  780                        let root = server.workspace_folders();
  781                        Ok(Some(
  782                            root.into_iter()
  783                                .map(|uri| WorkspaceFolder {
  784                                    uri,
  785                                    name: Default::default(),
  786                                })
  787                                .collect(),
  788                        ))
  789                    }
  790                }
  791            })
  792            .detach();
  793        // Even though we don't have handling for these requests, respond to them to
  794        // avoid stalling any language server like `gopls` which waits for a response
  795        // to these requests when initializing.
  796        language_server
  797            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  798                let this = lsp_store.clone();
  799                move |params, cx| {
  800                    let this = this.clone();
  801                    let mut cx = cx.clone();
  802                    async move {
  803                        this.update(&mut cx, |this, _| {
  804                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  805                            {
  806                                status
  807                                    .progress_tokens
  808                                    .insert(ProgressToken::from_lsp(params.token));
  809                            }
  810                        })?;
  811
  812                        Ok(())
  813                    }
  814                }
  815            })
  816            .detach();
  817
  818        language_server
  819            .on_request::<lsp::request::RegisterCapability, _, _>({
  820                let lsp_store = lsp_store.clone();
  821                move |params, cx| {
  822                    let lsp_store = lsp_store.clone();
  823                    let mut cx = cx.clone();
  824                    async move {
  825                        lsp_store
  826                            .update(&mut cx, |lsp_store, cx| {
  827                                if lsp_store.as_local().is_some() {
  828                                    match lsp_store
  829                                        .register_server_capabilities(server_id, params, cx)
  830                                    {
  831                                        Ok(()) => {}
  832                                        Err(e) => {
  833                                            log::error!(
  834                                                "Failed to register server capabilities: {e:#}"
  835                                            );
  836                                        }
  837                                    };
  838                                }
  839                            })
  840                            .ok();
  841                        Ok(())
  842                    }
  843                }
  844            })
  845            .detach();
  846
  847        language_server
  848            .on_request::<lsp::request::UnregisterCapability, _, _>({
  849                let lsp_store = lsp_store.clone();
  850                move |params, cx| {
  851                    let lsp_store = lsp_store.clone();
  852                    let mut cx = cx.clone();
  853                    async move {
  854                        lsp_store
  855                            .update(&mut cx, |lsp_store, cx| {
  856                                if lsp_store.as_local().is_some() {
  857                                    match lsp_store
  858                                        .unregister_server_capabilities(server_id, params, cx)
  859                                    {
  860                                        Ok(()) => {}
  861                                        Err(e) => {
  862                                            log::error!(
  863                                                "Failed to unregister server capabilities: {e:#}"
  864                                            );
  865                                        }
  866                                    }
  867                                }
  868                            })
  869                            .ok();
  870                        Ok(())
  871                    }
  872                }
  873            })
  874            .detach();
  875
  876        language_server
  877            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  878                let this = lsp_store.clone();
  879                move |params, cx| {
  880                    let mut cx = cx.clone();
  881                    let this = this.clone();
  882                    async move {
  883                        LocalLspStore::on_lsp_workspace_edit(
  884                            this.clone(),
  885                            params,
  886                            server_id,
  887                            &mut cx,
  888                        )
  889                        .await
  890                    }
  891                }
  892            })
  893            .detach();
  894
  895        language_server
  896            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  897                let lsp_store = lsp_store.clone();
  898                let request_id = Arc::new(AtomicUsize::new(0));
  899                move |(), cx| {
  900                    let lsp_store = lsp_store.clone();
  901                    let request_id = request_id.clone();
  902                    let mut cx = cx.clone();
  903                    async move {
  904                        lsp_store
  905                            .update(&mut cx, |lsp_store, cx| {
  906                                let request_id =
  907                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  908                                cx.emit(LspStoreEvent::RefreshInlayHints {
  909                                    server_id,
  910                                    request_id,
  911                                });
  912                                lsp_store
  913                                    .downstream_client
  914                                    .as_ref()
  915                                    .map(|(client, project_id)| {
  916                                        client.send(proto::RefreshInlayHints {
  917                                            project_id: *project_id,
  918                                            server_id: server_id.to_proto(),
  919                                            request_id: request_id.map(|id| id as u64),
  920                                        })
  921                                    })
  922                            })?
  923                            .transpose()?;
  924                        Ok(())
  925                    }
  926                }
  927            })
  928            .detach();
  929
  930        language_server
  931            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  932                let this = lsp_store.clone();
  933                move |(), cx| {
  934                    let this = this.clone();
  935                    let mut cx = cx.clone();
  936                    async move {
  937                        this.update(&mut cx, |this, cx| {
  938                            cx.emit(LspStoreEvent::RefreshCodeLens);
  939                            this.downstream_client.as_ref().map(|(client, project_id)| {
  940                                client.send(proto::RefreshCodeLens {
  941                                    project_id: *project_id,
  942                                })
  943                            })
  944                        })?
  945                        .transpose()?;
  946                        Ok(())
  947                    }
  948                }
  949            })
  950            .detach();
  951
  952        language_server
  953            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  954                let this = lsp_store.clone();
  955                move |(), cx| {
  956                    let this = this.clone();
  957                    let mut cx = cx.clone();
  958                    async move {
  959                        this.update(&mut cx, |lsp_store, _| {
  960                            lsp_store.pull_workspace_diagnostics(server_id);
  961                            lsp_store
  962                                .downstream_client
  963                                .as_ref()
  964                                .map(|(client, project_id)| {
  965                                    client.send(proto::PullWorkspaceDiagnostics {
  966                                        project_id: *project_id,
  967                                        server_id: server_id.to_proto(),
  968                                    })
  969                                })
  970                        })?
  971                        .transpose()?;
  972                        Ok(())
  973                    }
  974                }
  975            })
  976            .detach();
  977
  978        language_server
  979            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  980                let this = lsp_store.clone();
  981                let name = name.to_string();
  982                move |params, cx| {
  983                    let this = this.clone();
  984                    let name = name.to_string();
  985                    let mut cx = cx.clone();
  986                    async move {
  987                        let actions = params.actions.unwrap_or_default();
  988                        let (tx, rx) = smol::channel::bounded(1);
  989                        let request = LanguageServerPromptRequest {
  990                            level: match params.typ {
  991                                lsp::MessageType::ERROR => PromptLevel::Critical,
  992                                lsp::MessageType::WARNING => PromptLevel::Warning,
  993                                _ => PromptLevel::Info,
  994                            },
  995                            message: params.message,
  996                            actions,
  997                            response_channel: tx,
  998                            lsp_name: name.clone(),
  999                        };
 1000
 1001                        let did_update = this
 1002                            .update(&mut cx, |_, cx| {
 1003                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1004                            })
 1005                            .is_ok();
 1006                        if did_update {
 1007                            let response = rx.recv().await.ok();
 1008                            Ok(response)
 1009                        } else {
 1010                            Ok(None)
 1011                        }
 1012                    }
 1013                }
 1014            })
 1015            .detach();
 1016        language_server
 1017            .on_notification::<lsp::notification::ShowMessage, _>({
 1018                let this = lsp_store.clone();
 1019                let name = name.to_string();
 1020                move |params, cx| {
 1021                    let this = this.clone();
 1022                    let name = name.to_string();
 1023                    let mut cx = cx.clone();
 1024
 1025                    let (tx, _) = smol::channel::bounded(1);
 1026                    let request = LanguageServerPromptRequest {
 1027                        level: match params.typ {
 1028                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1029                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1030                            _ => PromptLevel::Info,
 1031                        },
 1032                        message: params.message,
 1033                        actions: vec![],
 1034                        response_channel: tx,
 1035                        lsp_name: name,
 1036                    };
 1037
 1038                    let _ = this.update(&mut cx, |_, cx| {
 1039                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1040                    });
 1041                }
 1042            })
 1043            .detach();
 1044
 1045        let disk_based_diagnostics_progress_token =
 1046            adapter.disk_based_diagnostics_progress_token.clone();
 1047
 1048        language_server
 1049            .on_notification::<lsp::notification::Progress, _>({
 1050                let this = lsp_store.clone();
 1051                move |params, cx| {
 1052                    if let Some(this) = this.upgrade() {
 1053                        this.update(cx, |this, cx| {
 1054                            this.on_lsp_progress(
 1055                                params,
 1056                                server_id,
 1057                                disk_based_diagnostics_progress_token.clone(),
 1058                                cx,
 1059                            );
 1060                        })
 1061                        .ok();
 1062                    }
 1063                }
 1064            })
 1065            .detach();
 1066
 1067        language_server
 1068            .on_notification::<lsp::notification::LogMessage, _>({
 1069                let this = lsp_store.clone();
 1070                move |params, cx| {
 1071                    if let Some(this) = this.upgrade() {
 1072                        this.update(cx, |_, cx| {
 1073                            cx.emit(LspStoreEvent::LanguageServerLog(
 1074                                server_id,
 1075                                LanguageServerLogType::Log(params.typ),
 1076                                params.message,
 1077                            ));
 1078                        })
 1079                        .ok();
 1080                    }
 1081                }
 1082            })
 1083            .detach();
 1084
 1085        language_server
 1086            .on_notification::<lsp::notification::LogTrace, _>({
 1087                let this = lsp_store.clone();
 1088                move |params, cx| {
 1089                    let mut cx = cx.clone();
 1090                    if let Some(this) = this.upgrade() {
 1091                        this.update(&mut cx, |_, cx| {
 1092                            cx.emit(LspStoreEvent::LanguageServerLog(
 1093                                server_id,
 1094                                LanguageServerLogType::Trace {
 1095                                    verbose_info: params.verbose,
 1096                                },
 1097                                params.message,
 1098                            ));
 1099                        })
 1100                        .ok();
 1101                    }
 1102                }
 1103            })
 1104            .detach();
 1105
 1106        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1107        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1108        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1109        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1110    }
 1111
 1112    fn shutdown_language_servers_on_quit(
 1113        &mut self,
 1114        _: &mut Context<LspStore>,
 1115    ) -> impl Future<Output = ()> + use<> {
 1116        let shutdown_futures = self
 1117            .language_servers
 1118            .drain()
 1119            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1120            .collect::<Vec<_>>();
 1121
 1122        async move {
 1123            join_all(shutdown_futures).await;
 1124        }
 1125    }
 1126
 1127    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1128        match server_state {
 1129            LanguageServerState::Running { server, .. } => {
 1130                if let Some(shutdown) = server.shutdown() {
 1131                    shutdown.await;
 1132                }
 1133            }
 1134            LanguageServerState::Starting { startup, .. } => {
 1135                if let Some(server) = startup.await
 1136                    && let Some(shutdown) = server.shutdown()
 1137                {
 1138                    shutdown.await;
 1139                }
 1140            }
 1141        }
 1142        Ok(())
 1143    }
 1144
 1145    fn language_servers_for_worktree(
 1146        &self,
 1147        worktree_id: WorktreeId,
 1148    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1149        self.language_server_ids
 1150            .iter()
 1151            .filter_map(move |(seed, state)| {
 1152                if seed.worktree_id != worktree_id {
 1153                    return None;
 1154                }
 1155
 1156                if let Some(LanguageServerState::Running { server, .. }) =
 1157                    self.language_servers.get(&state.id)
 1158                {
 1159                    Some(server)
 1160                } else {
 1161                    None
 1162                }
 1163            })
 1164    }
 1165
 1166    fn language_server_ids_for_project_path(
 1167        &self,
 1168        project_path: ProjectPath,
 1169        language: &Language,
 1170        cx: &mut App,
 1171    ) -> Vec<LanguageServerId> {
 1172        let Some(worktree) = self
 1173            .worktree_store
 1174            .read(cx)
 1175            .worktree_for_id(project_path.worktree_id, cx)
 1176        else {
 1177            return Vec::new();
 1178        };
 1179        let delegate: Arc<dyn ManifestDelegate> =
 1180            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1181
 1182        self.lsp_tree
 1183            .get(
 1184                project_path,
 1185                language.name(),
 1186                language.manifest(),
 1187                &delegate,
 1188                cx,
 1189            )
 1190            .collect::<Vec<_>>()
 1191    }
 1192
 1193    fn language_server_ids_for_buffer(
 1194        &self,
 1195        buffer: &Buffer,
 1196        cx: &mut App,
 1197    ) -> Vec<LanguageServerId> {
 1198        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1199            let worktree_id = file.worktree_id(cx);
 1200
 1201            let path: Arc<RelPath> = file
 1202                .path()
 1203                .parent()
 1204                .map(Arc::from)
 1205                .unwrap_or_else(|| file.path().clone());
 1206            let worktree_path = ProjectPath { worktree_id, path };
 1207            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1208        } else {
 1209            Vec::new()
 1210        }
 1211    }
 1212
 1213    fn language_servers_for_buffer<'a>(
 1214        &'a self,
 1215        buffer: &'a Buffer,
 1216        cx: &'a mut App,
 1217    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1218        self.language_server_ids_for_buffer(buffer, cx)
 1219            .into_iter()
 1220            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1221                LanguageServerState::Running {
 1222                    adapter, server, ..
 1223                } => Some((adapter, server)),
 1224                _ => None,
 1225            })
 1226    }
 1227
 1228    async fn execute_code_action_kind_locally(
 1229        lsp_store: WeakEntity<LspStore>,
 1230        mut buffers: Vec<Entity<Buffer>>,
 1231        kind: CodeActionKind,
 1232        push_to_history: bool,
 1233        cx: &mut AsyncApp,
 1234    ) -> anyhow::Result<ProjectTransaction> {
 1235        // Do not allow multiple concurrent code actions requests for the
 1236        // same buffer.
 1237        lsp_store.update(cx, |this, cx| {
 1238            let this = this.as_local_mut().unwrap();
 1239            buffers.retain(|buffer| {
 1240                this.buffers_being_formatted
 1241                    .insert(buffer.read(cx).remote_id())
 1242            });
 1243        })?;
 1244        let _cleanup = defer({
 1245            let this = lsp_store.clone();
 1246            let mut cx = cx.clone();
 1247            let buffers = &buffers;
 1248            move || {
 1249                this.update(&mut cx, |this, cx| {
 1250                    let this = this.as_local_mut().unwrap();
 1251                    for buffer in buffers {
 1252                        this.buffers_being_formatted
 1253                            .remove(&buffer.read(cx).remote_id());
 1254                    }
 1255                })
 1256                .ok();
 1257            }
 1258        });
 1259        let mut project_transaction = ProjectTransaction::default();
 1260
 1261        for buffer in &buffers {
 1262            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1263                buffer.update(cx, |buffer, cx| {
 1264                    lsp_store
 1265                        .as_local()
 1266                        .unwrap()
 1267                        .language_servers_for_buffer(buffer, cx)
 1268                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1269                        .collect::<Vec<_>>()
 1270                })
 1271            })?;
 1272            for (_, language_server) in adapters_and_servers.iter() {
 1273                let actions = Self::get_server_code_actions_from_action_kinds(
 1274                    &lsp_store,
 1275                    language_server.server_id(),
 1276                    vec![kind.clone()],
 1277                    buffer,
 1278                    cx,
 1279                )
 1280                .await?;
 1281                Self::execute_code_actions_on_server(
 1282                    &lsp_store,
 1283                    language_server,
 1284                    actions,
 1285                    push_to_history,
 1286                    &mut project_transaction,
 1287                    cx,
 1288                )
 1289                .await?;
 1290            }
 1291        }
 1292        Ok(project_transaction)
 1293    }
 1294
 1295    async fn format_locally(
 1296        lsp_store: WeakEntity<LspStore>,
 1297        mut buffers: Vec<FormattableBuffer>,
 1298        push_to_history: bool,
 1299        trigger: FormatTrigger,
 1300        logger: zlog::Logger,
 1301        cx: &mut AsyncApp,
 1302    ) -> anyhow::Result<ProjectTransaction> {
 1303        // Do not allow multiple concurrent formatting requests for the
 1304        // same buffer.
 1305        lsp_store.update(cx, |this, cx| {
 1306            let this = this.as_local_mut().unwrap();
 1307            buffers.retain(|buffer| {
 1308                this.buffers_being_formatted
 1309                    .insert(buffer.handle.read(cx).remote_id())
 1310            });
 1311        })?;
 1312
 1313        let _cleanup = defer({
 1314            let this = lsp_store.clone();
 1315            let mut cx = cx.clone();
 1316            let buffers = &buffers;
 1317            move || {
 1318                this.update(&mut cx, |this, cx| {
 1319                    let this = this.as_local_mut().unwrap();
 1320                    for buffer in buffers {
 1321                        this.buffers_being_formatted
 1322                            .remove(&buffer.handle.read(cx).remote_id());
 1323                    }
 1324                })
 1325                .ok();
 1326            }
 1327        });
 1328
 1329        let mut project_transaction = ProjectTransaction::default();
 1330
 1331        for buffer in &buffers {
 1332            zlog::debug!(
 1333                logger =>
 1334                "formatting buffer '{:?}'",
 1335                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1336            );
 1337            // Create an empty transaction to hold all of the formatting edits.
 1338            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1339                // ensure no transactions created while formatting are
 1340                // grouped with the previous transaction in the history
 1341                // based on the transaction group interval
 1342                buffer.finalize_last_transaction();
 1343                buffer
 1344                    .start_transaction()
 1345                    .context("transaction already open")?;
 1346                buffer.end_transaction(cx);
 1347                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1348                buffer.finalize_last_transaction();
 1349                anyhow::Ok(transaction_id)
 1350            })??;
 1351
 1352            let result = Self::format_buffer_locally(
 1353                lsp_store.clone(),
 1354                buffer,
 1355                formatting_transaction_id,
 1356                trigger,
 1357                logger,
 1358                cx,
 1359            )
 1360            .await;
 1361
 1362            buffer.handle.update(cx, |buffer, cx| {
 1363                let Some(formatting_transaction) =
 1364                    buffer.get_transaction(formatting_transaction_id).cloned()
 1365                else {
 1366                    zlog::warn!(logger => "no formatting transaction");
 1367                    return;
 1368                };
 1369                if formatting_transaction.edit_ids.is_empty() {
 1370                    zlog::debug!(logger => "no changes made while formatting");
 1371                    buffer.forget_transaction(formatting_transaction_id);
 1372                    return;
 1373                }
 1374                if !push_to_history {
 1375                    zlog::trace!(logger => "forgetting format transaction");
 1376                    buffer.forget_transaction(formatting_transaction.id);
 1377                }
 1378                project_transaction
 1379                    .0
 1380                    .insert(cx.entity(), formatting_transaction);
 1381            })?;
 1382
 1383            result?;
 1384        }
 1385
 1386        Ok(project_transaction)
 1387    }
 1388
 1389    async fn format_buffer_locally(
 1390        lsp_store: WeakEntity<LspStore>,
 1391        buffer: &FormattableBuffer,
 1392        formatting_transaction_id: clock::Lamport,
 1393        trigger: FormatTrigger,
 1394        logger: zlog::Logger,
 1395        cx: &mut AsyncApp,
 1396    ) -> Result<()> {
 1397        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1398            buffer.handle.update(cx, |buffer, cx| {
 1399                let adapters_and_servers = lsp_store
 1400                    .as_local()
 1401                    .unwrap()
 1402                    .language_servers_for_buffer(buffer, cx)
 1403                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1404                    .collect::<Vec<_>>();
 1405                let settings =
 1406                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1407                        .into_owned();
 1408                (adapters_and_servers, settings)
 1409            })
 1410        })?;
 1411
 1412        /// Apply edits to the buffer that will become part of the formatting transaction.
 1413        /// Fails if the buffer has been edited since the start of that transaction.
 1414        fn extend_formatting_transaction(
 1415            buffer: &FormattableBuffer,
 1416            formatting_transaction_id: text::TransactionId,
 1417            cx: &mut AsyncApp,
 1418            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1419        ) -> anyhow::Result<()> {
 1420            buffer.handle.update(cx, |buffer, cx| {
 1421                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1422                if last_transaction_id != Some(formatting_transaction_id) {
 1423                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1424                }
 1425                buffer.start_transaction();
 1426                operation(buffer, cx);
 1427                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1428                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1429                }
 1430                Ok(())
 1431            })?
 1432        }
 1433
 1434        // handle whitespace formatting
 1435        if settings.remove_trailing_whitespace_on_save {
 1436            zlog::trace!(logger => "removing trailing whitespace");
 1437            let diff = buffer
 1438                .handle
 1439                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1440                .await;
 1441            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1442                buffer.apply_diff(diff, cx);
 1443            })?;
 1444        }
 1445
 1446        if settings.ensure_final_newline_on_save {
 1447            zlog::trace!(logger => "ensuring final newline");
 1448            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1449                buffer.ensure_final_newline(cx);
 1450            })?;
 1451        }
 1452
 1453        // Formatter for `code_actions_on_format` that runs before
 1454        // the rest of the formatters
 1455        let mut code_actions_on_format_formatters = None;
 1456        let should_run_code_actions_on_format = !matches!(
 1457            (trigger, &settings.format_on_save),
 1458            (FormatTrigger::Save, &FormatOnSave::Off)
 1459        );
 1460        if should_run_code_actions_on_format {
 1461            let have_code_actions_to_run_on_format = settings
 1462                .code_actions_on_format
 1463                .values()
 1464                .any(|enabled| *enabled);
 1465            if have_code_actions_to_run_on_format {
 1466                zlog::trace!(logger => "going to run code actions on format");
 1467                code_actions_on_format_formatters = Some(
 1468                    settings
 1469                        .code_actions_on_format
 1470                        .iter()
 1471                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1472                        .cloned()
 1473                        .map(Formatter::CodeAction)
 1474                        .collect::<Vec<_>>(),
 1475                );
 1476            }
 1477        }
 1478
 1479        let formatters = match (trigger, &settings.format_on_save) {
 1480            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1481            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1482                settings.formatter.as_ref()
 1483            }
 1484        };
 1485
 1486        let formatters = code_actions_on_format_formatters
 1487            .iter()
 1488            .flatten()
 1489            .chain(formatters);
 1490
 1491        for formatter in formatters {
 1492            let formatter = if formatter == &Formatter::Auto {
 1493                if settings.prettier.allowed {
 1494                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1495                    &Formatter::Prettier
 1496                } else {
 1497                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1498                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1499                }
 1500            } else {
 1501                formatter
 1502            };
 1503            match formatter {
 1504                Formatter::Auto => unreachable!("Auto resolved above"),
 1505                Formatter::Prettier => {
 1506                    let logger = zlog::scoped!(logger => "prettier");
 1507                    zlog::trace!(logger => "formatting");
 1508                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1509
 1510                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1511                        lsp_store.prettier_store().unwrap().downgrade()
 1512                    })?;
 1513                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1514                        .await
 1515                        .transpose()?;
 1516                    let Some(diff) = diff else {
 1517                        zlog::trace!(logger => "No changes");
 1518                        continue;
 1519                    };
 1520
 1521                    extend_formatting_transaction(
 1522                        buffer,
 1523                        formatting_transaction_id,
 1524                        cx,
 1525                        |buffer, cx| {
 1526                            buffer.apply_diff(diff, cx);
 1527                        },
 1528                    )?;
 1529                }
 1530                Formatter::External { command, arguments } => {
 1531                    let logger = zlog::scoped!(logger => "command");
 1532                    zlog::trace!(logger => "formatting");
 1533                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1534
 1535                    let diff = Self::format_via_external_command(
 1536                        buffer,
 1537                        command.as_ref(),
 1538                        arguments.as_deref(),
 1539                        cx,
 1540                    )
 1541                    .await
 1542                    .with_context(|| {
 1543                        format!("Failed to format buffer via external command: {}", command)
 1544                    })?;
 1545                    let Some(diff) = diff else {
 1546                        zlog::trace!(logger => "No changes");
 1547                        continue;
 1548                    };
 1549
 1550                    extend_formatting_transaction(
 1551                        buffer,
 1552                        formatting_transaction_id,
 1553                        cx,
 1554                        |buffer, cx| {
 1555                            buffer.apply_diff(diff, cx);
 1556                        },
 1557                    )?;
 1558                }
 1559                Formatter::LanguageServer(specifier) => {
 1560                    let logger = zlog::scoped!(logger => "language-server");
 1561                    zlog::trace!(logger => "formatting");
 1562                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1563
 1564                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1565                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1566                        continue;
 1567                    };
 1568
 1569                    let language_server = match specifier {
 1570                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1571                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1572                                if adapter.name.0.as_ref() == name {
 1573                                    Some(server.clone())
 1574                                } else {
 1575                                    None
 1576                                }
 1577                            })
 1578                        }
 1579                        settings::LanguageServerFormatterSpecifier::Current => {
 1580                            adapters_and_servers.first().map(|e| e.1.clone())
 1581                        }
 1582                    };
 1583
 1584                    let Some(language_server) = language_server else {
 1585                        log::debug!(
 1586                            "No language server found to format buffer '{:?}'. Skipping",
 1587                            buffer_path_abs.as_path().to_string_lossy()
 1588                        );
 1589                        continue;
 1590                    };
 1591
 1592                    zlog::trace!(
 1593                        logger =>
 1594                        "Formatting buffer '{:?}' using language server '{:?}'",
 1595                        buffer_path_abs.as_path().to_string_lossy(),
 1596                        language_server.name()
 1597                    );
 1598
 1599                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1600                        zlog::trace!(logger => "formatting ranges");
 1601                        Self::format_ranges_via_lsp(
 1602                            &lsp_store,
 1603                            &buffer.handle,
 1604                            ranges,
 1605                            buffer_path_abs,
 1606                            &language_server,
 1607                            &settings,
 1608                            cx,
 1609                        )
 1610                        .await
 1611                        .context("Failed to format ranges via language server")?
 1612                    } else {
 1613                        zlog::trace!(logger => "formatting full");
 1614                        Self::format_via_lsp(
 1615                            &lsp_store,
 1616                            &buffer.handle,
 1617                            buffer_path_abs,
 1618                            &language_server,
 1619                            &settings,
 1620                            cx,
 1621                        )
 1622                        .await
 1623                        .context("failed to format via language server")?
 1624                    };
 1625
 1626                    if edits.is_empty() {
 1627                        zlog::trace!(logger => "No changes");
 1628                        continue;
 1629                    }
 1630                    extend_formatting_transaction(
 1631                        buffer,
 1632                        formatting_transaction_id,
 1633                        cx,
 1634                        |buffer, cx| {
 1635                            buffer.edit(edits, None, cx);
 1636                        },
 1637                    )?;
 1638                }
 1639                Formatter::CodeAction(code_action_name) => {
 1640                    let logger = zlog::scoped!(logger => "code-actions");
 1641                    zlog::trace!(logger => "formatting");
 1642                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1643
 1644                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1645                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1646                        continue;
 1647                    };
 1648
 1649                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1650                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1651
 1652                    let mut actions_and_servers = Vec::new();
 1653
 1654                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1655                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1656                            &lsp_store,
 1657                            language_server.server_id(),
 1658                            vec![code_action_kind.clone()],
 1659                            &buffer.handle,
 1660                            cx,
 1661                        )
 1662                        .await
 1663                        .with_context(|| {
 1664                            format!(
 1665                                "Failed to resolve code action {:?} with language server {}",
 1666                                code_action_kind,
 1667                                language_server.name()
 1668                            )
 1669                        });
 1670                        let Ok(actions) = actions_result else {
 1671                            // note: it may be better to set result to the error and break formatters here
 1672                            // but for now we try to execute the actions that we can resolve and skip the rest
 1673                            zlog::error!(
 1674                                logger =>
 1675                                "Failed to resolve code action {:?} with language server {}",
 1676                                code_action_kind,
 1677                                language_server.name()
 1678                            );
 1679                            continue;
 1680                        };
 1681                        for action in actions {
 1682                            actions_and_servers.push((action, index));
 1683                        }
 1684                    }
 1685
 1686                    if actions_and_servers.is_empty() {
 1687                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1688                        continue;
 1689                    }
 1690
 1691                    'actions: for (mut action, server_index) in actions_and_servers {
 1692                        let server = &adapters_and_servers[server_index].1;
 1693
 1694                        let describe_code_action = |action: &CodeAction| {
 1695                            format!(
 1696                                "code action '{}' with title \"{}\" on server {}",
 1697                                action
 1698                                    .lsp_action
 1699                                    .action_kind()
 1700                                    .unwrap_or("unknown".into())
 1701                                    .as_str(),
 1702                                action.lsp_action.title(),
 1703                                server.name(),
 1704                            )
 1705                        };
 1706
 1707                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1708
 1709                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1710                            zlog::error!(
 1711                                logger =>
 1712                                "Failed to resolve {}. Error: {}",
 1713                                describe_code_action(&action),
 1714                                err
 1715                            );
 1716                            continue;
 1717                        }
 1718
 1719                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1720                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1721                            // but filters out and logs warnings for code actions that require unreasonably
 1722                            // difficult handling on our part, such as:
 1723                            // - applying edits that call commands
 1724                            //   which can result in arbitrary workspace edits being sent from the server that
 1725                            //   have no way of being tied back to the command that initiated them (i.e. we
 1726                            //   can't know which edits are part of the format request, or if the server is done sending
 1727                            //   actions in response to the command)
 1728                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1729                            //   as we then would need to handle such changes correctly in the local history as well
 1730                            //   as the remote history through the ProjectTransaction
 1731                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1732                            // Supporting these actions is not impossible, but not supported as of yet.
 1733                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1734                                zlog::trace!(
 1735                                    logger =>
 1736                                    "No changes for code action. Skipping {}",
 1737                                    describe_code_action(&action),
 1738                                );
 1739                                continue;
 1740                            }
 1741
 1742                            let mut operations = Vec::new();
 1743                            if let Some(document_changes) = edit.document_changes {
 1744                                match document_changes {
 1745                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1746                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1747                                    ),
 1748                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1749                                }
 1750                            } else if let Some(changes) = edit.changes {
 1751                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1752                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1753                                        text_document:
 1754                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1755                                                uri,
 1756                                                version: None,
 1757                                            },
 1758                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1759                                    })
 1760                                }));
 1761                            }
 1762
 1763                            let mut edits = Vec::with_capacity(operations.len());
 1764
 1765                            if operations.is_empty() {
 1766                                zlog::trace!(
 1767                                    logger =>
 1768                                    "No changes for code action. Skipping {}",
 1769                                    describe_code_action(&action),
 1770                                );
 1771                                continue;
 1772                            }
 1773                            for operation in operations {
 1774                                let op = match operation {
 1775                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1776                                    lsp::DocumentChangeOperation::Op(_) => {
 1777                                        zlog::warn!(
 1778                                            logger =>
 1779                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1780                                            describe_code_action(&action),
 1781                                        );
 1782                                        continue 'actions;
 1783                                    }
 1784                                };
 1785                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1786                                    zlog::warn!(
 1787                                        logger =>
 1788                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1789                                        &op.text_document.uri,
 1790                                        describe_code_action(&action),
 1791                                    );
 1792                                    continue 'actions;
 1793                                };
 1794                                if &file_path != buffer_path_abs {
 1795                                    zlog::warn!(
 1796                                        logger =>
 1797                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1798                                        file_path,
 1799                                        buffer_path_abs,
 1800                                        describe_code_action(&action),
 1801                                    );
 1802                                    continue 'actions;
 1803                                }
 1804
 1805                                let mut lsp_edits = Vec::new();
 1806                                for edit in op.edits {
 1807                                    match edit {
 1808                                        Edit::Plain(edit) => {
 1809                                            if !lsp_edits.contains(&edit) {
 1810                                                lsp_edits.push(edit);
 1811                                            }
 1812                                        }
 1813                                        Edit::Annotated(edit) => {
 1814                                            if !lsp_edits.contains(&edit.text_edit) {
 1815                                                lsp_edits.push(edit.text_edit);
 1816                                            }
 1817                                        }
 1818                                        Edit::Snippet(_) => {
 1819                                            zlog::warn!(
 1820                                                logger =>
 1821                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1822                                                describe_code_action(&action),
 1823                                            );
 1824                                            continue 'actions;
 1825                                        }
 1826                                    }
 1827                                }
 1828                                let edits_result = lsp_store
 1829                                    .update(cx, |lsp_store, cx| {
 1830                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1831                                            &buffer.handle,
 1832                                            lsp_edits,
 1833                                            server.server_id(),
 1834                                            op.text_document.version,
 1835                                            cx,
 1836                                        )
 1837                                    })?
 1838                                    .await;
 1839                                let Ok(resolved_edits) = edits_result else {
 1840                                    zlog::warn!(
 1841                                        logger =>
 1842                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1843                                        buffer_path_abs.as_path(),
 1844                                        describe_code_action(&action),
 1845                                    );
 1846                                    continue 'actions;
 1847                                };
 1848                                edits.extend(resolved_edits);
 1849                            }
 1850
 1851                            if edits.is_empty() {
 1852                                zlog::warn!(logger => "No edits resolved from LSP");
 1853                                continue;
 1854                            }
 1855
 1856                            extend_formatting_transaction(
 1857                                buffer,
 1858                                formatting_transaction_id,
 1859                                cx,
 1860                                |buffer, cx| {
 1861                                    zlog::info!(
 1862                                        "Applying edits {edits:?}. Content: {:?}",
 1863                                        buffer.text()
 1864                                    );
 1865                                    buffer.edit(edits, None, cx);
 1866                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1867                                },
 1868                            )?;
 1869                        }
 1870
 1871                        if let Some(command) = action.lsp_action.command() {
 1872                            zlog::warn!(
 1873                                logger =>
 1874                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1875                                &command.command,
 1876                            );
 1877
 1878                            // bail early if command is invalid
 1879                            let server_capabilities = server.capabilities();
 1880                            let available_commands = server_capabilities
 1881                                .execute_command_provider
 1882                                .as_ref()
 1883                                .map(|options| options.commands.as_slice())
 1884                                .unwrap_or_default();
 1885                            if !available_commands.contains(&command.command) {
 1886                                zlog::warn!(
 1887                                    logger =>
 1888                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1889                                    command.command,
 1890                                    server.name(),
 1891                                );
 1892                                continue;
 1893                            }
 1894
 1895                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1896                            extend_formatting_transaction(
 1897                                buffer,
 1898                                formatting_transaction_id,
 1899                                cx,
 1900                                |_, _| {},
 1901                            )?;
 1902                            zlog::info!(logger => "Executing command {}", &command.command);
 1903
 1904                            lsp_store.update(cx, |this, _| {
 1905                                this.as_local_mut()
 1906                                    .unwrap()
 1907                                    .last_workspace_edits_by_language_server
 1908                                    .remove(&server.server_id());
 1909                            })?;
 1910
 1911                            let execute_command_result = server
 1912                                .request::<lsp::request::ExecuteCommand>(
 1913                                    lsp::ExecuteCommandParams {
 1914                                        command: command.command.clone(),
 1915                                        arguments: command.arguments.clone().unwrap_or_default(),
 1916                                        ..Default::default()
 1917                                    },
 1918                                )
 1919                                .await
 1920                                .into_response();
 1921
 1922                            if execute_command_result.is_err() {
 1923                                zlog::error!(
 1924                                    logger =>
 1925                                    "Failed to execute command '{}' as part of {}",
 1926                                    &command.command,
 1927                                    describe_code_action(&action),
 1928                                );
 1929                                continue 'actions;
 1930                            }
 1931
 1932                            let mut project_transaction_command =
 1933                                lsp_store.update(cx, |this, _| {
 1934                                    this.as_local_mut()
 1935                                        .unwrap()
 1936                                        .last_workspace_edits_by_language_server
 1937                                        .remove(&server.server_id())
 1938                                        .unwrap_or_default()
 1939                                })?;
 1940
 1941                            if let Some(transaction) =
 1942                                project_transaction_command.0.remove(&buffer.handle)
 1943                            {
 1944                                zlog::trace!(
 1945                                    logger =>
 1946                                    "Successfully captured {} edits that resulted from command {}",
 1947                                    transaction.edit_ids.len(),
 1948                                    &command.command,
 1949                                );
 1950                                let transaction_id_project_transaction = transaction.id;
 1951                                buffer.handle.update(cx, |buffer, _| {
 1952                                    // it may have been removed from history if push_to_history was
 1953                                    // false in deserialize_workspace_edit. If so push it so we
 1954                                    // can merge it with the format transaction
 1955                                    // and pop the combined transaction off the history stack
 1956                                    // later if push_to_history is false
 1957                                    if buffer.get_transaction(transaction.id).is_none() {
 1958                                        buffer.push_transaction(transaction, Instant::now());
 1959                                    }
 1960                                    buffer.merge_transactions(
 1961                                        transaction_id_project_transaction,
 1962                                        formatting_transaction_id,
 1963                                    );
 1964                                })?;
 1965                            }
 1966
 1967                            if !project_transaction_command.0.is_empty() {
 1968                                let mut extra_buffers = String::new();
 1969                                for buffer in project_transaction_command.0.keys() {
 1970                                    buffer
 1971                                        .read_with(cx, |b, cx| {
 1972                                            if let Some(path) = b.project_path(cx) {
 1973                                                if !extra_buffers.is_empty() {
 1974                                                    extra_buffers.push_str(", ");
 1975                                                }
 1976                                                extra_buffers.push_str(path.path.as_unix_str());
 1977                                            }
 1978                                        })
 1979                                        .ok();
 1980                                }
 1981                                zlog::warn!(
 1982                                    logger =>
 1983                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1984                                    &command.command,
 1985                                    extra_buffers,
 1986                                );
 1987                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1988                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1989                                // add it so it's included, and merge it into the format transaction when its created later
 1990                            }
 1991                        }
 1992                    }
 1993                }
 1994            }
 1995        }
 1996
 1997        Ok(())
 1998    }
 1999
 2000    pub async fn format_ranges_via_lsp(
 2001        this: &WeakEntity<LspStore>,
 2002        buffer_handle: &Entity<Buffer>,
 2003        ranges: &[Range<Anchor>],
 2004        abs_path: &Path,
 2005        language_server: &Arc<LanguageServer>,
 2006        settings: &LanguageSettings,
 2007        cx: &mut AsyncApp,
 2008    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2009        let capabilities = &language_server.capabilities();
 2010        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2011        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2012            anyhow::bail!(
 2013                "{} language server does not support range formatting",
 2014                language_server.name()
 2015            );
 2016        }
 2017
 2018        let uri = file_path_to_lsp_url(abs_path)?;
 2019        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2020
 2021        let lsp_edits = {
 2022            let mut lsp_ranges = Vec::new();
 2023            this.update(cx, |_this, cx| {
 2024                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2025                // not have been sent to the language server. This seems like a fairly systemic
 2026                // issue, though, the resolution probably is not specific to formatting.
 2027                //
 2028                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2029                // LSP.
 2030                let snapshot = buffer_handle.read(cx).snapshot();
 2031                for range in ranges {
 2032                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2033                }
 2034                anyhow::Ok(())
 2035            })??;
 2036
 2037            let mut edits = None;
 2038            for range in lsp_ranges {
 2039                if let Some(mut edit) = language_server
 2040                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2041                        text_document: text_document.clone(),
 2042                        range,
 2043                        options: lsp_command::lsp_formatting_options(settings),
 2044                        work_done_progress_params: Default::default(),
 2045                    })
 2046                    .await
 2047                    .into_response()?
 2048                {
 2049                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2050                }
 2051            }
 2052            edits
 2053        };
 2054
 2055        if let Some(lsp_edits) = lsp_edits {
 2056            this.update(cx, |this, cx| {
 2057                this.as_local_mut().unwrap().edits_from_lsp(
 2058                    buffer_handle,
 2059                    lsp_edits,
 2060                    language_server.server_id(),
 2061                    None,
 2062                    cx,
 2063                )
 2064            })?
 2065            .await
 2066        } else {
 2067            Ok(Vec::with_capacity(0))
 2068        }
 2069    }
 2070
 2071    async fn format_via_lsp(
 2072        this: &WeakEntity<LspStore>,
 2073        buffer: &Entity<Buffer>,
 2074        abs_path: &Path,
 2075        language_server: &Arc<LanguageServer>,
 2076        settings: &LanguageSettings,
 2077        cx: &mut AsyncApp,
 2078    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2079        let logger = zlog::scoped!("lsp_format");
 2080        zlog::debug!(logger => "Formatting via LSP");
 2081
 2082        let uri = file_path_to_lsp_url(abs_path)?;
 2083        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2084        let capabilities = &language_server.capabilities();
 2085
 2086        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2087        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2088
 2089        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2090            let _timer = zlog::time!(logger => "format-full");
 2091            language_server
 2092                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2093                    text_document,
 2094                    options: lsp_command::lsp_formatting_options(settings),
 2095                    work_done_progress_params: Default::default(),
 2096                })
 2097                .await
 2098                .into_response()?
 2099        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2100            let _timer = zlog::time!(logger => "format-range");
 2101            let buffer_start = lsp::Position::new(0, 0);
 2102            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2103            language_server
 2104                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2105                    text_document: text_document.clone(),
 2106                    range: lsp::Range::new(buffer_start, buffer_end),
 2107                    options: lsp_command::lsp_formatting_options(settings),
 2108                    work_done_progress_params: Default::default(),
 2109                })
 2110                .await
 2111                .into_response()?
 2112        } else {
 2113            None
 2114        };
 2115
 2116        if let Some(lsp_edits) = lsp_edits {
 2117            this.update(cx, |this, cx| {
 2118                this.as_local_mut().unwrap().edits_from_lsp(
 2119                    buffer,
 2120                    lsp_edits,
 2121                    language_server.server_id(),
 2122                    None,
 2123                    cx,
 2124                )
 2125            })?
 2126            .await
 2127        } else {
 2128            Ok(Vec::with_capacity(0))
 2129        }
 2130    }
 2131
 2132    async fn format_via_external_command(
 2133        buffer: &FormattableBuffer,
 2134        command: &str,
 2135        arguments: Option<&[String]>,
 2136        cx: &mut AsyncApp,
 2137    ) -> Result<Option<Diff>> {
 2138        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2139            let file = File::from_dyn(buffer.file())?;
 2140            let worktree = file.worktree.read(cx);
 2141            let mut worktree_path = worktree.abs_path().to_path_buf();
 2142            if worktree.root_entry()?.is_file() {
 2143                worktree_path.pop();
 2144            }
 2145            Some(worktree_path)
 2146        })?;
 2147
 2148        let mut child = util::command::new_smol_command(command);
 2149
 2150        if let Some(buffer_env) = buffer.env.as_ref() {
 2151            child.envs(buffer_env);
 2152        }
 2153
 2154        if let Some(working_dir_path) = working_dir_path {
 2155            child.current_dir(working_dir_path);
 2156        }
 2157
 2158        if let Some(arguments) = arguments {
 2159            child.args(arguments.iter().map(|arg| {
 2160                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2161                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2162                } else {
 2163                    arg.replace("{buffer_path}", "Untitled")
 2164                }
 2165            }));
 2166        }
 2167
 2168        let mut child = child
 2169            .stdin(smol::process::Stdio::piped())
 2170            .stdout(smol::process::Stdio::piped())
 2171            .stderr(smol::process::Stdio::piped())
 2172            .spawn()?;
 2173
 2174        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2175        let text = buffer
 2176            .handle
 2177            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2178        for chunk in text.chunks() {
 2179            stdin.write_all(chunk.as_bytes()).await?;
 2180        }
 2181        stdin.flush().await?;
 2182
 2183        let output = child.output().await?;
 2184        anyhow::ensure!(
 2185            output.status.success(),
 2186            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2187            output.status.code(),
 2188            String::from_utf8_lossy(&output.stdout),
 2189            String::from_utf8_lossy(&output.stderr),
 2190        );
 2191
 2192        let stdout = String::from_utf8(output.stdout)?;
 2193        Ok(Some(
 2194            buffer
 2195                .handle
 2196                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2197                .await,
 2198        ))
 2199    }
 2200
 2201    async fn try_resolve_code_action(
 2202        lang_server: &LanguageServer,
 2203        action: &mut CodeAction,
 2204    ) -> anyhow::Result<()> {
 2205        match &mut action.lsp_action {
 2206            LspAction::Action(lsp_action) => {
 2207                if !action.resolved
 2208                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2209                    && lsp_action.data.is_some()
 2210                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2211                {
 2212                    *lsp_action = Box::new(
 2213                        lang_server
 2214                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2215                            .await
 2216                            .into_response()?,
 2217                    );
 2218                }
 2219            }
 2220            LspAction::CodeLens(lens) => {
 2221                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2222                    *lens = lang_server
 2223                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2224                        .await
 2225                        .into_response()?;
 2226                }
 2227            }
 2228            LspAction::Command(_) => {}
 2229        }
 2230
 2231        action.resolved = true;
 2232        anyhow::Ok(())
 2233    }
 2234
 2235    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2236        let buffer = buffer_handle.read(cx);
 2237
 2238        let file = buffer.file().cloned();
 2239
 2240        let Some(file) = File::from_dyn(file.as_ref()) else {
 2241            return;
 2242        };
 2243        if !file.is_local() {
 2244            return;
 2245        }
 2246        let path = ProjectPath::from_file(file, cx);
 2247        let worktree_id = file.worktree_id(cx);
 2248        let language = buffer.language().cloned();
 2249
 2250        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2251            for (server_id, diagnostics) in
 2252                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2253            {
 2254                self.update_buffer_diagnostics(
 2255                    buffer_handle,
 2256                    server_id,
 2257                    None,
 2258                    None,
 2259                    diagnostics,
 2260                    Vec::new(),
 2261                    cx,
 2262                )
 2263                .log_err();
 2264            }
 2265        }
 2266        let Some(language) = language else {
 2267            return;
 2268        };
 2269        let Some(snapshot) = self
 2270            .worktree_store
 2271            .read(cx)
 2272            .worktree_for_id(worktree_id, cx)
 2273            .map(|worktree| worktree.read(cx).snapshot())
 2274        else {
 2275            return;
 2276        };
 2277        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2278
 2279        for server_id in
 2280            self.lsp_tree
 2281                .get(path, language.name(), language.manifest(), &delegate, cx)
 2282        {
 2283            let server = self
 2284                .language_servers
 2285                .get(&server_id)
 2286                .and_then(|server_state| {
 2287                    if let LanguageServerState::Running { server, .. } = server_state {
 2288                        Some(server.clone())
 2289                    } else {
 2290                        None
 2291                    }
 2292                });
 2293            let server = match server {
 2294                Some(server) => server,
 2295                None => continue,
 2296            };
 2297
 2298            buffer_handle.update(cx, |buffer, cx| {
 2299                buffer.set_completion_triggers(
 2300                    server.server_id(),
 2301                    server
 2302                        .capabilities()
 2303                        .completion_provider
 2304                        .as_ref()
 2305                        .and_then(|provider| {
 2306                            provider
 2307                                .trigger_characters
 2308                                .as_ref()
 2309                                .map(|characters| characters.iter().cloned().collect())
 2310                        })
 2311                        .unwrap_or_default(),
 2312                    cx,
 2313                );
 2314            });
 2315        }
 2316    }
 2317
 2318    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2319        buffer.update(cx, |buffer, cx| {
 2320            let Some(language) = buffer.language() else {
 2321                return;
 2322            };
 2323            let path = ProjectPath {
 2324                worktree_id: old_file.worktree_id(cx),
 2325                path: old_file.path.clone(),
 2326            };
 2327            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2328                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2329                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2330            }
 2331        });
 2332    }
 2333
 2334    fn update_buffer_diagnostics(
 2335        &mut self,
 2336        buffer: &Entity<Buffer>,
 2337        server_id: LanguageServerId,
 2338        result_id: Option<String>,
 2339        version: Option<i32>,
 2340        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2341        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2342        cx: &mut Context<LspStore>,
 2343    ) -> Result<()> {
 2344        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2345            Ordering::Equal
 2346                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2347                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2348                .then_with(|| a.severity.cmp(&b.severity))
 2349                .then_with(|| a.message.cmp(&b.message))
 2350        }
 2351
 2352        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2353        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2354        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2355
 2356        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2357            Ordering::Equal
 2358                .then_with(|| a.range.start.cmp(&b.range.start))
 2359                .then_with(|| b.range.end.cmp(&a.range.end))
 2360                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2361        });
 2362
 2363        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2364
 2365        let edits_since_save = std::cell::LazyCell::new(|| {
 2366            let saved_version = buffer.read(cx).saved_version();
 2367            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2368        });
 2369
 2370        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2371
 2372        for (new_diagnostic, entry) in diagnostics {
 2373            let start;
 2374            let end;
 2375            if new_diagnostic && entry.diagnostic.is_disk_based {
 2376                // Some diagnostics are based on files on disk instead of buffers'
 2377                // current contents. Adjust these diagnostics' ranges to reflect
 2378                // any unsaved edits.
 2379                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2380                // and were properly adjusted on reuse.
 2381                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2382                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2383            } else {
 2384                start = entry.range.start;
 2385                end = entry.range.end;
 2386            }
 2387
 2388            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2389                ..snapshot.clip_point_utf16(end, Bias::Right);
 2390
 2391            // Expand empty ranges by one codepoint
 2392            if range.start == range.end {
 2393                // This will be go to the next boundary when being clipped
 2394                range.end.column += 1;
 2395                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2396                if range.start == range.end && range.end.column > 0 {
 2397                    range.start.column -= 1;
 2398                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2399                }
 2400            }
 2401
 2402            sanitized_diagnostics.push(DiagnosticEntry {
 2403                range,
 2404                diagnostic: entry.diagnostic,
 2405            });
 2406        }
 2407        drop(edits_since_save);
 2408
 2409        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2410        buffer.update(cx, |buffer, cx| {
 2411            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2412                self.buffer_pull_diagnostics_result_ids
 2413                    .entry(server_id)
 2414                    .or_default()
 2415                    .insert(abs_path, result_id);
 2416            }
 2417
 2418            buffer.update_diagnostics(server_id, set, cx)
 2419        });
 2420
 2421        Ok(())
 2422    }
 2423
 2424    fn register_language_server_for_invisible_worktree(
 2425        &mut self,
 2426        worktree: &Entity<Worktree>,
 2427        language_server_id: LanguageServerId,
 2428        cx: &mut App,
 2429    ) {
 2430        let worktree = worktree.read(cx);
 2431        let worktree_id = worktree.id();
 2432        debug_assert!(!worktree.is_visible());
 2433        let Some(mut origin_seed) = self
 2434            .language_server_ids
 2435            .iter()
 2436            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2437        else {
 2438            return;
 2439        };
 2440        origin_seed.worktree_id = worktree_id;
 2441        self.language_server_ids
 2442            .entry(origin_seed)
 2443            .or_insert_with(|| UnifiedLanguageServer {
 2444                id: language_server_id,
 2445                project_roots: Default::default(),
 2446            });
 2447    }
 2448
 2449    fn register_buffer_with_language_servers(
 2450        &mut self,
 2451        buffer_handle: &Entity<Buffer>,
 2452        only_register_servers: HashSet<LanguageServerSelector>,
 2453        cx: &mut Context<LspStore>,
 2454    ) {
 2455        let buffer = buffer_handle.read(cx);
 2456        let buffer_id = buffer.remote_id();
 2457
 2458        let Some(file) = File::from_dyn(buffer.file()) else {
 2459            return;
 2460        };
 2461        if !file.is_local() {
 2462            return;
 2463        }
 2464
 2465        let abs_path = file.abs_path(cx);
 2466        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2467            return;
 2468        };
 2469        let initial_snapshot = buffer.text_snapshot();
 2470        let worktree_id = file.worktree_id(cx);
 2471
 2472        let Some(language) = buffer.language().cloned() else {
 2473            return;
 2474        };
 2475        let path: Arc<RelPath> = file
 2476            .path()
 2477            .parent()
 2478            .map(Arc::from)
 2479            .unwrap_or_else(|| file.path().clone());
 2480        let Some(worktree) = self
 2481            .worktree_store
 2482            .read(cx)
 2483            .worktree_for_id(worktree_id, cx)
 2484        else {
 2485            return;
 2486        };
 2487        let language_name = language.name();
 2488        let (reused, delegate, servers) = self
 2489            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2490            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2491            .unwrap_or_else(|| {
 2492                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2493                let delegate: Arc<dyn ManifestDelegate> =
 2494                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2495
 2496                let servers = self
 2497                    .lsp_tree
 2498                    .walk(
 2499                        ProjectPath { worktree_id, path },
 2500                        language.name(),
 2501                        language.manifest(),
 2502                        &delegate,
 2503                        cx,
 2504                    )
 2505                    .collect::<Vec<_>>();
 2506                (false, lsp_delegate, servers)
 2507            });
 2508        let servers_and_adapters = servers
 2509            .into_iter()
 2510            .filter_map(|server_node| {
 2511                if reused && server_node.server_id().is_none() {
 2512                    return None;
 2513                }
 2514                if !only_register_servers.is_empty() {
 2515                    if let Some(server_id) = server_node.server_id()
 2516                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2517                    {
 2518                        return None;
 2519                    }
 2520                    if let Some(name) = server_node.name()
 2521                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2522                    {
 2523                        return None;
 2524                    }
 2525                }
 2526
 2527                let server_id = server_node.server_id_or_init(|disposition| {
 2528                    let path = &disposition.path;
 2529
 2530                    {
 2531                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2532
 2533                        let server_id = self.get_or_insert_language_server(
 2534                            &worktree,
 2535                            delegate.clone(),
 2536                            disposition,
 2537                            &language_name,
 2538                            cx,
 2539                        );
 2540
 2541                        if let Some(state) = self.language_servers.get(&server_id)
 2542                            && let Ok(uri) = uri
 2543                        {
 2544                            state.add_workspace_folder(uri);
 2545                        };
 2546                        server_id
 2547                    }
 2548                })?;
 2549                let server_state = self.language_servers.get(&server_id)?;
 2550                if let LanguageServerState::Running {
 2551                    server, adapter, ..
 2552                } = server_state
 2553                {
 2554                    Some((server.clone(), adapter.clone()))
 2555                } else {
 2556                    None
 2557                }
 2558            })
 2559            .collect::<Vec<_>>();
 2560        for (server, adapter) in servers_and_adapters {
 2561            buffer_handle.update(cx, |buffer, cx| {
 2562                buffer.set_completion_triggers(
 2563                    server.server_id(),
 2564                    server
 2565                        .capabilities()
 2566                        .completion_provider
 2567                        .as_ref()
 2568                        .and_then(|provider| {
 2569                            provider
 2570                                .trigger_characters
 2571                                .as_ref()
 2572                                .map(|characters| characters.iter().cloned().collect())
 2573                        })
 2574                        .unwrap_or_default(),
 2575                    cx,
 2576                );
 2577            });
 2578
 2579            let snapshot = LspBufferSnapshot {
 2580                version: 0,
 2581                snapshot: initial_snapshot.clone(),
 2582            };
 2583
 2584            let mut registered = false;
 2585            self.buffer_snapshots
 2586                .entry(buffer_id)
 2587                .or_default()
 2588                .entry(server.server_id())
 2589                .or_insert_with(|| {
 2590                    registered = true;
 2591                    server.register_buffer(
 2592                        uri.clone(),
 2593                        adapter.language_id(&language.name()),
 2594                        0,
 2595                        initial_snapshot.text(),
 2596                    );
 2597
 2598                    vec![snapshot]
 2599                });
 2600
 2601            self.buffers_opened_in_servers
 2602                .entry(buffer_id)
 2603                .or_default()
 2604                .insert(server.server_id());
 2605            if registered {
 2606                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2607                    language_server_id: server.server_id(),
 2608                    name: None,
 2609                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2610                        proto::RegisteredForBuffer {
 2611                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2612                            buffer_id: buffer_id.to_proto(),
 2613                        },
 2614                    ),
 2615                });
 2616            }
 2617        }
 2618    }
 2619
 2620    fn reuse_existing_language_server<'lang_name>(
 2621        &self,
 2622        server_tree: &LanguageServerTree,
 2623        worktree: &Entity<Worktree>,
 2624        language_name: &'lang_name LanguageName,
 2625        cx: &mut App,
 2626    ) -> Option<(
 2627        Arc<LocalLspAdapterDelegate>,
 2628        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2629    )> {
 2630        if worktree.read(cx).is_visible() {
 2631            return None;
 2632        }
 2633
 2634        let worktree_store = self.worktree_store.read(cx);
 2635        let servers = server_tree
 2636            .instances
 2637            .iter()
 2638            .filter(|(worktree_id, _)| {
 2639                worktree_store
 2640                    .worktree_for_id(**worktree_id, cx)
 2641                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2642            })
 2643            .flat_map(|(worktree_id, servers)| {
 2644                servers
 2645                    .roots
 2646                    .iter()
 2647                    .flat_map(|(_, language_servers)| language_servers)
 2648                    .map(move |(_, (server_node, server_languages))| {
 2649                        (worktree_id, server_node, server_languages)
 2650                    })
 2651                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2652                    .map(|(worktree_id, server_node, _)| {
 2653                        (
 2654                            *worktree_id,
 2655                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2656                        )
 2657                    })
 2658            })
 2659            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2660                acc.entry(worktree_id)
 2661                    .or_insert_with(Vec::new)
 2662                    .push(server_node);
 2663                acc
 2664            })
 2665            .into_values()
 2666            .max_by_key(|servers| servers.len())?;
 2667
 2668        let worktree_id = worktree.read(cx).id();
 2669        let apply = move |tree: &mut LanguageServerTree| {
 2670            for server_node in &servers {
 2671                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2672            }
 2673            servers
 2674        };
 2675
 2676        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2677        Some((delegate, apply))
 2678    }
 2679
 2680    pub(crate) fn unregister_old_buffer_from_language_servers(
 2681        &mut self,
 2682        buffer: &Entity<Buffer>,
 2683        old_file: &File,
 2684        cx: &mut App,
 2685    ) {
 2686        let old_path = match old_file.as_local() {
 2687            Some(local) => local.abs_path(cx),
 2688            None => return,
 2689        };
 2690
 2691        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2692            debug_panic!("{old_path:?} is not parseable as an URI");
 2693            return;
 2694        };
 2695        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2696    }
 2697
 2698    pub(crate) fn unregister_buffer_from_language_servers(
 2699        &mut self,
 2700        buffer: &Entity<Buffer>,
 2701        file_url: &lsp::Uri,
 2702        cx: &mut App,
 2703    ) {
 2704        buffer.update(cx, |buffer, cx| {
 2705            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2706
 2707            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2708                if snapshots
 2709                    .as_mut()
 2710                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2711                {
 2712                    language_server.unregister_buffer(file_url.clone());
 2713                }
 2714            }
 2715        });
 2716    }
 2717
 2718    fn buffer_snapshot_for_lsp_version(
 2719        &mut self,
 2720        buffer: &Entity<Buffer>,
 2721        server_id: LanguageServerId,
 2722        version: Option<i32>,
 2723        cx: &App,
 2724    ) -> Result<TextBufferSnapshot> {
 2725        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2726
 2727        if let Some(version) = version {
 2728            let buffer_id = buffer.read(cx).remote_id();
 2729            let snapshots = if let Some(snapshots) = self
 2730                .buffer_snapshots
 2731                .get_mut(&buffer_id)
 2732                .and_then(|m| m.get_mut(&server_id))
 2733            {
 2734                snapshots
 2735            } else if version == 0 {
 2736                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2737                // We detect this case and treat it as if the version was `None`.
 2738                return Ok(buffer.read(cx).text_snapshot());
 2739            } else {
 2740                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2741            };
 2742
 2743            let found_snapshot = snapshots
 2744                    .binary_search_by_key(&version, |e| e.version)
 2745                    .map(|ix| snapshots[ix].snapshot.clone())
 2746                    .map_err(|_| {
 2747                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2748                    })?;
 2749
 2750            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2751            Ok(found_snapshot)
 2752        } else {
 2753            Ok((buffer.read(cx)).text_snapshot())
 2754        }
 2755    }
 2756
 2757    async fn get_server_code_actions_from_action_kinds(
 2758        lsp_store: &WeakEntity<LspStore>,
 2759        language_server_id: LanguageServerId,
 2760        code_action_kinds: Vec<lsp::CodeActionKind>,
 2761        buffer: &Entity<Buffer>,
 2762        cx: &mut AsyncApp,
 2763    ) -> Result<Vec<CodeAction>> {
 2764        let actions = lsp_store
 2765            .update(cx, move |this, cx| {
 2766                let request = GetCodeActions {
 2767                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2768                    kinds: Some(code_action_kinds),
 2769                };
 2770                let server = LanguageServerToQuery::Other(language_server_id);
 2771                this.request_lsp(buffer.clone(), server, request, cx)
 2772            })?
 2773            .await?;
 2774        Ok(actions)
 2775    }
 2776
 2777    pub async fn execute_code_actions_on_server(
 2778        lsp_store: &WeakEntity<LspStore>,
 2779        language_server: &Arc<LanguageServer>,
 2780
 2781        actions: Vec<CodeAction>,
 2782        push_to_history: bool,
 2783        project_transaction: &mut ProjectTransaction,
 2784        cx: &mut AsyncApp,
 2785    ) -> anyhow::Result<()> {
 2786        for mut action in actions {
 2787            Self::try_resolve_code_action(language_server, &mut action)
 2788                .await
 2789                .context("resolving a formatting code action")?;
 2790
 2791            if let Some(edit) = action.lsp_action.edit() {
 2792                if edit.changes.is_none() && edit.document_changes.is_none() {
 2793                    continue;
 2794                }
 2795
 2796                let new = Self::deserialize_workspace_edit(
 2797                    lsp_store.upgrade().context("project dropped")?,
 2798                    edit.clone(),
 2799                    push_to_history,
 2800                    language_server.clone(),
 2801                    cx,
 2802                )
 2803                .await?;
 2804                project_transaction.0.extend(new.0);
 2805            }
 2806
 2807            if let Some(command) = action.lsp_action.command() {
 2808                let server_capabilities = language_server.capabilities();
 2809                let available_commands = server_capabilities
 2810                    .execute_command_provider
 2811                    .as_ref()
 2812                    .map(|options| options.commands.as_slice())
 2813                    .unwrap_or_default();
 2814                if available_commands.contains(&command.command) {
 2815                    lsp_store.update(cx, |lsp_store, _| {
 2816                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2817                            mode.last_workspace_edits_by_language_server
 2818                                .remove(&language_server.server_id());
 2819                        }
 2820                    })?;
 2821
 2822                    language_server
 2823                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2824                            command: command.command.clone(),
 2825                            arguments: command.arguments.clone().unwrap_or_default(),
 2826                            ..Default::default()
 2827                        })
 2828                        .await
 2829                        .into_response()
 2830                        .context("execute command")?;
 2831
 2832                    lsp_store.update(cx, |this, _| {
 2833                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2834                            project_transaction.0.extend(
 2835                                mode.last_workspace_edits_by_language_server
 2836                                    .remove(&language_server.server_id())
 2837                                    .unwrap_or_default()
 2838                                    .0,
 2839                            )
 2840                        }
 2841                    })?;
 2842                } else {
 2843                    log::warn!(
 2844                        "Cannot execute a command {} not listed in the language server capabilities",
 2845                        command.command
 2846                    )
 2847                }
 2848            }
 2849        }
 2850        Ok(())
 2851    }
 2852
 2853    pub async fn deserialize_text_edits(
 2854        this: Entity<LspStore>,
 2855        buffer_to_edit: Entity<Buffer>,
 2856        edits: Vec<lsp::TextEdit>,
 2857        push_to_history: bool,
 2858        _: Arc<CachedLspAdapter>,
 2859        language_server: Arc<LanguageServer>,
 2860        cx: &mut AsyncApp,
 2861    ) -> Result<Option<Transaction>> {
 2862        let edits = this
 2863            .update(cx, |this, cx| {
 2864                this.as_local_mut().unwrap().edits_from_lsp(
 2865                    &buffer_to_edit,
 2866                    edits,
 2867                    language_server.server_id(),
 2868                    None,
 2869                    cx,
 2870                )
 2871            })?
 2872            .await?;
 2873
 2874        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2875            buffer.finalize_last_transaction();
 2876            buffer.start_transaction();
 2877            for (range, text) in edits {
 2878                buffer.edit([(range, text)], None, cx);
 2879            }
 2880
 2881            if buffer.end_transaction(cx).is_some() {
 2882                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2883                if !push_to_history {
 2884                    buffer.forget_transaction(transaction.id);
 2885                }
 2886                Some(transaction)
 2887            } else {
 2888                None
 2889            }
 2890        })?;
 2891
 2892        Ok(transaction)
 2893    }
 2894
 2895    #[allow(clippy::type_complexity)]
 2896    pub(crate) fn edits_from_lsp(
 2897        &mut self,
 2898        buffer: &Entity<Buffer>,
 2899        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2900        server_id: LanguageServerId,
 2901        version: Option<i32>,
 2902        cx: &mut Context<LspStore>,
 2903    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2904        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2905        cx.background_spawn(async move {
 2906            let snapshot = snapshot?;
 2907            let mut lsp_edits = lsp_edits
 2908                .into_iter()
 2909                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2910                .collect::<Vec<_>>();
 2911
 2912            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2913
 2914            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2915            let mut edits = Vec::new();
 2916            while let Some((range, mut new_text)) = lsp_edits.next() {
 2917                // Clip invalid ranges provided by the language server.
 2918                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2919                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2920
 2921                // Combine any LSP edits that are adjacent.
 2922                //
 2923                // Also, combine LSP edits that are separated from each other by only
 2924                // a newline. This is important because for some code actions,
 2925                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2926                // are separated by unchanged newline characters.
 2927                //
 2928                // In order for the diffing logic below to work properly, any edits that
 2929                // cancel each other out must be combined into one.
 2930                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2931                    if next_range.start.0 > range.end {
 2932                        if next_range.start.0.row > range.end.row + 1
 2933                            || next_range.start.0.column > 0
 2934                            || snapshot.clip_point_utf16(
 2935                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2936                                Bias::Left,
 2937                            ) > range.end
 2938                        {
 2939                            break;
 2940                        }
 2941                        new_text.push('\n');
 2942                    }
 2943                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2944                    new_text.push_str(next_text);
 2945                    lsp_edits.next();
 2946                }
 2947
 2948                // For multiline edits, perform a diff of the old and new text so that
 2949                // we can identify the changes more precisely, preserving the locations
 2950                // of any anchors positioned in the unchanged regions.
 2951                if range.end.row > range.start.row {
 2952                    let offset = range.start.to_offset(&snapshot);
 2953                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2954                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2955                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2956                        (
 2957                            snapshot.anchor_after(offset + range.start)
 2958                                ..snapshot.anchor_before(offset + range.end),
 2959                            replacement,
 2960                        )
 2961                    }));
 2962                } else if range.end == range.start {
 2963                    let anchor = snapshot.anchor_after(range.start);
 2964                    edits.push((anchor..anchor, new_text.into()));
 2965                } else {
 2966                    let edit_start = snapshot.anchor_after(range.start);
 2967                    let edit_end = snapshot.anchor_before(range.end);
 2968                    edits.push((edit_start..edit_end, new_text.into()));
 2969                }
 2970            }
 2971
 2972            Ok(edits)
 2973        })
 2974    }
 2975
 2976    pub(crate) async fn deserialize_workspace_edit(
 2977        this: Entity<LspStore>,
 2978        edit: lsp::WorkspaceEdit,
 2979        push_to_history: bool,
 2980        language_server: Arc<LanguageServer>,
 2981        cx: &mut AsyncApp,
 2982    ) -> Result<ProjectTransaction> {
 2983        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2984
 2985        let mut operations = Vec::new();
 2986        if let Some(document_changes) = edit.document_changes {
 2987            match document_changes {
 2988                lsp::DocumentChanges::Edits(edits) => {
 2989                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2990                }
 2991                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2992            }
 2993        } else if let Some(changes) = edit.changes {
 2994            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2995                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2996                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2997                        uri,
 2998                        version: None,
 2999                    },
 3000                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3001                })
 3002            }));
 3003        }
 3004
 3005        let mut project_transaction = ProjectTransaction::default();
 3006        for operation in operations {
 3007            match operation {
 3008                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3009                    let abs_path = op
 3010                        .uri
 3011                        .to_file_path()
 3012                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3013
 3014                    if let Some(parent_path) = abs_path.parent() {
 3015                        fs.create_dir(parent_path).await?;
 3016                    }
 3017                    if abs_path.ends_with("/") {
 3018                        fs.create_dir(&abs_path).await?;
 3019                    } else {
 3020                        fs.create_file(
 3021                            &abs_path,
 3022                            op.options
 3023                                .map(|options| fs::CreateOptions {
 3024                                    overwrite: options.overwrite.unwrap_or(false),
 3025                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3026                                })
 3027                                .unwrap_or_default(),
 3028                        )
 3029                        .await?;
 3030                    }
 3031                }
 3032
 3033                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3034                    let source_abs_path = op
 3035                        .old_uri
 3036                        .to_file_path()
 3037                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3038                    let target_abs_path = op
 3039                        .new_uri
 3040                        .to_file_path()
 3041                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3042
 3043                    let options = fs::RenameOptions {
 3044                        overwrite: op
 3045                            .options
 3046                            .as_ref()
 3047                            .and_then(|options| options.overwrite)
 3048                            .unwrap_or(false),
 3049                        ignore_if_exists: op
 3050                            .options
 3051                            .as_ref()
 3052                            .and_then(|options| options.ignore_if_exists)
 3053                            .unwrap_or(false),
 3054                        create_parents: true,
 3055                    };
 3056
 3057                    fs.rename(&source_abs_path, &target_abs_path, options)
 3058                        .await?;
 3059                }
 3060
 3061                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3062                    let abs_path = op
 3063                        .uri
 3064                        .to_file_path()
 3065                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3066                    let options = op
 3067                        .options
 3068                        .map(|options| fs::RemoveOptions {
 3069                            recursive: options.recursive.unwrap_or(false),
 3070                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3071                        })
 3072                        .unwrap_or_default();
 3073                    if abs_path.ends_with("/") {
 3074                        fs.remove_dir(&abs_path, options).await?;
 3075                    } else {
 3076                        fs.remove_file(&abs_path, options).await?;
 3077                    }
 3078                }
 3079
 3080                lsp::DocumentChangeOperation::Edit(op) => {
 3081                    let buffer_to_edit = this
 3082                        .update(cx, |this, cx| {
 3083                            this.open_local_buffer_via_lsp(
 3084                                op.text_document.uri.clone(),
 3085                                language_server.server_id(),
 3086                                cx,
 3087                            )
 3088                        })?
 3089                        .await?;
 3090
 3091                    let edits = this
 3092                        .update(cx, |this, cx| {
 3093                            let path = buffer_to_edit.read(cx).project_path(cx);
 3094                            let active_entry = this.active_entry;
 3095                            let is_active_entry = path.is_some_and(|project_path| {
 3096                                this.worktree_store
 3097                                    .read(cx)
 3098                                    .entry_for_path(&project_path, cx)
 3099                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3100                            });
 3101                            let local = this.as_local_mut().unwrap();
 3102
 3103                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3104                            for edit in op.edits {
 3105                                match edit {
 3106                                    Edit::Plain(edit) => {
 3107                                        if !edits.contains(&edit) {
 3108                                            edits.push(edit)
 3109                                        }
 3110                                    }
 3111                                    Edit::Annotated(edit) => {
 3112                                        if !edits.contains(&edit.text_edit) {
 3113                                            edits.push(edit.text_edit)
 3114                                        }
 3115                                    }
 3116                                    Edit::Snippet(edit) => {
 3117                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3118                                        else {
 3119                                            continue;
 3120                                        };
 3121
 3122                                        if is_active_entry {
 3123                                            snippet_edits.push((edit.range, snippet));
 3124                                        } else {
 3125                                            // Since this buffer is not focused, apply a normal edit.
 3126                                            let new_edit = TextEdit {
 3127                                                range: edit.range,
 3128                                                new_text: snippet.text,
 3129                                            };
 3130                                            if !edits.contains(&new_edit) {
 3131                                                edits.push(new_edit);
 3132                                            }
 3133                                        }
 3134                                    }
 3135                                }
 3136                            }
 3137                            if !snippet_edits.is_empty() {
 3138                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3139                                let version = if let Some(buffer_version) = op.text_document.version
 3140                                {
 3141                                    local
 3142                                        .buffer_snapshot_for_lsp_version(
 3143                                            &buffer_to_edit,
 3144                                            language_server.server_id(),
 3145                                            Some(buffer_version),
 3146                                            cx,
 3147                                        )
 3148                                        .ok()
 3149                                        .map(|snapshot| snapshot.version)
 3150                                } else {
 3151                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3152                                };
 3153
 3154                                let most_recent_edit =
 3155                                    version.and_then(|version| version.most_recent());
 3156                                // Check if the edit that triggered that edit has been made by this participant.
 3157
 3158                                if let Some(most_recent_edit) = most_recent_edit {
 3159                                    cx.emit(LspStoreEvent::SnippetEdit {
 3160                                        buffer_id,
 3161                                        edits: snippet_edits,
 3162                                        most_recent_edit,
 3163                                    });
 3164                                }
 3165                            }
 3166
 3167                            local.edits_from_lsp(
 3168                                &buffer_to_edit,
 3169                                edits,
 3170                                language_server.server_id(),
 3171                                op.text_document.version,
 3172                                cx,
 3173                            )
 3174                        })?
 3175                        .await?;
 3176
 3177                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3178                        buffer.finalize_last_transaction();
 3179                        buffer.start_transaction();
 3180                        for (range, text) in edits {
 3181                            buffer.edit([(range, text)], None, cx);
 3182                        }
 3183
 3184                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3185                            if push_to_history {
 3186                                buffer.finalize_last_transaction();
 3187                                buffer.get_transaction(transaction_id).cloned()
 3188                            } else {
 3189                                buffer.forget_transaction(transaction_id)
 3190                            }
 3191                        })
 3192                    })?;
 3193                    if let Some(transaction) = transaction {
 3194                        project_transaction.0.insert(buffer_to_edit, transaction);
 3195                    }
 3196                }
 3197            }
 3198        }
 3199
 3200        Ok(project_transaction)
 3201    }
 3202
 3203    async fn on_lsp_workspace_edit(
 3204        this: WeakEntity<LspStore>,
 3205        params: lsp::ApplyWorkspaceEditParams,
 3206        server_id: LanguageServerId,
 3207        cx: &mut AsyncApp,
 3208    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3209        let this = this.upgrade().context("project project closed")?;
 3210        let language_server = this
 3211            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3212            .context("language server not found")?;
 3213        let transaction = Self::deserialize_workspace_edit(
 3214            this.clone(),
 3215            params.edit,
 3216            true,
 3217            language_server.clone(),
 3218            cx,
 3219        )
 3220        .await
 3221        .log_err();
 3222        this.update(cx, |this, _| {
 3223            if let Some(transaction) = transaction {
 3224                this.as_local_mut()
 3225                    .unwrap()
 3226                    .last_workspace_edits_by_language_server
 3227                    .insert(server_id, transaction);
 3228            }
 3229        })?;
 3230        Ok(lsp::ApplyWorkspaceEditResponse {
 3231            applied: true,
 3232            failed_change: None,
 3233            failure_reason: None,
 3234        })
 3235    }
 3236
 3237    fn remove_worktree(
 3238        &mut self,
 3239        id_to_remove: WorktreeId,
 3240        cx: &mut Context<LspStore>,
 3241    ) -> Vec<LanguageServerId> {
 3242        self.diagnostics.remove(&id_to_remove);
 3243        self.prettier_store.update(cx, |prettier_store, cx| {
 3244            prettier_store.remove_worktree(id_to_remove, cx);
 3245        });
 3246
 3247        let mut servers_to_remove = BTreeSet::default();
 3248        let mut servers_to_preserve = HashSet::default();
 3249        for (seed, state) in &self.language_server_ids {
 3250            if seed.worktree_id == id_to_remove {
 3251                servers_to_remove.insert(state.id);
 3252            } else {
 3253                servers_to_preserve.insert(state.id);
 3254            }
 3255        }
 3256        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3257        self.language_server_ids
 3258            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3259        for server_id_to_remove in &servers_to_remove {
 3260            self.language_server_watched_paths
 3261                .remove(server_id_to_remove);
 3262            self.language_server_paths_watched_for_rename
 3263                .remove(server_id_to_remove);
 3264            self.last_workspace_edits_by_language_server
 3265                .remove(server_id_to_remove);
 3266            self.language_servers.remove(server_id_to_remove);
 3267            self.buffer_pull_diagnostics_result_ids
 3268                .remove(server_id_to_remove);
 3269            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3270                buffer_servers.remove(server_id_to_remove);
 3271            }
 3272            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3273        }
 3274        servers_to_remove.into_iter().collect()
 3275    }
 3276
 3277    fn rebuild_watched_paths_inner<'a>(
 3278        &'a self,
 3279        language_server_id: LanguageServerId,
 3280        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3281        cx: &mut Context<LspStore>,
 3282    ) -> LanguageServerWatchedPathsBuilder {
 3283        let worktrees = self
 3284            .worktree_store
 3285            .read(cx)
 3286            .worktrees()
 3287            .filter_map(|worktree| {
 3288                self.language_servers_for_worktree(worktree.read(cx).id())
 3289                    .find(|server| server.server_id() == language_server_id)
 3290                    .map(|_| worktree)
 3291            })
 3292            .collect::<Vec<_>>();
 3293
 3294        let mut worktree_globs = HashMap::default();
 3295        let mut abs_globs = HashMap::default();
 3296        log::trace!(
 3297            "Processing new watcher paths for language server with id {}",
 3298            language_server_id
 3299        );
 3300
 3301        for watcher in watchers {
 3302            if let Some((worktree, literal_prefix, pattern)) =
 3303                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3304            {
 3305                worktree.update(cx, |worktree, _| {
 3306                    if let Some((tree, glob)) =
 3307                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3308                    {
 3309                        tree.add_path_prefix_to_scan(literal_prefix);
 3310                        worktree_globs
 3311                            .entry(tree.id())
 3312                            .or_insert_with(GlobSetBuilder::new)
 3313                            .add(glob);
 3314                    }
 3315                });
 3316            } else {
 3317                let (path, pattern) = match &watcher.glob_pattern {
 3318                    lsp::GlobPattern::String(s) => {
 3319                        let watcher_path = SanitizedPath::new(s);
 3320                        let path = glob_literal_prefix(watcher_path.as_path());
 3321                        let pattern = watcher_path
 3322                            .as_path()
 3323                            .strip_prefix(&path)
 3324                            .map(|p| p.to_string_lossy().into_owned())
 3325                            .unwrap_or_else(|e| {
 3326                                debug_panic!(
 3327                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3328                                    s,
 3329                                    path.display(),
 3330                                    e
 3331                                );
 3332                                watcher_path.as_path().to_string_lossy().into_owned()
 3333                            });
 3334                        (path, pattern)
 3335                    }
 3336                    lsp::GlobPattern::Relative(rp) => {
 3337                        let Ok(mut base_uri) = match &rp.base_uri {
 3338                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3339                            lsp::OneOf::Right(base_uri) => base_uri,
 3340                        }
 3341                        .to_file_path() else {
 3342                            continue;
 3343                        };
 3344
 3345                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3346                        let pattern = Path::new(&rp.pattern)
 3347                            .strip_prefix(&path)
 3348                            .map(|p| p.to_string_lossy().into_owned())
 3349                            .unwrap_or_else(|e| {
 3350                                debug_panic!(
 3351                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3352                                    rp.pattern,
 3353                                    path.display(),
 3354                                    e
 3355                                );
 3356                                rp.pattern.clone()
 3357                            });
 3358                        base_uri.push(path);
 3359                        (base_uri, pattern)
 3360                    }
 3361                };
 3362
 3363                if let Some(glob) = Glob::new(&pattern).log_err() {
 3364                    if !path
 3365                        .components()
 3366                        .any(|c| matches!(c, path::Component::Normal(_)))
 3367                    {
 3368                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3369                        // rather than adding a new watcher for `/`.
 3370                        for worktree in &worktrees {
 3371                            worktree_globs
 3372                                .entry(worktree.read(cx).id())
 3373                                .or_insert_with(GlobSetBuilder::new)
 3374                                .add(glob.clone());
 3375                        }
 3376                    } else {
 3377                        abs_globs
 3378                            .entry(path.into())
 3379                            .or_insert_with(GlobSetBuilder::new)
 3380                            .add(glob);
 3381                    }
 3382                }
 3383            }
 3384        }
 3385
 3386        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3387        for (worktree_id, builder) in worktree_globs {
 3388            if let Ok(globset) = builder.build() {
 3389                watch_builder.watch_worktree(worktree_id, globset);
 3390            }
 3391        }
 3392        for (abs_path, builder) in abs_globs {
 3393            if let Ok(globset) = builder.build() {
 3394                watch_builder.watch_abs_path(abs_path, globset);
 3395            }
 3396        }
 3397        watch_builder
 3398    }
 3399
 3400    fn worktree_and_path_for_file_watcher(
 3401        worktrees: &[Entity<Worktree>],
 3402        watcher: &FileSystemWatcher,
 3403        cx: &App,
 3404    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3405        worktrees.iter().find_map(|worktree| {
 3406            let tree = worktree.read(cx);
 3407            let worktree_root_path = tree.abs_path();
 3408            let path_style = tree.path_style();
 3409            match &watcher.glob_pattern {
 3410                lsp::GlobPattern::String(s) => {
 3411                    let watcher_path = SanitizedPath::new(s);
 3412                    let relative = watcher_path
 3413                        .as_path()
 3414                        .strip_prefix(&worktree_root_path)
 3415                        .ok()?;
 3416                    let literal_prefix = glob_literal_prefix(relative);
 3417                    Some((
 3418                        worktree.clone(),
 3419                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3420                        relative.to_string_lossy().into_owned(),
 3421                    ))
 3422                }
 3423                lsp::GlobPattern::Relative(rp) => {
 3424                    let base_uri = match &rp.base_uri {
 3425                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3426                        lsp::OneOf::Right(base_uri) => base_uri,
 3427                    }
 3428                    .to_file_path()
 3429                    .ok()?;
 3430                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3431                    let mut literal_prefix = relative.to_owned();
 3432                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3433                    Some((
 3434                        worktree.clone(),
 3435                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3436                        rp.pattern.clone(),
 3437                    ))
 3438                }
 3439            }
 3440        })
 3441    }
 3442
 3443    fn rebuild_watched_paths(
 3444        &mut self,
 3445        language_server_id: LanguageServerId,
 3446        cx: &mut Context<LspStore>,
 3447    ) {
 3448        let Some(registrations) = self
 3449            .language_server_dynamic_registrations
 3450            .get(&language_server_id)
 3451        else {
 3452            return;
 3453        };
 3454
 3455        let watch_builder = self.rebuild_watched_paths_inner(
 3456            language_server_id,
 3457            registrations.did_change_watched_files.values().flatten(),
 3458            cx,
 3459        );
 3460        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3461        self.language_server_watched_paths
 3462            .insert(language_server_id, watcher);
 3463
 3464        cx.notify();
 3465    }
 3466
 3467    fn on_lsp_did_change_watched_files(
 3468        &mut self,
 3469        language_server_id: LanguageServerId,
 3470        registration_id: &str,
 3471        params: DidChangeWatchedFilesRegistrationOptions,
 3472        cx: &mut Context<LspStore>,
 3473    ) {
 3474        let registrations = self
 3475            .language_server_dynamic_registrations
 3476            .entry(language_server_id)
 3477            .or_default();
 3478
 3479        registrations
 3480            .did_change_watched_files
 3481            .insert(registration_id.to_string(), params.watchers);
 3482
 3483        self.rebuild_watched_paths(language_server_id, cx);
 3484    }
 3485
 3486    fn on_lsp_unregister_did_change_watched_files(
 3487        &mut self,
 3488        language_server_id: LanguageServerId,
 3489        registration_id: &str,
 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        if registrations
 3498            .did_change_watched_files
 3499            .remove(registration_id)
 3500            .is_some()
 3501        {
 3502            log::info!(
 3503                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3504                language_server_id,
 3505                registration_id
 3506            );
 3507        } else {
 3508            log::warn!(
 3509                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3510                language_server_id,
 3511                registration_id
 3512            );
 3513        }
 3514
 3515        self.rebuild_watched_paths(language_server_id, cx);
 3516    }
 3517
 3518    async fn initialization_options_for_adapter(
 3519        adapter: Arc<dyn LspAdapter>,
 3520        delegate: &Arc<dyn LspAdapterDelegate>,
 3521    ) -> Result<Option<serde_json::Value>> {
 3522        let Some(mut initialization_config) =
 3523            adapter.clone().initialization_options(delegate).await?
 3524        else {
 3525            return Ok(None);
 3526        };
 3527
 3528        for other_adapter in delegate.registered_lsp_adapters() {
 3529            if other_adapter.name() == adapter.name() {
 3530                continue;
 3531            }
 3532            if let Ok(Some(target_config)) = other_adapter
 3533                .clone()
 3534                .additional_initialization_options(adapter.name(), delegate)
 3535                .await
 3536            {
 3537                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3538            }
 3539        }
 3540
 3541        Ok(Some(initialization_config))
 3542    }
 3543
 3544    async fn workspace_configuration_for_adapter(
 3545        adapter: Arc<dyn LspAdapter>,
 3546        delegate: &Arc<dyn LspAdapterDelegate>,
 3547        toolchain: Option<Toolchain>,
 3548        requested_uri: Option<Uri>,
 3549        cx: &mut AsyncApp,
 3550    ) -> Result<serde_json::Value> {
 3551        let mut workspace_config = adapter
 3552            .clone()
 3553            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3554            .await?;
 3555
 3556        for other_adapter in delegate.registered_lsp_adapters() {
 3557            if other_adapter.name() == adapter.name() {
 3558                continue;
 3559            }
 3560            if let Ok(Some(target_config)) = other_adapter
 3561                .clone()
 3562                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3563                .await
 3564            {
 3565                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3566            }
 3567        }
 3568
 3569        Ok(workspace_config)
 3570    }
 3571
 3572    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3573        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3574            Some(server.clone())
 3575        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3576            Some(Arc::clone(server))
 3577        } else {
 3578            None
 3579        }
 3580    }
 3581}
 3582
 3583fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3584    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3585        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3586            language_server_id: server.server_id(),
 3587            name: Some(server.name()),
 3588            message: proto::update_language_server::Variant::MetadataUpdated(
 3589                proto::ServerMetadataUpdated {
 3590                    capabilities: Some(capabilities),
 3591                    binary: Some(proto::LanguageServerBinaryInfo {
 3592                        path: server.binary().path.to_string_lossy().into_owned(),
 3593                        arguments: server
 3594                            .binary()
 3595                            .arguments
 3596                            .iter()
 3597                            .map(|arg| arg.to_string_lossy().into_owned())
 3598                            .collect(),
 3599                    }),
 3600                    configuration: serde_json::to_string(server.configuration()).ok(),
 3601                    workspace_folders: server
 3602                        .workspace_folders()
 3603                        .iter()
 3604                        .map(|uri| uri.to_string())
 3605                        .collect(),
 3606                },
 3607            ),
 3608        });
 3609    }
 3610}
 3611
 3612#[derive(Debug)]
 3613pub struct FormattableBuffer {
 3614    handle: Entity<Buffer>,
 3615    abs_path: Option<PathBuf>,
 3616    env: Option<HashMap<String, String>>,
 3617    ranges: Option<Vec<Range<Anchor>>>,
 3618}
 3619
 3620pub struct RemoteLspStore {
 3621    upstream_client: Option<AnyProtoClient>,
 3622    upstream_project_id: u64,
 3623}
 3624
 3625pub(crate) enum LspStoreMode {
 3626    Local(LocalLspStore),   // ssh host and collab host
 3627    Remote(RemoteLspStore), // collab guest
 3628}
 3629
 3630impl LspStoreMode {
 3631    fn is_local(&self) -> bool {
 3632        matches!(self, LspStoreMode::Local(_))
 3633    }
 3634}
 3635
 3636pub struct LspStore {
 3637    mode: LspStoreMode,
 3638    last_formatting_failure: Option<String>,
 3639    downstream_client: Option<(AnyProtoClient, u64)>,
 3640    nonce: u128,
 3641    buffer_store: Entity<BufferStore>,
 3642    worktree_store: Entity<WorktreeStore>,
 3643    pub languages: Arc<LanguageRegistry>,
 3644    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3645    active_entry: Option<ProjectEntryId>,
 3646    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3647    _maintain_buffer_languages: Task<()>,
 3648    diagnostic_summaries:
 3649        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3650    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3651    lsp_data: HashMap<BufferId, BufferLspData>,
 3652    next_hint_id: Arc<AtomicUsize>,
 3653}
 3654
 3655#[derive(Debug)]
 3656pub struct BufferLspData {
 3657    buffer_version: Global,
 3658    document_colors: Option<DocumentColorData>,
 3659    code_lens: Option<CodeLensData>,
 3660    inlay_hints: BufferInlayHints,
 3661    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3662    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3663}
 3664
 3665#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3666struct LspKey {
 3667    request_type: TypeId,
 3668    server_queried: Option<LanguageServerId>,
 3669}
 3670
 3671impl BufferLspData {
 3672    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3673        Self {
 3674            buffer_version: buffer.read(cx).version(),
 3675            document_colors: None,
 3676            code_lens: None,
 3677            inlay_hints: BufferInlayHints::new(buffer, cx),
 3678            lsp_requests: HashMap::default(),
 3679            chunk_lsp_requests: HashMap::default(),
 3680        }
 3681    }
 3682
 3683    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3684        if let Some(document_colors) = &mut self.document_colors {
 3685            document_colors.colors.remove(&for_server);
 3686            document_colors.cache_version += 1;
 3687        }
 3688
 3689        if let Some(code_lens) = &mut self.code_lens {
 3690            code_lens.lens.remove(&for_server);
 3691        }
 3692
 3693        self.inlay_hints.remove_server_data(for_server);
 3694    }
 3695
 3696    #[cfg(any(test, feature = "test-support"))]
 3697    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3698        &self.inlay_hints
 3699    }
 3700}
 3701
 3702#[derive(Debug, Default, Clone)]
 3703pub struct DocumentColors {
 3704    pub colors: HashSet<DocumentColor>,
 3705    pub cache_version: Option<usize>,
 3706}
 3707
 3708type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3709type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3710
 3711#[derive(Debug, Default)]
 3712struct DocumentColorData {
 3713    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3714    cache_version: usize,
 3715    colors_update: Option<(Global, DocumentColorTask)>,
 3716}
 3717
 3718#[derive(Debug, Default)]
 3719struct CodeLensData {
 3720    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3721    update: Option<(Global, CodeLensTask)>,
 3722}
 3723
 3724#[derive(Debug)]
 3725pub enum LspStoreEvent {
 3726    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3727    LanguageServerRemoved(LanguageServerId),
 3728    LanguageServerUpdate {
 3729        language_server_id: LanguageServerId,
 3730        name: Option<LanguageServerName>,
 3731        message: proto::update_language_server::Variant,
 3732    },
 3733    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3734    LanguageServerPrompt(LanguageServerPromptRequest),
 3735    LanguageDetected {
 3736        buffer: Entity<Buffer>,
 3737        new_language: Option<Arc<Language>>,
 3738    },
 3739    Notification(String),
 3740    RefreshInlayHints {
 3741        server_id: LanguageServerId,
 3742        request_id: Option<usize>,
 3743    },
 3744    RefreshCodeLens,
 3745    DiagnosticsUpdated {
 3746        server_id: LanguageServerId,
 3747        paths: Vec<ProjectPath>,
 3748    },
 3749    DiskBasedDiagnosticsStarted {
 3750        language_server_id: LanguageServerId,
 3751    },
 3752    DiskBasedDiagnosticsFinished {
 3753        language_server_id: LanguageServerId,
 3754    },
 3755    SnippetEdit {
 3756        buffer_id: BufferId,
 3757        edits: Vec<(lsp::Range, Snippet)>,
 3758        most_recent_edit: clock::Lamport,
 3759    },
 3760}
 3761
 3762#[derive(Clone, Debug, Serialize)]
 3763pub struct LanguageServerStatus {
 3764    pub name: LanguageServerName,
 3765    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3766    pub has_pending_diagnostic_updates: bool,
 3767    pub progress_tokens: HashSet<ProgressToken>,
 3768    pub worktree: Option<WorktreeId>,
 3769    pub binary: Option<LanguageServerBinary>,
 3770    pub configuration: Option<Value>,
 3771    pub workspace_folders: BTreeSet<Uri>,
 3772}
 3773
 3774#[derive(Clone, Debug)]
 3775struct CoreSymbol {
 3776    pub language_server_name: LanguageServerName,
 3777    pub source_worktree_id: WorktreeId,
 3778    pub source_language_server_id: LanguageServerId,
 3779    pub path: SymbolLocation,
 3780    pub name: String,
 3781    pub kind: lsp::SymbolKind,
 3782    pub range: Range<Unclipped<PointUtf16>>,
 3783}
 3784
 3785#[derive(Clone, Debug, PartialEq, Eq)]
 3786pub enum SymbolLocation {
 3787    InProject(ProjectPath),
 3788    OutsideProject {
 3789        abs_path: Arc<Path>,
 3790        signature: [u8; 32],
 3791    },
 3792}
 3793
 3794impl SymbolLocation {
 3795    fn file_name(&self) -> Option<&str> {
 3796        match self {
 3797            Self::InProject(path) => path.path.file_name(),
 3798            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3799        }
 3800    }
 3801}
 3802
 3803impl LspStore {
 3804    pub fn init(client: &AnyProtoClient) {
 3805        client.add_entity_request_handler(Self::handle_lsp_query);
 3806        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3807        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3808        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3809        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3810        client.add_entity_message_handler(Self::handle_start_language_server);
 3811        client.add_entity_message_handler(Self::handle_update_language_server);
 3812        client.add_entity_message_handler(Self::handle_language_server_log);
 3813        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3814        client.add_entity_request_handler(Self::handle_format_buffers);
 3815        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3816        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3817        client.add_entity_request_handler(Self::handle_apply_code_action);
 3818        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3819        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3820        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3821        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3822        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3823        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3824        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3825        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3826        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3827        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3828        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3829        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3830        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3831        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3832        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3833        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3834        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3835
 3836        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3837        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3838        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3839        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3840        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3841        client.add_entity_request_handler(
 3842            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3843        );
 3844        client.add_entity_request_handler(
 3845            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3846        );
 3847        client.add_entity_request_handler(
 3848            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3849        );
 3850    }
 3851
 3852    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3853        match &self.mode {
 3854            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3855            _ => None,
 3856        }
 3857    }
 3858
 3859    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3860        match &self.mode {
 3861            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3862            _ => None,
 3863        }
 3864    }
 3865
 3866    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3867        match &mut self.mode {
 3868            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3869            _ => None,
 3870        }
 3871    }
 3872
 3873    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3874        match &self.mode {
 3875            LspStoreMode::Remote(RemoteLspStore {
 3876                upstream_client: Some(upstream_client),
 3877                upstream_project_id,
 3878                ..
 3879            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3880
 3881            LspStoreMode::Remote(RemoteLspStore {
 3882                upstream_client: None,
 3883                ..
 3884            }) => None,
 3885            LspStoreMode::Local(_) => None,
 3886        }
 3887    }
 3888
 3889    pub fn new_local(
 3890        buffer_store: Entity<BufferStore>,
 3891        worktree_store: Entity<WorktreeStore>,
 3892        prettier_store: Entity<PrettierStore>,
 3893        toolchain_store: Entity<LocalToolchainStore>,
 3894        environment: Entity<ProjectEnvironment>,
 3895        manifest_tree: Entity<ManifestTree>,
 3896        languages: Arc<LanguageRegistry>,
 3897        http_client: Arc<dyn HttpClient>,
 3898        fs: Arc<dyn Fs>,
 3899        cx: &mut Context<Self>,
 3900    ) -> Self {
 3901        let yarn = YarnPathStore::new(fs.clone(), cx);
 3902        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3903            .detach();
 3904        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3905            .detach();
 3906        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3907            .detach();
 3908        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3909            .detach();
 3910        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3911            .detach();
 3912        subscribe_to_binary_statuses(&languages, cx).detach();
 3913
 3914        let _maintain_workspace_config = {
 3915            let (sender, receiver) = watch::channel();
 3916            (Self::maintain_workspace_config(receiver, cx), sender)
 3917        };
 3918
 3919        Self {
 3920            mode: LspStoreMode::Local(LocalLspStore {
 3921                weak: cx.weak_entity(),
 3922                worktree_store: worktree_store.clone(),
 3923
 3924                supplementary_language_servers: Default::default(),
 3925                languages: languages.clone(),
 3926                language_server_ids: Default::default(),
 3927                language_servers: Default::default(),
 3928                last_workspace_edits_by_language_server: Default::default(),
 3929                language_server_watched_paths: Default::default(),
 3930                language_server_paths_watched_for_rename: Default::default(),
 3931                language_server_dynamic_registrations: Default::default(),
 3932                buffers_being_formatted: Default::default(),
 3933                buffer_snapshots: Default::default(),
 3934                prettier_store,
 3935                environment,
 3936                http_client,
 3937                fs,
 3938                yarn,
 3939                next_diagnostic_group_id: Default::default(),
 3940                diagnostics: Default::default(),
 3941                _subscription: cx.on_app_quit(|this, cx| {
 3942                    this.as_local_mut()
 3943                        .unwrap()
 3944                        .shutdown_language_servers_on_quit(cx)
 3945                }),
 3946                lsp_tree: LanguageServerTree::new(
 3947                    manifest_tree,
 3948                    languages.clone(),
 3949                    toolchain_store.clone(),
 3950                ),
 3951                toolchain_store,
 3952                registered_buffers: HashMap::default(),
 3953                buffers_opened_in_servers: HashMap::default(),
 3954                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3955                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3956                    .manifest_file_names(),
 3957            }),
 3958            last_formatting_failure: None,
 3959            downstream_client: None,
 3960            buffer_store,
 3961            worktree_store,
 3962            languages: languages.clone(),
 3963            language_server_statuses: Default::default(),
 3964            nonce: StdRng::from_os_rng().random(),
 3965            diagnostic_summaries: HashMap::default(),
 3966            lsp_server_capabilities: HashMap::default(),
 3967            lsp_data: HashMap::default(),
 3968            next_hint_id: Arc::default(),
 3969            active_entry: None,
 3970            _maintain_workspace_config,
 3971            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3972        }
 3973    }
 3974
 3975    fn send_lsp_proto_request<R: LspCommand>(
 3976        &self,
 3977        buffer: Entity<Buffer>,
 3978        client: AnyProtoClient,
 3979        upstream_project_id: u64,
 3980        request: R,
 3981        cx: &mut Context<LspStore>,
 3982    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3983        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3984            return Task::ready(Ok(R::Response::default()));
 3985        }
 3986        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3987        cx.spawn(async move |this, cx| {
 3988            let response = client.request(message).await?;
 3989            let this = this.upgrade().context("project dropped")?;
 3990            request
 3991                .response_from_proto(response, this, buffer, cx.clone())
 3992                .await
 3993        })
 3994    }
 3995
 3996    pub(super) fn new_remote(
 3997        buffer_store: Entity<BufferStore>,
 3998        worktree_store: Entity<WorktreeStore>,
 3999        languages: Arc<LanguageRegistry>,
 4000        upstream_client: AnyProtoClient,
 4001        project_id: u64,
 4002        cx: &mut Context<Self>,
 4003    ) -> Self {
 4004        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4005            .detach();
 4006        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4007            .detach();
 4008        subscribe_to_binary_statuses(&languages, cx).detach();
 4009        let _maintain_workspace_config = {
 4010            let (sender, receiver) = watch::channel();
 4011            (Self::maintain_workspace_config(receiver, cx), sender)
 4012        };
 4013        Self {
 4014            mode: LspStoreMode::Remote(RemoteLspStore {
 4015                upstream_client: Some(upstream_client),
 4016                upstream_project_id: project_id,
 4017            }),
 4018            downstream_client: None,
 4019            last_formatting_failure: None,
 4020            buffer_store,
 4021            worktree_store,
 4022            languages: languages.clone(),
 4023            language_server_statuses: Default::default(),
 4024            nonce: StdRng::from_os_rng().random(),
 4025            diagnostic_summaries: HashMap::default(),
 4026            lsp_server_capabilities: HashMap::default(),
 4027            next_hint_id: Arc::default(),
 4028            lsp_data: HashMap::default(),
 4029            active_entry: None,
 4030
 4031            _maintain_workspace_config,
 4032            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4033        }
 4034    }
 4035
 4036    fn on_buffer_store_event(
 4037        &mut self,
 4038        _: Entity<BufferStore>,
 4039        event: &BufferStoreEvent,
 4040        cx: &mut Context<Self>,
 4041    ) {
 4042        match event {
 4043            BufferStoreEvent::BufferAdded(buffer) => {
 4044                self.on_buffer_added(buffer, cx).log_err();
 4045            }
 4046            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4047                let buffer_id = buffer.read(cx).remote_id();
 4048                if let Some(local) = self.as_local_mut()
 4049                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4050                {
 4051                    local.reset_buffer(buffer, old_file, cx);
 4052
 4053                    if local.registered_buffers.contains_key(&buffer_id) {
 4054                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4055                    }
 4056                }
 4057
 4058                self.detect_language_for_buffer(buffer, cx);
 4059                if let Some(local) = self.as_local_mut() {
 4060                    local.initialize_buffer(buffer, cx);
 4061                    if local.registered_buffers.contains_key(&buffer_id) {
 4062                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4063                    }
 4064                }
 4065            }
 4066            _ => {}
 4067        }
 4068    }
 4069
 4070    fn on_worktree_store_event(
 4071        &mut self,
 4072        _: Entity<WorktreeStore>,
 4073        event: &WorktreeStoreEvent,
 4074        cx: &mut Context<Self>,
 4075    ) {
 4076        match event {
 4077            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4078                if !worktree.read(cx).is_local() {
 4079                    return;
 4080                }
 4081                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4082                    worktree::Event::UpdatedEntries(changes) => {
 4083                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4084                    }
 4085                    worktree::Event::UpdatedGitRepositories(_)
 4086                    | worktree::Event::DeletedEntry(_) => {}
 4087                })
 4088                .detach()
 4089            }
 4090            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4091            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4092                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4093            }
 4094            WorktreeStoreEvent::WorktreeReleased(..)
 4095            | WorktreeStoreEvent::WorktreeOrderChanged
 4096            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4097            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4098            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4099        }
 4100    }
 4101
 4102    fn on_prettier_store_event(
 4103        &mut self,
 4104        _: Entity<PrettierStore>,
 4105        event: &PrettierStoreEvent,
 4106        cx: &mut Context<Self>,
 4107    ) {
 4108        match event {
 4109            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4110                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4111            }
 4112            PrettierStoreEvent::LanguageServerAdded {
 4113                new_server_id,
 4114                name,
 4115                prettier_server,
 4116            } => {
 4117                self.register_supplementary_language_server(
 4118                    *new_server_id,
 4119                    name.clone(),
 4120                    prettier_server.clone(),
 4121                    cx,
 4122                );
 4123            }
 4124        }
 4125    }
 4126
 4127    fn on_toolchain_store_event(
 4128        &mut self,
 4129        _: Entity<LocalToolchainStore>,
 4130        event: &ToolchainStoreEvent,
 4131        _: &mut Context<Self>,
 4132    ) {
 4133        if let ToolchainStoreEvent::ToolchainActivated = event {
 4134            self.request_workspace_config_refresh()
 4135        }
 4136    }
 4137
 4138    fn request_workspace_config_refresh(&mut self) {
 4139        *self._maintain_workspace_config.1.borrow_mut() = ();
 4140    }
 4141
 4142    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4143        self.as_local().map(|local| local.prettier_store.clone())
 4144    }
 4145
 4146    fn on_buffer_event(
 4147        &mut self,
 4148        buffer: Entity<Buffer>,
 4149        event: &language::BufferEvent,
 4150        cx: &mut Context<Self>,
 4151    ) {
 4152        match event {
 4153            language::BufferEvent::Edited => {
 4154                self.on_buffer_edited(buffer, cx);
 4155            }
 4156
 4157            language::BufferEvent::Saved => {
 4158                self.on_buffer_saved(buffer, cx);
 4159            }
 4160
 4161            _ => {}
 4162        }
 4163    }
 4164
 4165    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4166        buffer
 4167            .read(cx)
 4168            .set_language_registry(self.languages.clone());
 4169
 4170        cx.subscribe(buffer, |this, buffer, event, cx| {
 4171            this.on_buffer_event(buffer, event, cx);
 4172        })
 4173        .detach();
 4174
 4175        self.detect_language_for_buffer(buffer, cx);
 4176        if let Some(local) = self.as_local_mut() {
 4177            local.initialize_buffer(buffer, cx);
 4178        }
 4179
 4180        Ok(())
 4181    }
 4182
 4183    pub(crate) fn register_buffer_with_language_servers(
 4184        &mut self,
 4185        buffer: &Entity<Buffer>,
 4186        only_register_servers: HashSet<LanguageServerSelector>,
 4187        ignore_refcounts: bool,
 4188        cx: &mut Context<Self>,
 4189    ) -> OpenLspBufferHandle {
 4190        let buffer_id = buffer.read(cx).remote_id();
 4191        let handle = cx.new(|_| buffer.clone());
 4192        if let Some(local) = self.as_local_mut() {
 4193            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4194            if !ignore_refcounts {
 4195                *refcount += 1;
 4196            }
 4197
 4198            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4199            // 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
 4200            // 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
 4201            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4202            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4203                return handle;
 4204            };
 4205            if !file.is_local() {
 4206                return handle;
 4207            }
 4208
 4209            if ignore_refcounts || *refcount == 1 {
 4210                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4211            }
 4212            if !ignore_refcounts {
 4213                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4214                    let refcount = {
 4215                        let local = lsp_store.as_local_mut().unwrap();
 4216                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4217                            debug_panic!("bad refcounting");
 4218                            return;
 4219                        };
 4220
 4221                        *refcount -= 1;
 4222                        *refcount
 4223                    };
 4224                    if refcount == 0 {
 4225                        lsp_store.lsp_data.remove(&buffer_id);
 4226                        let local = lsp_store.as_local_mut().unwrap();
 4227                        local.registered_buffers.remove(&buffer_id);
 4228                        local.buffers_opened_in_servers.remove(&buffer_id);
 4229                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4230                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4231                        }
 4232                    }
 4233                })
 4234                .detach();
 4235            }
 4236        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4237            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4238            cx.background_spawn(async move {
 4239                upstream_client
 4240                    .request(proto::RegisterBufferWithLanguageServers {
 4241                        project_id: upstream_project_id,
 4242                        buffer_id,
 4243                        only_servers: only_register_servers
 4244                            .into_iter()
 4245                            .map(|selector| {
 4246                                let selector = match selector {
 4247                                    LanguageServerSelector::Id(language_server_id) => {
 4248                                        proto::language_server_selector::Selector::ServerId(
 4249                                            language_server_id.to_proto(),
 4250                                        )
 4251                                    }
 4252                                    LanguageServerSelector::Name(language_server_name) => {
 4253                                        proto::language_server_selector::Selector::Name(
 4254                                            language_server_name.to_string(),
 4255                                        )
 4256                                    }
 4257                                };
 4258                                proto::LanguageServerSelector {
 4259                                    selector: Some(selector),
 4260                                }
 4261                            })
 4262                            .collect(),
 4263                    })
 4264                    .await
 4265            })
 4266            .detach();
 4267        } else {
 4268            // Our remote connection got closed
 4269        }
 4270        handle
 4271    }
 4272
 4273    fn maintain_buffer_languages(
 4274        languages: Arc<LanguageRegistry>,
 4275        cx: &mut Context<Self>,
 4276    ) -> Task<()> {
 4277        let mut subscription = languages.subscribe();
 4278        let mut prev_reload_count = languages.reload_count();
 4279        cx.spawn(async move |this, cx| {
 4280            while let Some(()) = subscription.next().await {
 4281                if let Some(this) = this.upgrade() {
 4282                    // If the language registry has been reloaded, then remove and
 4283                    // re-assign the languages on all open buffers.
 4284                    let reload_count = languages.reload_count();
 4285                    if reload_count > prev_reload_count {
 4286                        prev_reload_count = reload_count;
 4287                        this.update(cx, |this, cx| {
 4288                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4289                                for buffer in buffer_store.buffers() {
 4290                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4291                                    {
 4292                                        buffer.update(cx, |buffer, cx| {
 4293                                            buffer.set_language_async(None, cx)
 4294                                        });
 4295                                        if let Some(local) = this.as_local_mut() {
 4296                                            local.reset_buffer(&buffer, &f, cx);
 4297
 4298                                            if local
 4299                                                .registered_buffers
 4300                                                .contains_key(&buffer.read(cx).remote_id())
 4301                                                && let Some(file_url) =
 4302                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4303                                            {
 4304                                                local.unregister_buffer_from_language_servers(
 4305                                                    &buffer, &file_url, cx,
 4306                                                );
 4307                                            }
 4308                                        }
 4309                                    }
 4310                                }
 4311                            });
 4312                        })
 4313                        .ok();
 4314                    }
 4315
 4316                    this.update(cx, |this, cx| {
 4317                        let mut plain_text_buffers = Vec::new();
 4318                        let mut buffers_with_unknown_injections = Vec::new();
 4319                        for handle in this.buffer_store.read(cx).buffers() {
 4320                            let buffer = handle.read(cx);
 4321                            if buffer.language().is_none()
 4322                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4323                            {
 4324                                plain_text_buffers.push(handle);
 4325                            } else if buffer.contains_unknown_injections() {
 4326                                buffers_with_unknown_injections.push(handle);
 4327                            }
 4328                        }
 4329
 4330                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4331                        // and reused later in the invisible worktrees.
 4332                        plain_text_buffers.sort_by_key(|buffer| {
 4333                            Reverse(
 4334                                File::from_dyn(buffer.read(cx).file())
 4335                                    .map(|file| file.worktree.read(cx).is_visible()),
 4336                            )
 4337                        });
 4338
 4339                        for buffer in plain_text_buffers {
 4340                            this.detect_language_for_buffer(&buffer, cx);
 4341                            if let Some(local) = this.as_local_mut() {
 4342                                local.initialize_buffer(&buffer, cx);
 4343                                if local
 4344                                    .registered_buffers
 4345                                    .contains_key(&buffer.read(cx).remote_id())
 4346                                {
 4347                                    local.register_buffer_with_language_servers(
 4348                                        &buffer,
 4349                                        HashSet::default(),
 4350                                        cx,
 4351                                    );
 4352                                }
 4353                            }
 4354                        }
 4355
 4356                        for buffer in buffers_with_unknown_injections {
 4357                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4358                        }
 4359                    })
 4360                    .ok();
 4361                }
 4362            }
 4363        })
 4364    }
 4365
 4366    fn detect_language_for_buffer(
 4367        &mut self,
 4368        buffer_handle: &Entity<Buffer>,
 4369        cx: &mut Context<Self>,
 4370    ) -> Option<language::AvailableLanguage> {
 4371        // If the buffer has a language, set it and start the language server if we haven't already.
 4372        let buffer = buffer_handle.read(cx);
 4373        let file = buffer.file()?;
 4374
 4375        let content = buffer.as_rope();
 4376        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4377        if let Some(available_language) = &available_language {
 4378            if let Some(Ok(Ok(new_language))) = self
 4379                .languages
 4380                .load_language(available_language)
 4381                .now_or_never()
 4382            {
 4383                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4384            }
 4385        } else {
 4386            cx.emit(LspStoreEvent::LanguageDetected {
 4387                buffer: buffer_handle.clone(),
 4388                new_language: None,
 4389            });
 4390        }
 4391
 4392        available_language
 4393    }
 4394
 4395    pub(crate) fn set_language_for_buffer(
 4396        &mut self,
 4397        buffer_entity: &Entity<Buffer>,
 4398        new_language: Arc<Language>,
 4399        cx: &mut Context<Self>,
 4400    ) {
 4401        let buffer = buffer_entity.read(cx);
 4402        let buffer_file = buffer.file().cloned();
 4403        let buffer_id = buffer.remote_id();
 4404        if let Some(local_store) = self.as_local_mut()
 4405            && local_store.registered_buffers.contains_key(&buffer_id)
 4406            && let Some(abs_path) =
 4407                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4408            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4409        {
 4410            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4411        }
 4412        buffer_entity.update(cx, |buffer, cx| {
 4413            if buffer
 4414                .language()
 4415                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4416            {
 4417                buffer.set_language_async(Some(new_language.clone()), cx);
 4418            }
 4419        });
 4420
 4421        let settings =
 4422            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4423        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4424
 4425        let worktree_id = if let Some(file) = buffer_file {
 4426            let worktree = file.worktree.clone();
 4427
 4428            if let Some(local) = self.as_local_mut()
 4429                && local.registered_buffers.contains_key(&buffer_id)
 4430            {
 4431                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4432            }
 4433            Some(worktree.read(cx).id())
 4434        } else {
 4435            None
 4436        };
 4437
 4438        if settings.prettier.allowed
 4439            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4440        {
 4441            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4442            if let Some(prettier_store) = prettier_store {
 4443                prettier_store.update(cx, |prettier_store, cx| {
 4444                    prettier_store.install_default_prettier(
 4445                        worktree_id,
 4446                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4447                        cx,
 4448                    )
 4449                })
 4450            }
 4451        }
 4452
 4453        cx.emit(LspStoreEvent::LanguageDetected {
 4454            buffer: buffer_entity.clone(),
 4455            new_language: Some(new_language),
 4456        })
 4457    }
 4458
 4459    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4460        self.buffer_store.clone()
 4461    }
 4462
 4463    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4464        self.active_entry = active_entry;
 4465    }
 4466
 4467    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4468        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4469            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4470        {
 4471            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4472                summaries
 4473                    .iter()
 4474                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4475            });
 4476            if let Some(summary) = summaries.next() {
 4477                client
 4478                    .send(proto::UpdateDiagnosticSummary {
 4479                        project_id: downstream_project_id,
 4480                        worktree_id: worktree.id().to_proto(),
 4481                        summary: Some(summary),
 4482                        more_summaries: summaries.collect(),
 4483                    })
 4484                    .log_err();
 4485            }
 4486        }
 4487    }
 4488
 4489    fn is_capable_for_proto_request<R>(
 4490        &self,
 4491        buffer: &Entity<Buffer>,
 4492        request: &R,
 4493        cx: &App,
 4494    ) -> bool
 4495    where
 4496        R: LspCommand,
 4497    {
 4498        self.check_if_capable_for_proto_request(
 4499            buffer,
 4500            |capabilities| {
 4501                request.check_capabilities(AdapterServerCapabilities {
 4502                    server_capabilities: capabilities.clone(),
 4503                    code_action_kinds: None,
 4504                })
 4505            },
 4506            cx,
 4507        )
 4508    }
 4509
 4510    fn check_if_capable_for_proto_request<F>(
 4511        &self,
 4512        buffer: &Entity<Buffer>,
 4513        check: F,
 4514        cx: &App,
 4515    ) -> bool
 4516    where
 4517        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4518    {
 4519        let Some(language) = buffer.read(cx).language().cloned() else {
 4520            return false;
 4521        };
 4522        let relevant_language_servers = self
 4523            .languages
 4524            .lsp_adapters(&language.name())
 4525            .into_iter()
 4526            .map(|lsp_adapter| lsp_adapter.name())
 4527            .collect::<HashSet<_>>();
 4528        self.language_server_statuses
 4529            .iter()
 4530            .filter_map(|(server_id, server_status)| {
 4531                relevant_language_servers
 4532                    .contains(&server_status.name)
 4533                    .then_some(server_id)
 4534            })
 4535            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4536            .any(check)
 4537    }
 4538
 4539    fn all_capable_for_proto_request<F>(
 4540        &self,
 4541        buffer: &Entity<Buffer>,
 4542        mut check: F,
 4543        cx: &App,
 4544    ) -> Vec<lsp::LanguageServerId>
 4545    where
 4546        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4547    {
 4548        let Some(language) = buffer.read(cx).language().cloned() else {
 4549            return Vec::default();
 4550        };
 4551        let relevant_language_servers = self
 4552            .languages
 4553            .lsp_adapters(&language.name())
 4554            .into_iter()
 4555            .map(|lsp_adapter| lsp_adapter.name())
 4556            .collect::<HashSet<_>>();
 4557        self.language_server_statuses
 4558            .iter()
 4559            .filter_map(|(server_id, server_status)| {
 4560                relevant_language_servers
 4561                    .contains(&server_status.name)
 4562                    .then_some((server_id, &server_status.name))
 4563            })
 4564            .filter_map(|(server_id, server_name)| {
 4565                self.lsp_server_capabilities
 4566                    .get(server_id)
 4567                    .map(|c| (server_id, server_name, c))
 4568            })
 4569            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4570            .map(|(server_id, _, _)| *server_id)
 4571            .collect()
 4572    }
 4573
 4574    pub fn request_lsp<R>(
 4575        &mut self,
 4576        buffer: Entity<Buffer>,
 4577        server: LanguageServerToQuery,
 4578        request: R,
 4579        cx: &mut Context<Self>,
 4580    ) -> Task<Result<R::Response>>
 4581    where
 4582        R: LspCommand,
 4583        <R::LspRequest as lsp::request::Request>::Result: Send,
 4584        <R::LspRequest as lsp::request::Request>::Params: Send,
 4585    {
 4586        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4587            return self.send_lsp_proto_request(
 4588                buffer,
 4589                upstream_client,
 4590                upstream_project_id,
 4591                request,
 4592                cx,
 4593            );
 4594        }
 4595
 4596        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4597            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4598                local
 4599                    .language_servers_for_buffer(buffer, cx)
 4600                    .find(|(_, server)| {
 4601                        request.check_capabilities(server.adapter_server_capabilities())
 4602                    })
 4603                    .map(|(_, server)| server.clone())
 4604            }),
 4605            LanguageServerToQuery::Other(id) => self
 4606                .language_server_for_local_buffer(buffer, id, cx)
 4607                .and_then(|(_, server)| {
 4608                    request
 4609                        .check_capabilities(server.adapter_server_capabilities())
 4610                        .then(|| Arc::clone(server))
 4611                }),
 4612        }) else {
 4613            return Task::ready(Ok(Default::default()));
 4614        };
 4615
 4616        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4617
 4618        let Some(file) = file else {
 4619            return Task::ready(Ok(Default::default()));
 4620        };
 4621
 4622        let lsp_params = match request.to_lsp_params_or_response(
 4623            &file.abs_path(cx),
 4624            buffer.read(cx),
 4625            &language_server,
 4626            cx,
 4627        ) {
 4628            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4629            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4630            Err(err) => {
 4631                let message = format!(
 4632                    "{} via {} failed: {}",
 4633                    request.display_name(),
 4634                    language_server.name(),
 4635                    err
 4636                );
 4637                // rust-analyzer likes to error with this when its still loading up
 4638                if !message.ends_with("content modified") {
 4639                    log::warn!("{message}");
 4640                }
 4641                return Task::ready(Err(anyhow!(message)));
 4642            }
 4643        };
 4644
 4645        let status = request.status();
 4646        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4647            return Task::ready(Ok(Default::default()));
 4648        }
 4649        cx.spawn(async move |this, cx| {
 4650            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4651
 4652            let id = lsp_request.id();
 4653            let _cleanup = if status.is_some() {
 4654                cx.update(|cx| {
 4655                    this.update(cx, |this, cx| {
 4656                        this.on_lsp_work_start(
 4657                            language_server.server_id(),
 4658                            ProgressToken::Number(id),
 4659                            LanguageServerProgress {
 4660                                is_disk_based_diagnostics_progress: false,
 4661                                is_cancellable: false,
 4662                                title: None,
 4663                                message: status.clone(),
 4664                                percentage: None,
 4665                                last_update_at: cx.background_executor().now(),
 4666                            },
 4667                            cx,
 4668                        );
 4669                    })
 4670                })
 4671                .log_err();
 4672
 4673                Some(defer(|| {
 4674                    cx.update(|cx| {
 4675                        this.update(cx, |this, cx| {
 4676                            this.on_lsp_work_end(
 4677                                language_server.server_id(),
 4678                                ProgressToken::Number(id),
 4679                                cx,
 4680                            );
 4681                        })
 4682                    })
 4683                    .log_err();
 4684                }))
 4685            } else {
 4686                None
 4687            };
 4688
 4689            let result = lsp_request.await.into_response();
 4690
 4691            let response = result.map_err(|err| {
 4692                let message = format!(
 4693                    "{} via {} failed: {}",
 4694                    request.display_name(),
 4695                    language_server.name(),
 4696                    err
 4697                );
 4698                // rust-analyzer likes to error with this when its still loading up
 4699                if !message.ends_with("content modified") {
 4700                    log::warn!("{message}");
 4701                }
 4702                anyhow::anyhow!(message)
 4703            })?;
 4704
 4705            request
 4706                .response_from_lsp(
 4707                    response,
 4708                    this.upgrade().context("no app context")?,
 4709                    buffer,
 4710                    language_server.server_id(),
 4711                    cx.clone(),
 4712                )
 4713                .await
 4714        })
 4715    }
 4716
 4717    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4718        let mut language_formatters_to_check = Vec::new();
 4719        for buffer in self.buffer_store.read(cx).buffers() {
 4720            let buffer = buffer.read(cx);
 4721            let buffer_file = File::from_dyn(buffer.file());
 4722            let buffer_language = buffer.language();
 4723            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4724            if buffer_language.is_some() {
 4725                language_formatters_to_check.push((
 4726                    buffer_file.map(|f| f.worktree_id(cx)),
 4727                    settings.into_owned(),
 4728                ));
 4729            }
 4730        }
 4731
 4732        self.request_workspace_config_refresh();
 4733
 4734        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4735            prettier_store.update(cx, |prettier_store, cx| {
 4736                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4737            })
 4738        }
 4739
 4740        cx.notify();
 4741    }
 4742
 4743    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4744        let buffer_store = self.buffer_store.clone();
 4745        let Some(local) = self.as_local_mut() else {
 4746            return;
 4747        };
 4748        let mut adapters = BTreeMap::default();
 4749        let get_adapter = {
 4750            let languages = local.languages.clone();
 4751            let environment = local.environment.clone();
 4752            let weak = local.weak.clone();
 4753            let worktree_store = local.worktree_store.clone();
 4754            let http_client = local.http_client.clone();
 4755            let fs = local.fs.clone();
 4756            move |worktree_id, cx: &mut App| {
 4757                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4758                Some(LocalLspAdapterDelegate::new(
 4759                    languages.clone(),
 4760                    &environment,
 4761                    weak.clone(),
 4762                    &worktree,
 4763                    http_client.clone(),
 4764                    fs.clone(),
 4765                    cx,
 4766                ))
 4767            }
 4768        };
 4769
 4770        let mut messages_to_report = Vec::new();
 4771        let (new_tree, to_stop) = {
 4772            let mut rebase = local.lsp_tree.rebase();
 4773            let buffers = buffer_store
 4774                .read(cx)
 4775                .buffers()
 4776                .filter_map(|buffer| {
 4777                    let raw_buffer = buffer.read(cx);
 4778                    if !local
 4779                        .registered_buffers
 4780                        .contains_key(&raw_buffer.remote_id())
 4781                    {
 4782                        return None;
 4783                    }
 4784                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4785                    let language = raw_buffer.language().cloned()?;
 4786                    Some((file, language, raw_buffer.remote_id()))
 4787                })
 4788                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4789            for (file, language, buffer_id) in buffers {
 4790                let worktree_id = file.worktree_id(cx);
 4791                let Some(worktree) = local
 4792                    .worktree_store
 4793                    .read(cx)
 4794                    .worktree_for_id(worktree_id, cx)
 4795                else {
 4796                    continue;
 4797                };
 4798
 4799                if let Some((_, apply)) = local.reuse_existing_language_server(
 4800                    rebase.server_tree(),
 4801                    &worktree,
 4802                    &language.name(),
 4803                    cx,
 4804                ) {
 4805                    (apply)(rebase.server_tree());
 4806                } else if let Some(lsp_delegate) = adapters
 4807                    .entry(worktree_id)
 4808                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4809                    .clone()
 4810                {
 4811                    let delegate =
 4812                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4813                    let path = file
 4814                        .path()
 4815                        .parent()
 4816                        .map(Arc::from)
 4817                        .unwrap_or_else(|| file.path().clone());
 4818                    let worktree_path = ProjectPath { worktree_id, path };
 4819                    let abs_path = file.abs_path(cx);
 4820                    let nodes = rebase
 4821                        .walk(
 4822                            worktree_path,
 4823                            language.name(),
 4824                            language.manifest(),
 4825                            delegate.clone(),
 4826                            cx,
 4827                        )
 4828                        .collect::<Vec<_>>();
 4829                    for node in nodes {
 4830                        let server_id = node.server_id_or_init(|disposition| {
 4831                            let path = &disposition.path;
 4832                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4833                            let key = LanguageServerSeed {
 4834                                worktree_id,
 4835                                name: disposition.server_name.clone(),
 4836                                settings: disposition.settings.clone(),
 4837                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4838                                    path.worktree_id,
 4839                                    &path.path,
 4840                                    language.name(),
 4841                                ),
 4842                            };
 4843                            local.language_server_ids.remove(&key);
 4844
 4845                            let server_id = local.get_or_insert_language_server(
 4846                                &worktree,
 4847                                lsp_delegate.clone(),
 4848                                disposition,
 4849                                &language.name(),
 4850                                cx,
 4851                            );
 4852                            if let Some(state) = local.language_servers.get(&server_id)
 4853                                && let Ok(uri) = uri
 4854                            {
 4855                                state.add_workspace_folder(uri);
 4856                            };
 4857                            server_id
 4858                        });
 4859
 4860                        if let Some(language_server_id) = server_id {
 4861                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4862                                language_server_id,
 4863                                name: node.name(),
 4864                                message:
 4865                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4866                                        proto::RegisteredForBuffer {
 4867                                            buffer_abs_path: abs_path
 4868                                                .to_string_lossy()
 4869                                                .into_owned(),
 4870                                            buffer_id: buffer_id.to_proto(),
 4871                                        },
 4872                                    ),
 4873                            });
 4874                        }
 4875                    }
 4876                } else {
 4877                    continue;
 4878                }
 4879            }
 4880            rebase.finish()
 4881        };
 4882        for message in messages_to_report {
 4883            cx.emit(message);
 4884        }
 4885        local.lsp_tree = new_tree;
 4886        for (id, _) in to_stop {
 4887            self.stop_local_language_server(id, cx).detach();
 4888        }
 4889    }
 4890
 4891    pub fn apply_code_action(
 4892        &self,
 4893        buffer_handle: Entity<Buffer>,
 4894        mut action: CodeAction,
 4895        push_to_history: bool,
 4896        cx: &mut Context<Self>,
 4897    ) -> Task<Result<ProjectTransaction>> {
 4898        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4899            let request = proto::ApplyCodeAction {
 4900                project_id,
 4901                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4902                action: Some(Self::serialize_code_action(&action)),
 4903            };
 4904            let buffer_store = self.buffer_store();
 4905            cx.spawn(async move |_, cx| {
 4906                let response = upstream_client
 4907                    .request(request)
 4908                    .await?
 4909                    .transaction
 4910                    .context("missing transaction")?;
 4911
 4912                buffer_store
 4913                    .update(cx, |buffer_store, cx| {
 4914                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4915                    })?
 4916                    .await
 4917            })
 4918        } else if self.mode.is_local() {
 4919            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4920                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4921                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4922            }) else {
 4923                return Task::ready(Ok(ProjectTransaction::default()));
 4924            };
 4925            cx.spawn(async move |this,  cx| {
 4926                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4927                    .await
 4928                    .context("resolving a code action")?;
 4929                if let Some(edit) = action.lsp_action.edit()
 4930                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4931                        return LocalLspStore::deserialize_workspace_edit(
 4932                            this.upgrade().context("no app present")?,
 4933                            edit.clone(),
 4934                            push_to_history,
 4935
 4936                            lang_server.clone(),
 4937                            cx,
 4938                        )
 4939                        .await;
 4940                    }
 4941
 4942                if let Some(command) = action.lsp_action.command() {
 4943                    let server_capabilities = lang_server.capabilities();
 4944                    let available_commands = server_capabilities
 4945                        .execute_command_provider
 4946                        .as_ref()
 4947                        .map(|options| options.commands.as_slice())
 4948                        .unwrap_or_default();
 4949                    if available_commands.contains(&command.command) {
 4950                        this.update(cx, |this, _| {
 4951                            this.as_local_mut()
 4952                                .unwrap()
 4953                                .last_workspace_edits_by_language_server
 4954                                .remove(&lang_server.server_id());
 4955                        })?;
 4956
 4957                        let _result = lang_server
 4958                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4959                                command: command.command.clone(),
 4960                                arguments: command.arguments.clone().unwrap_or_default(),
 4961                                ..lsp::ExecuteCommandParams::default()
 4962                            })
 4963                            .await.into_response()
 4964                            .context("execute command")?;
 4965
 4966                        return this.update(cx, |this, _| {
 4967                            this.as_local_mut()
 4968                                .unwrap()
 4969                                .last_workspace_edits_by_language_server
 4970                                .remove(&lang_server.server_id())
 4971                                .unwrap_or_default()
 4972                        });
 4973                    } else {
 4974                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4975                    }
 4976                }
 4977
 4978                Ok(ProjectTransaction::default())
 4979            })
 4980        } else {
 4981            Task::ready(Err(anyhow!("no upstream client and not local")))
 4982        }
 4983    }
 4984
 4985    pub fn apply_code_action_kind(
 4986        &mut self,
 4987        buffers: HashSet<Entity<Buffer>>,
 4988        kind: CodeActionKind,
 4989        push_to_history: bool,
 4990        cx: &mut Context<Self>,
 4991    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4992        if self.as_local().is_some() {
 4993            cx.spawn(async move |lsp_store, cx| {
 4994                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4995                let result = LocalLspStore::execute_code_action_kind_locally(
 4996                    lsp_store.clone(),
 4997                    buffers,
 4998                    kind,
 4999                    push_to_history,
 5000                    cx,
 5001                )
 5002                .await;
 5003                lsp_store.update(cx, |lsp_store, _| {
 5004                    lsp_store.update_last_formatting_failure(&result);
 5005                })?;
 5006                result
 5007            })
 5008        } else if let Some((client, project_id)) = self.upstream_client() {
 5009            let buffer_store = self.buffer_store();
 5010            cx.spawn(async move |lsp_store, cx| {
 5011                let result = client
 5012                    .request(proto::ApplyCodeActionKind {
 5013                        project_id,
 5014                        kind: kind.as_str().to_owned(),
 5015                        buffer_ids: buffers
 5016                            .iter()
 5017                            .map(|buffer| {
 5018                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5019                            })
 5020                            .collect::<Result<_>>()?,
 5021                    })
 5022                    .await
 5023                    .and_then(|result| result.transaction.context("missing transaction"));
 5024                lsp_store.update(cx, |lsp_store, _| {
 5025                    lsp_store.update_last_formatting_failure(&result);
 5026                })?;
 5027
 5028                let transaction_response = result?;
 5029                buffer_store
 5030                    .update(cx, |buffer_store, cx| {
 5031                        buffer_store.deserialize_project_transaction(
 5032                            transaction_response,
 5033                            push_to_history,
 5034                            cx,
 5035                        )
 5036                    })?
 5037                    .await
 5038            })
 5039        } else {
 5040            Task::ready(Ok(ProjectTransaction::default()))
 5041        }
 5042    }
 5043
 5044    pub fn resolved_hint(
 5045        &mut self,
 5046        buffer_id: BufferId,
 5047        id: InlayId,
 5048        cx: &mut Context<Self>,
 5049    ) -> Option<ResolvedHint> {
 5050        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5051
 5052        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5053        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5054        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5055        let (server_id, resolve_data) = match &hint.resolve_state {
 5056            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5057            ResolveState::Resolving => {
 5058                return Some(ResolvedHint::Resolving(
 5059                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5060                ));
 5061            }
 5062            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5063        };
 5064
 5065        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5066        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5067        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5068            id,
 5069            cx.spawn(async move |lsp_store, cx| {
 5070                let resolved_hint = resolve_task.await;
 5071                lsp_store
 5072                    .update(cx, |lsp_store, _| {
 5073                        if let Some(old_inlay_hint) = lsp_store
 5074                            .lsp_data
 5075                            .get_mut(&buffer_id)
 5076                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5077                        {
 5078                            match resolved_hint {
 5079                                Ok(resolved_hint) => {
 5080                                    *old_inlay_hint = resolved_hint;
 5081                                }
 5082                                Err(e) => {
 5083                                    old_inlay_hint.resolve_state =
 5084                                        ResolveState::CanResolve(server_id, resolve_data);
 5085                                    log::error!("Inlay hint resolve failed: {e:#}");
 5086                                }
 5087                            }
 5088                        }
 5089                    })
 5090                    .ok();
 5091            })
 5092            .shared(),
 5093        );
 5094        debug_assert!(
 5095            previous_task.is_none(),
 5096            "Did not change hint's resolve state after spawning its resolve"
 5097        );
 5098        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5099        None
 5100    }
 5101
 5102    fn resolve_inlay_hint(
 5103        &self,
 5104        mut hint: InlayHint,
 5105        buffer: Entity<Buffer>,
 5106        server_id: LanguageServerId,
 5107        cx: &mut Context<Self>,
 5108    ) -> Task<anyhow::Result<InlayHint>> {
 5109        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5110            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5111            {
 5112                hint.resolve_state = ResolveState::Resolved;
 5113                return Task::ready(Ok(hint));
 5114            }
 5115            let request = proto::ResolveInlayHint {
 5116                project_id,
 5117                buffer_id: buffer.read(cx).remote_id().into(),
 5118                language_server_id: server_id.0 as u64,
 5119                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5120            };
 5121            cx.background_spawn(async move {
 5122                let response = upstream_client
 5123                    .request(request)
 5124                    .await
 5125                    .context("inlay hints proto request")?;
 5126                match response.hint {
 5127                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5128                        .context("inlay hints proto resolve response conversion"),
 5129                    None => Ok(hint),
 5130                }
 5131            })
 5132        } else {
 5133            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5134                self.language_server_for_local_buffer(buffer, server_id, cx)
 5135                    .map(|(_, server)| server.clone())
 5136            }) else {
 5137                return Task::ready(Ok(hint));
 5138            };
 5139            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5140                return Task::ready(Ok(hint));
 5141            }
 5142            let buffer_snapshot = buffer.read(cx).snapshot();
 5143            cx.spawn(async move |_, cx| {
 5144                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5145                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5146                );
 5147                let resolved_hint = resolve_task
 5148                    .await
 5149                    .into_response()
 5150                    .context("inlay hint resolve LSP request")?;
 5151                let resolved_hint = InlayHints::lsp_to_project_hint(
 5152                    resolved_hint,
 5153                    &buffer,
 5154                    server_id,
 5155                    ResolveState::Resolved,
 5156                    false,
 5157                    cx,
 5158                )
 5159                .await?;
 5160                Ok(resolved_hint)
 5161            })
 5162        }
 5163    }
 5164
 5165    pub fn resolve_color_presentation(
 5166        &mut self,
 5167        mut color: DocumentColor,
 5168        buffer: Entity<Buffer>,
 5169        server_id: LanguageServerId,
 5170        cx: &mut Context<Self>,
 5171    ) -> Task<Result<DocumentColor>> {
 5172        if color.resolved {
 5173            return Task::ready(Ok(color));
 5174        }
 5175
 5176        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5177            let start = color.lsp_range.start;
 5178            let end = color.lsp_range.end;
 5179            let request = proto::GetColorPresentation {
 5180                project_id,
 5181                server_id: server_id.to_proto(),
 5182                buffer_id: buffer.read(cx).remote_id().into(),
 5183                color: Some(proto::ColorInformation {
 5184                    red: color.color.red,
 5185                    green: color.color.green,
 5186                    blue: color.color.blue,
 5187                    alpha: color.color.alpha,
 5188                    lsp_range_start: Some(proto::PointUtf16 {
 5189                        row: start.line,
 5190                        column: start.character,
 5191                    }),
 5192                    lsp_range_end: Some(proto::PointUtf16 {
 5193                        row: end.line,
 5194                        column: end.character,
 5195                    }),
 5196                }),
 5197            };
 5198            cx.background_spawn(async move {
 5199                let response = upstream_client
 5200                    .request(request)
 5201                    .await
 5202                    .context("color presentation proto request")?;
 5203                color.resolved = true;
 5204                color.color_presentations = response
 5205                    .presentations
 5206                    .into_iter()
 5207                    .map(|presentation| ColorPresentation {
 5208                        label: SharedString::from(presentation.label),
 5209                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5210                        additional_text_edits: presentation
 5211                            .additional_text_edits
 5212                            .into_iter()
 5213                            .filter_map(deserialize_lsp_edit)
 5214                            .collect(),
 5215                    })
 5216                    .collect();
 5217                Ok(color)
 5218            })
 5219        } else {
 5220            let path = match buffer
 5221                .update(cx, |buffer, cx| {
 5222                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5223                })
 5224                .context("buffer with the missing path")
 5225            {
 5226                Ok(path) => path,
 5227                Err(e) => return Task::ready(Err(e)),
 5228            };
 5229            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5230                self.language_server_for_local_buffer(buffer, server_id, cx)
 5231                    .map(|(_, server)| server.clone())
 5232            }) else {
 5233                return Task::ready(Ok(color));
 5234            };
 5235            cx.background_spawn(async move {
 5236                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5237                    lsp::ColorPresentationParams {
 5238                        text_document: make_text_document_identifier(&path)?,
 5239                        color: color.color,
 5240                        range: color.lsp_range,
 5241                        work_done_progress_params: Default::default(),
 5242                        partial_result_params: Default::default(),
 5243                    },
 5244                );
 5245                color.color_presentations = resolve_task
 5246                    .await
 5247                    .into_response()
 5248                    .context("color presentation resolve LSP request")?
 5249                    .into_iter()
 5250                    .map(|presentation| ColorPresentation {
 5251                        label: SharedString::from(presentation.label),
 5252                        text_edit: presentation.text_edit,
 5253                        additional_text_edits: presentation
 5254                            .additional_text_edits
 5255                            .unwrap_or_default(),
 5256                    })
 5257                    .collect();
 5258                color.resolved = true;
 5259                Ok(color)
 5260            })
 5261        }
 5262    }
 5263
 5264    pub(crate) fn linked_edits(
 5265        &mut self,
 5266        buffer: &Entity<Buffer>,
 5267        position: Anchor,
 5268        cx: &mut Context<Self>,
 5269    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5270        let snapshot = buffer.read(cx).snapshot();
 5271        let scope = snapshot.language_scope_at(position);
 5272        let Some(server_id) = self
 5273            .as_local()
 5274            .and_then(|local| {
 5275                buffer.update(cx, |buffer, cx| {
 5276                    local
 5277                        .language_servers_for_buffer(buffer, cx)
 5278                        .filter(|(_, server)| {
 5279                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5280                        })
 5281                        .filter(|(adapter, _)| {
 5282                            scope
 5283                                .as_ref()
 5284                                .map(|scope| scope.language_allowed(&adapter.name))
 5285                                .unwrap_or(true)
 5286                        })
 5287                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5288                        .next()
 5289                })
 5290            })
 5291            .or_else(|| {
 5292                self.upstream_client()
 5293                    .is_some()
 5294                    .then_some(LanguageServerToQuery::FirstCapable)
 5295            })
 5296            .filter(|_| {
 5297                maybe!({
 5298                    let language = buffer.read(cx).language_at(position)?;
 5299                    Some(
 5300                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5301                            .linked_edits,
 5302                    )
 5303                }) == Some(true)
 5304            })
 5305        else {
 5306            return Task::ready(Ok(Vec::new()));
 5307        };
 5308
 5309        self.request_lsp(
 5310            buffer.clone(),
 5311            server_id,
 5312            LinkedEditingRange { position },
 5313            cx,
 5314        )
 5315    }
 5316
 5317    fn apply_on_type_formatting(
 5318        &mut self,
 5319        buffer: Entity<Buffer>,
 5320        position: Anchor,
 5321        trigger: String,
 5322        cx: &mut Context<Self>,
 5323    ) -> Task<Result<Option<Transaction>>> {
 5324        if let Some((client, project_id)) = self.upstream_client() {
 5325            if !self.check_if_capable_for_proto_request(
 5326                &buffer,
 5327                |capabilities| {
 5328                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5329                },
 5330                cx,
 5331            ) {
 5332                return Task::ready(Ok(None));
 5333            }
 5334            let request = proto::OnTypeFormatting {
 5335                project_id,
 5336                buffer_id: buffer.read(cx).remote_id().into(),
 5337                position: Some(serialize_anchor(&position)),
 5338                trigger,
 5339                version: serialize_version(&buffer.read(cx).version()),
 5340            };
 5341            cx.background_spawn(async move {
 5342                client
 5343                    .request(request)
 5344                    .await?
 5345                    .transaction
 5346                    .map(language::proto::deserialize_transaction)
 5347                    .transpose()
 5348            })
 5349        } else if let Some(local) = self.as_local_mut() {
 5350            let buffer_id = buffer.read(cx).remote_id();
 5351            local.buffers_being_formatted.insert(buffer_id);
 5352            cx.spawn(async move |this, cx| {
 5353                let _cleanup = defer({
 5354                    let this = this.clone();
 5355                    let mut cx = cx.clone();
 5356                    move || {
 5357                        this.update(&mut cx, |this, _| {
 5358                            if let Some(local) = this.as_local_mut() {
 5359                                local.buffers_being_formatted.remove(&buffer_id);
 5360                            }
 5361                        })
 5362                        .ok();
 5363                    }
 5364                });
 5365
 5366                buffer
 5367                    .update(cx, |buffer, _| {
 5368                        buffer.wait_for_edits(Some(position.timestamp))
 5369                    })?
 5370                    .await?;
 5371                this.update(cx, |this, cx| {
 5372                    let position = position.to_point_utf16(buffer.read(cx));
 5373                    this.on_type_format(buffer, position, trigger, false, cx)
 5374                })?
 5375                .await
 5376            })
 5377        } else {
 5378            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5379        }
 5380    }
 5381
 5382    pub fn on_type_format<T: ToPointUtf16>(
 5383        &mut self,
 5384        buffer: Entity<Buffer>,
 5385        position: T,
 5386        trigger: String,
 5387        push_to_history: bool,
 5388        cx: &mut Context<Self>,
 5389    ) -> Task<Result<Option<Transaction>>> {
 5390        let position = position.to_point_utf16(buffer.read(cx));
 5391        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5392    }
 5393
 5394    fn on_type_format_impl(
 5395        &mut self,
 5396        buffer: Entity<Buffer>,
 5397        position: PointUtf16,
 5398        trigger: String,
 5399        push_to_history: bool,
 5400        cx: &mut Context<Self>,
 5401    ) -> Task<Result<Option<Transaction>>> {
 5402        let options = buffer.update(cx, |buffer, cx| {
 5403            lsp_command::lsp_formatting_options(
 5404                language_settings(
 5405                    buffer.language_at(position).map(|l| l.name()),
 5406                    buffer.file(),
 5407                    cx,
 5408                )
 5409                .as_ref(),
 5410            )
 5411        });
 5412
 5413        cx.spawn(async move |this, cx| {
 5414            if let Some(waiter) =
 5415                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5416            {
 5417                waiter.await?;
 5418            }
 5419            cx.update(|cx| {
 5420                this.update(cx, |this, cx| {
 5421                    this.request_lsp(
 5422                        buffer.clone(),
 5423                        LanguageServerToQuery::FirstCapable,
 5424                        OnTypeFormatting {
 5425                            position,
 5426                            trigger,
 5427                            options,
 5428                            push_to_history,
 5429                        },
 5430                        cx,
 5431                    )
 5432                })
 5433            })??
 5434            .await
 5435        })
 5436    }
 5437
 5438    pub fn definitions(
 5439        &mut self,
 5440        buffer: &Entity<Buffer>,
 5441        position: PointUtf16,
 5442        cx: &mut Context<Self>,
 5443    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5444        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5445            let request = GetDefinitions { position };
 5446            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5447                return Task::ready(Ok(None));
 5448            }
 5449            let request_task = upstream_client.request_lsp(
 5450                project_id,
 5451                None,
 5452                LSP_REQUEST_TIMEOUT,
 5453                cx.background_executor().clone(),
 5454                request.to_proto(project_id, buffer.read(cx)),
 5455            );
 5456            let buffer = buffer.clone();
 5457            cx.spawn(async move |weak_lsp_store, cx| {
 5458                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5459                    return Ok(None);
 5460                };
 5461                let Some(responses) = request_task.await? else {
 5462                    return Ok(None);
 5463                };
 5464                let actions = join_all(responses.payload.into_iter().map(|response| {
 5465                    GetDefinitions { position }.response_from_proto(
 5466                        response.response,
 5467                        lsp_store.clone(),
 5468                        buffer.clone(),
 5469                        cx.clone(),
 5470                    )
 5471                }))
 5472                .await;
 5473
 5474                Ok(Some(
 5475                    actions
 5476                        .into_iter()
 5477                        .collect::<Result<Vec<Vec<_>>>>()?
 5478                        .into_iter()
 5479                        .flatten()
 5480                        .dedup()
 5481                        .collect(),
 5482                ))
 5483            })
 5484        } else {
 5485            let definitions_task = self.request_multiple_lsp_locally(
 5486                buffer,
 5487                Some(position),
 5488                GetDefinitions { position },
 5489                cx,
 5490            );
 5491            cx.background_spawn(async move {
 5492                Ok(Some(
 5493                    definitions_task
 5494                        .await
 5495                        .into_iter()
 5496                        .flat_map(|(_, definitions)| definitions)
 5497                        .dedup()
 5498                        .collect(),
 5499                ))
 5500            })
 5501        }
 5502    }
 5503
 5504    pub fn declarations(
 5505        &mut self,
 5506        buffer: &Entity<Buffer>,
 5507        position: PointUtf16,
 5508        cx: &mut Context<Self>,
 5509    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5510        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5511            let request = GetDeclarations { position };
 5512            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5513                return Task::ready(Ok(None));
 5514            }
 5515            let request_task = upstream_client.request_lsp(
 5516                project_id,
 5517                None,
 5518                LSP_REQUEST_TIMEOUT,
 5519                cx.background_executor().clone(),
 5520                request.to_proto(project_id, buffer.read(cx)),
 5521            );
 5522            let buffer = buffer.clone();
 5523            cx.spawn(async move |weak_lsp_store, cx| {
 5524                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5525                    return Ok(None);
 5526                };
 5527                let Some(responses) = request_task.await? else {
 5528                    return Ok(None);
 5529                };
 5530                let actions = join_all(responses.payload.into_iter().map(|response| {
 5531                    GetDeclarations { position }.response_from_proto(
 5532                        response.response,
 5533                        lsp_store.clone(),
 5534                        buffer.clone(),
 5535                        cx.clone(),
 5536                    )
 5537                }))
 5538                .await;
 5539
 5540                Ok(Some(
 5541                    actions
 5542                        .into_iter()
 5543                        .collect::<Result<Vec<Vec<_>>>>()?
 5544                        .into_iter()
 5545                        .flatten()
 5546                        .dedup()
 5547                        .collect(),
 5548                ))
 5549            })
 5550        } else {
 5551            let declarations_task = self.request_multiple_lsp_locally(
 5552                buffer,
 5553                Some(position),
 5554                GetDeclarations { position },
 5555                cx,
 5556            );
 5557            cx.background_spawn(async move {
 5558                Ok(Some(
 5559                    declarations_task
 5560                        .await
 5561                        .into_iter()
 5562                        .flat_map(|(_, declarations)| declarations)
 5563                        .dedup()
 5564                        .collect(),
 5565                ))
 5566            })
 5567        }
 5568    }
 5569
 5570    pub fn type_definitions(
 5571        &mut self,
 5572        buffer: &Entity<Buffer>,
 5573        position: PointUtf16,
 5574        cx: &mut Context<Self>,
 5575    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5576        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5577            let request = GetTypeDefinitions { position };
 5578            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5579                return Task::ready(Ok(None));
 5580            }
 5581            let request_task = upstream_client.request_lsp(
 5582                project_id,
 5583                None,
 5584                LSP_REQUEST_TIMEOUT,
 5585                cx.background_executor().clone(),
 5586                request.to_proto(project_id, buffer.read(cx)),
 5587            );
 5588            let buffer = buffer.clone();
 5589            cx.spawn(async move |weak_lsp_store, cx| {
 5590                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5591                    return Ok(None);
 5592                };
 5593                let Some(responses) = request_task.await? else {
 5594                    return Ok(None);
 5595                };
 5596                let actions = join_all(responses.payload.into_iter().map(|response| {
 5597                    GetTypeDefinitions { position }.response_from_proto(
 5598                        response.response,
 5599                        lsp_store.clone(),
 5600                        buffer.clone(),
 5601                        cx.clone(),
 5602                    )
 5603                }))
 5604                .await;
 5605
 5606                Ok(Some(
 5607                    actions
 5608                        .into_iter()
 5609                        .collect::<Result<Vec<Vec<_>>>>()?
 5610                        .into_iter()
 5611                        .flatten()
 5612                        .dedup()
 5613                        .collect(),
 5614                ))
 5615            })
 5616        } else {
 5617            let type_definitions_task = self.request_multiple_lsp_locally(
 5618                buffer,
 5619                Some(position),
 5620                GetTypeDefinitions { position },
 5621                cx,
 5622            );
 5623            cx.background_spawn(async move {
 5624                Ok(Some(
 5625                    type_definitions_task
 5626                        .await
 5627                        .into_iter()
 5628                        .flat_map(|(_, type_definitions)| type_definitions)
 5629                        .dedup()
 5630                        .collect(),
 5631                ))
 5632            })
 5633        }
 5634    }
 5635
 5636    pub fn implementations(
 5637        &mut self,
 5638        buffer: &Entity<Buffer>,
 5639        position: PointUtf16,
 5640        cx: &mut Context<Self>,
 5641    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5642        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5643            let request = GetImplementations { position };
 5644            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5645                return Task::ready(Ok(None));
 5646            }
 5647            let request_task = upstream_client.request_lsp(
 5648                project_id,
 5649                None,
 5650                LSP_REQUEST_TIMEOUT,
 5651                cx.background_executor().clone(),
 5652                request.to_proto(project_id, buffer.read(cx)),
 5653            );
 5654            let buffer = buffer.clone();
 5655            cx.spawn(async move |weak_lsp_store, cx| {
 5656                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5657                    return Ok(None);
 5658                };
 5659                let Some(responses) = request_task.await? else {
 5660                    return Ok(None);
 5661                };
 5662                let actions = join_all(responses.payload.into_iter().map(|response| {
 5663                    GetImplementations { position }.response_from_proto(
 5664                        response.response,
 5665                        lsp_store.clone(),
 5666                        buffer.clone(),
 5667                        cx.clone(),
 5668                    )
 5669                }))
 5670                .await;
 5671
 5672                Ok(Some(
 5673                    actions
 5674                        .into_iter()
 5675                        .collect::<Result<Vec<Vec<_>>>>()?
 5676                        .into_iter()
 5677                        .flatten()
 5678                        .dedup()
 5679                        .collect(),
 5680                ))
 5681            })
 5682        } else {
 5683            let implementations_task = self.request_multiple_lsp_locally(
 5684                buffer,
 5685                Some(position),
 5686                GetImplementations { position },
 5687                cx,
 5688            );
 5689            cx.background_spawn(async move {
 5690                Ok(Some(
 5691                    implementations_task
 5692                        .await
 5693                        .into_iter()
 5694                        .flat_map(|(_, implementations)| implementations)
 5695                        .dedup()
 5696                        .collect(),
 5697                ))
 5698            })
 5699        }
 5700    }
 5701
 5702    pub fn references(
 5703        &mut self,
 5704        buffer: &Entity<Buffer>,
 5705        position: PointUtf16,
 5706        cx: &mut Context<Self>,
 5707    ) -> Task<Result<Option<Vec<Location>>>> {
 5708        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5709            let request = GetReferences { position };
 5710            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5711                return Task::ready(Ok(None));
 5712            }
 5713
 5714            let request_task = upstream_client.request_lsp(
 5715                project_id,
 5716                None,
 5717                LSP_REQUEST_TIMEOUT,
 5718                cx.background_executor().clone(),
 5719                request.to_proto(project_id, buffer.read(cx)),
 5720            );
 5721            let buffer = buffer.clone();
 5722            cx.spawn(async move |weak_lsp_store, cx| {
 5723                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5724                    return Ok(None);
 5725                };
 5726                let Some(responses) = request_task.await? else {
 5727                    return Ok(None);
 5728                };
 5729
 5730                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5731                    GetReferences { position }.response_from_proto(
 5732                        lsp_response.response,
 5733                        lsp_store.clone(),
 5734                        buffer.clone(),
 5735                        cx.clone(),
 5736                    )
 5737                }))
 5738                .await
 5739                .into_iter()
 5740                .collect::<Result<Vec<Vec<_>>>>()?
 5741                .into_iter()
 5742                .flatten()
 5743                .dedup()
 5744                .collect();
 5745                Ok(Some(locations))
 5746            })
 5747        } else {
 5748            let references_task = self.request_multiple_lsp_locally(
 5749                buffer,
 5750                Some(position),
 5751                GetReferences { position },
 5752                cx,
 5753            );
 5754            cx.background_spawn(async move {
 5755                Ok(Some(
 5756                    references_task
 5757                        .await
 5758                        .into_iter()
 5759                        .flat_map(|(_, references)| references)
 5760                        .dedup()
 5761                        .collect(),
 5762                ))
 5763            })
 5764        }
 5765    }
 5766
 5767    pub fn code_actions(
 5768        &mut self,
 5769        buffer: &Entity<Buffer>,
 5770        range: Range<Anchor>,
 5771        kinds: Option<Vec<CodeActionKind>>,
 5772        cx: &mut Context<Self>,
 5773    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5774        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5775            let request = GetCodeActions {
 5776                range: range.clone(),
 5777                kinds: kinds.clone(),
 5778            };
 5779            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5780                return Task::ready(Ok(None));
 5781            }
 5782            let request_task = upstream_client.request_lsp(
 5783                project_id,
 5784                None,
 5785                LSP_REQUEST_TIMEOUT,
 5786                cx.background_executor().clone(),
 5787                request.to_proto(project_id, buffer.read(cx)),
 5788            );
 5789            let buffer = buffer.clone();
 5790            cx.spawn(async move |weak_lsp_store, cx| {
 5791                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5792                    return Ok(None);
 5793                };
 5794                let Some(responses) = request_task.await? else {
 5795                    return Ok(None);
 5796                };
 5797                let actions = join_all(responses.payload.into_iter().map(|response| {
 5798                    GetCodeActions {
 5799                        range: range.clone(),
 5800                        kinds: kinds.clone(),
 5801                    }
 5802                    .response_from_proto(
 5803                        response.response,
 5804                        lsp_store.clone(),
 5805                        buffer.clone(),
 5806                        cx.clone(),
 5807                    )
 5808                }))
 5809                .await;
 5810
 5811                Ok(Some(
 5812                    actions
 5813                        .into_iter()
 5814                        .collect::<Result<Vec<Vec<_>>>>()?
 5815                        .into_iter()
 5816                        .flatten()
 5817                        .collect(),
 5818                ))
 5819            })
 5820        } else {
 5821            let all_actions_task = self.request_multiple_lsp_locally(
 5822                buffer,
 5823                Some(range.start),
 5824                GetCodeActions { range, kinds },
 5825                cx,
 5826            );
 5827            cx.background_spawn(async move {
 5828                Ok(Some(
 5829                    all_actions_task
 5830                        .await
 5831                        .into_iter()
 5832                        .flat_map(|(_, actions)| actions)
 5833                        .collect(),
 5834                ))
 5835            })
 5836        }
 5837    }
 5838
 5839    pub fn code_lens_actions(
 5840        &mut self,
 5841        buffer: &Entity<Buffer>,
 5842        cx: &mut Context<Self>,
 5843    ) -> CodeLensTask {
 5844        let version_queried_for = buffer.read(cx).version();
 5845        let buffer_id = buffer.read(cx).remote_id();
 5846        let existing_servers = self.as_local().map(|local| {
 5847            local
 5848                .buffers_opened_in_servers
 5849                .get(&buffer_id)
 5850                .cloned()
 5851                .unwrap_or_default()
 5852        });
 5853
 5854        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5855            if let Some(cached_lens) = &lsp_data.code_lens {
 5856                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5857                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5858                        existing_servers != cached_lens.lens.keys().copied().collect()
 5859                    });
 5860                    if !has_different_servers {
 5861                        return Task::ready(Ok(Some(
 5862                            cached_lens.lens.values().flatten().cloned().collect(),
 5863                        )))
 5864                        .shared();
 5865                    }
 5866                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5867                    if !version_queried_for.changed_since(updating_for) {
 5868                        return running_update.clone();
 5869                    }
 5870                }
 5871            }
 5872        }
 5873
 5874        let lens_lsp_data = self
 5875            .latest_lsp_data(buffer, cx)
 5876            .code_lens
 5877            .get_or_insert_default();
 5878        let buffer = buffer.clone();
 5879        let query_version_queried_for = version_queried_for.clone();
 5880        let new_task = cx
 5881            .spawn(async move |lsp_store, cx| {
 5882                cx.background_executor()
 5883                    .timer(Duration::from_millis(30))
 5884                    .await;
 5885                let fetched_lens = lsp_store
 5886                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5887                    .map_err(Arc::new)?
 5888                    .await
 5889                    .context("fetching code lens")
 5890                    .map_err(Arc::new);
 5891                let fetched_lens = match fetched_lens {
 5892                    Ok(fetched_lens) => fetched_lens,
 5893                    Err(e) => {
 5894                        lsp_store
 5895                            .update(cx, |lsp_store, _| {
 5896                                if let Some(lens_lsp_data) = lsp_store
 5897                                    .lsp_data
 5898                                    .get_mut(&buffer_id)
 5899                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5900                                {
 5901                                    lens_lsp_data.update = None;
 5902                                }
 5903                            })
 5904                            .ok();
 5905                        return Err(e);
 5906                    }
 5907                };
 5908
 5909                lsp_store
 5910                    .update(cx, |lsp_store, _| {
 5911                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5912                        let code_lens = lsp_data.code_lens.as_mut()?;
 5913                        if let Some(fetched_lens) = fetched_lens {
 5914                            if lsp_data.buffer_version == query_version_queried_for {
 5915                                code_lens.lens.extend(fetched_lens);
 5916                            } else if !lsp_data
 5917                                .buffer_version
 5918                                .changed_since(&query_version_queried_for)
 5919                            {
 5920                                lsp_data.buffer_version = query_version_queried_for;
 5921                                code_lens.lens = fetched_lens;
 5922                            }
 5923                        }
 5924                        code_lens.update = None;
 5925                        Some(code_lens.lens.values().flatten().cloned().collect())
 5926                    })
 5927                    .map_err(Arc::new)
 5928            })
 5929            .shared();
 5930        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5931        new_task
 5932    }
 5933
 5934    fn fetch_code_lens(
 5935        &mut self,
 5936        buffer: &Entity<Buffer>,
 5937        cx: &mut Context<Self>,
 5938    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5939        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5940            let request = GetCodeLens;
 5941            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5942                return Task::ready(Ok(None));
 5943            }
 5944            let request_task = upstream_client.request_lsp(
 5945                project_id,
 5946                None,
 5947                LSP_REQUEST_TIMEOUT,
 5948                cx.background_executor().clone(),
 5949                request.to_proto(project_id, buffer.read(cx)),
 5950            );
 5951            let buffer = buffer.clone();
 5952            cx.spawn(async move |weak_lsp_store, cx| {
 5953                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5954                    return Ok(None);
 5955                };
 5956                let Some(responses) = request_task.await? else {
 5957                    return Ok(None);
 5958                };
 5959
 5960                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5961                    let lsp_store = lsp_store.clone();
 5962                    let buffer = buffer.clone();
 5963                    let cx = cx.clone();
 5964                    async move {
 5965                        (
 5966                            LanguageServerId::from_proto(response.server_id),
 5967                            GetCodeLens
 5968                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5969                                .await,
 5970                        )
 5971                    }
 5972                }))
 5973                .await;
 5974
 5975                let mut has_errors = false;
 5976                let code_lens_actions = code_lens_actions
 5977                    .into_iter()
 5978                    .filter_map(|(server_id, code_lens)| match code_lens {
 5979                        Ok(code_lens) => Some((server_id, code_lens)),
 5980                        Err(e) => {
 5981                            has_errors = true;
 5982                            log::error!("{e:#}");
 5983                            None
 5984                        }
 5985                    })
 5986                    .collect::<HashMap<_, _>>();
 5987                anyhow::ensure!(
 5988                    !has_errors || !code_lens_actions.is_empty(),
 5989                    "Failed to fetch code lens"
 5990                );
 5991                Ok(Some(code_lens_actions))
 5992            })
 5993        } else {
 5994            let code_lens_actions_task =
 5995                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5996            cx.background_spawn(async move {
 5997                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5998            })
 5999        }
 6000    }
 6001
 6002    #[inline(never)]
 6003    pub fn completions(
 6004        &self,
 6005        buffer: &Entity<Buffer>,
 6006        position: PointUtf16,
 6007        context: CompletionContext,
 6008        cx: &mut Context<Self>,
 6009    ) -> Task<Result<Vec<CompletionResponse>>> {
 6010        let language_registry = self.languages.clone();
 6011
 6012        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6013            let snapshot = buffer.read(cx).snapshot();
 6014            let offset = position.to_offset(&snapshot);
 6015            let scope = snapshot.language_scope_at(offset);
 6016            let capable_lsps = self.all_capable_for_proto_request(
 6017                buffer,
 6018                |server_name, capabilities| {
 6019                    capabilities.completion_provider.is_some()
 6020                        && scope
 6021                            .as_ref()
 6022                            .map(|scope| scope.language_allowed(server_name))
 6023                            .unwrap_or(true)
 6024                },
 6025                cx,
 6026            );
 6027            if capable_lsps.is_empty() {
 6028                return Task::ready(Ok(Vec::new()));
 6029            }
 6030
 6031            let language = buffer.read(cx).language().cloned();
 6032
 6033            // In the future, we should provide project guests with the names of LSP adapters,
 6034            // so that they can use the correct LSP adapter when computing labels. For now,
 6035            // guests just use the first LSP adapter associated with the buffer's language.
 6036            let lsp_adapter = language.as_ref().and_then(|language| {
 6037                language_registry
 6038                    .lsp_adapters(&language.name())
 6039                    .first()
 6040                    .cloned()
 6041            });
 6042
 6043            let buffer = buffer.clone();
 6044
 6045            cx.spawn(async move |this, cx| {
 6046                let requests = join_all(
 6047                    capable_lsps
 6048                        .into_iter()
 6049                        .map(|id| {
 6050                            let request = GetCompletions {
 6051                                position,
 6052                                context: context.clone(),
 6053                                server_id: Some(id),
 6054                            };
 6055                            let buffer = buffer.clone();
 6056                            let language = language.clone();
 6057                            let lsp_adapter = lsp_adapter.clone();
 6058                            let upstream_client = upstream_client.clone();
 6059                            let response = this
 6060                                .update(cx, |this, cx| {
 6061                                    this.send_lsp_proto_request(
 6062                                        buffer,
 6063                                        upstream_client,
 6064                                        project_id,
 6065                                        request,
 6066                                        cx,
 6067                                    )
 6068                                })
 6069                                .log_err();
 6070                            async move {
 6071                                let response = response?.await.log_err()?;
 6072
 6073                                let completions = populate_labels_for_completions(
 6074                                    response.completions,
 6075                                    language,
 6076                                    lsp_adapter,
 6077                                )
 6078                                .await;
 6079
 6080                                Some(CompletionResponse {
 6081                                    completions,
 6082                                    display_options: CompletionDisplayOptions::default(),
 6083                                    is_incomplete: response.is_incomplete,
 6084                                })
 6085                            }
 6086                        })
 6087                        .collect::<Vec<_>>(),
 6088                );
 6089                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6090            })
 6091        } else if let Some(local) = self.as_local() {
 6092            let snapshot = buffer.read(cx).snapshot();
 6093            let offset = position.to_offset(&snapshot);
 6094            let scope = snapshot.language_scope_at(offset);
 6095            let language = snapshot.language().cloned();
 6096            let completion_settings = language_settings(
 6097                language.as_ref().map(|language| language.name()),
 6098                buffer.read(cx).file(),
 6099                cx,
 6100            )
 6101            .completions
 6102            .clone();
 6103            if !completion_settings.lsp {
 6104                return Task::ready(Ok(Vec::new()));
 6105            }
 6106
 6107            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6108                local
 6109                    .language_servers_for_buffer(buffer, cx)
 6110                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6111                    .filter(|(adapter, _)| {
 6112                        scope
 6113                            .as_ref()
 6114                            .map(|scope| scope.language_allowed(&adapter.name))
 6115                            .unwrap_or(true)
 6116                    })
 6117                    .map(|(_, server)| server.server_id())
 6118                    .collect()
 6119            });
 6120
 6121            let buffer = buffer.clone();
 6122            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6123            let lsp_timeout = if lsp_timeout > 0 {
 6124                Some(Duration::from_millis(lsp_timeout))
 6125            } else {
 6126                None
 6127            };
 6128            cx.spawn(async move |this,  cx| {
 6129                let mut tasks = Vec::with_capacity(server_ids.len());
 6130                this.update(cx, |lsp_store, cx| {
 6131                    for server_id in server_ids {
 6132                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6133                        let lsp_timeout = lsp_timeout
 6134                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6135                        let mut timeout = cx.background_spawn(async move {
 6136                            match lsp_timeout {
 6137                                Some(lsp_timeout) => {
 6138                                    lsp_timeout.await;
 6139                                    true
 6140                                },
 6141                                None => false,
 6142                            }
 6143                        }).fuse();
 6144                        let mut lsp_request = lsp_store.request_lsp(
 6145                            buffer.clone(),
 6146                            LanguageServerToQuery::Other(server_id),
 6147                            GetCompletions {
 6148                                position,
 6149                                context: context.clone(),
 6150                                server_id: Some(server_id),
 6151                            },
 6152                            cx,
 6153                        ).fuse();
 6154                        let new_task = cx.background_spawn(async move {
 6155                            select_biased! {
 6156                                response = lsp_request => anyhow::Ok(Some(response?)),
 6157                                timeout_happened = timeout => {
 6158                                    if timeout_happened {
 6159                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6160                                        Ok(None)
 6161                                    } else {
 6162                                        let completions = lsp_request.await?;
 6163                                        Ok(Some(completions))
 6164                                    }
 6165                                },
 6166                            }
 6167                        });
 6168                        tasks.push((lsp_adapter, new_task));
 6169                    }
 6170                })?;
 6171
 6172                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6173                    let completion_response = task.await.ok()??;
 6174                    let completions = populate_labels_for_completions(
 6175                            completion_response.completions,
 6176                            language.clone(),
 6177                            lsp_adapter,
 6178                        )
 6179                        .await;
 6180                    Some(CompletionResponse {
 6181                        completions,
 6182                        display_options: CompletionDisplayOptions::default(),
 6183                        is_incomplete: completion_response.is_incomplete,
 6184                    })
 6185                });
 6186
 6187                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6188
 6189                Ok(responses.into_iter().flatten().collect())
 6190            })
 6191        } else {
 6192            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6193        }
 6194    }
 6195
 6196    pub fn resolve_completions(
 6197        &self,
 6198        buffer: Entity<Buffer>,
 6199        completion_indices: Vec<usize>,
 6200        completions: Rc<RefCell<Box<[Completion]>>>,
 6201        cx: &mut Context<Self>,
 6202    ) -> Task<Result<bool>> {
 6203        let client = self.upstream_client();
 6204        let buffer_id = buffer.read(cx).remote_id();
 6205        let buffer_snapshot = buffer.read(cx).snapshot();
 6206
 6207        if !self.check_if_capable_for_proto_request(
 6208            &buffer,
 6209            GetCompletions::can_resolve_completions,
 6210            cx,
 6211        ) {
 6212            return Task::ready(Ok(false));
 6213        }
 6214        cx.spawn(async move |lsp_store, cx| {
 6215            let mut did_resolve = false;
 6216            if let Some((client, project_id)) = client {
 6217                for completion_index in completion_indices {
 6218                    let server_id = {
 6219                        let completion = &completions.borrow()[completion_index];
 6220                        completion.source.server_id()
 6221                    };
 6222                    if let Some(server_id) = server_id {
 6223                        if Self::resolve_completion_remote(
 6224                            project_id,
 6225                            server_id,
 6226                            buffer_id,
 6227                            completions.clone(),
 6228                            completion_index,
 6229                            client.clone(),
 6230                        )
 6231                        .await
 6232                        .log_err()
 6233                        .is_some()
 6234                        {
 6235                            did_resolve = true;
 6236                        }
 6237                    } else {
 6238                        resolve_word_completion(
 6239                            &buffer_snapshot,
 6240                            &mut completions.borrow_mut()[completion_index],
 6241                        );
 6242                    }
 6243                }
 6244            } else {
 6245                for completion_index in completion_indices {
 6246                    let server_id = {
 6247                        let completion = &completions.borrow()[completion_index];
 6248                        completion.source.server_id()
 6249                    };
 6250                    if let Some(server_id) = server_id {
 6251                        let server_and_adapter = lsp_store
 6252                            .read_with(cx, |lsp_store, _| {
 6253                                let server = lsp_store.language_server_for_id(server_id)?;
 6254                                let adapter =
 6255                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6256                                Some((server, adapter))
 6257                            })
 6258                            .ok()
 6259                            .flatten();
 6260                        let Some((server, adapter)) = server_and_adapter else {
 6261                            continue;
 6262                        };
 6263
 6264                        let resolved = Self::resolve_completion_local(
 6265                            server,
 6266                            completions.clone(),
 6267                            completion_index,
 6268                        )
 6269                        .await
 6270                        .log_err()
 6271                        .is_some();
 6272                        if resolved {
 6273                            Self::regenerate_completion_labels(
 6274                                adapter,
 6275                                &buffer_snapshot,
 6276                                completions.clone(),
 6277                                completion_index,
 6278                            )
 6279                            .await
 6280                            .log_err();
 6281                            did_resolve = true;
 6282                        }
 6283                    } else {
 6284                        resolve_word_completion(
 6285                            &buffer_snapshot,
 6286                            &mut completions.borrow_mut()[completion_index],
 6287                        );
 6288                    }
 6289                }
 6290            }
 6291
 6292            Ok(did_resolve)
 6293        })
 6294    }
 6295
 6296    async fn resolve_completion_local(
 6297        server: Arc<lsp::LanguageServer>,
 6298        completions: Rc<RefCell<Box<[Completion]>>>,
 6299        completion_index: usize,
 6300    ) -> Result<()> {
 6301        let server_id = server.server_id();
 6302        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6303            return Ok(());
 6304        }
 6305
 6306        let request = {
 6307            let completion = &completions.borrow()[completion_index];
 6308            match &completion.source {
 6309                CompletionSource::Lsp {
 6310                    lsp_completion,
 6311                    resolved,
 6312                    server_id: completion_server_id,
 6313                    ..
 6314                } => {
 6315                    if *resolved {
 6316                        return Ok(());
 6317                    }
 6318                    anyhow::ensure!(
 6319                        server_id == *completion_server_id,
 6320                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6321                    );
 6322                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6323                }
 6324                CompletionSource::BufferWord { .. }
 6325                | CompletionSource::Dap { .. }
 6326                | CompletionSource::Custom => {
 6327                    return Ok(());
 6328                }
 6329            }
 6330        };
 6331        let resolved_completion = request
 6332            .await
 6333            .into_response()
 6334            .context("resolve completion")?;
 6335
 6336        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6337        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6338
 6339        let mut completions = completions.borrow_mut();
 6340        let completion = &mut completions[completion_index];
 6341        if let CompletionSource::Lsp {
 6342            lsp_completion,
 6343            resolved,
 6344            server_id: completion_server_id,
 6345            ..
 6346        } = &mut completion.source
 6347        {
 6348            if *resolved {
 6349                return Ok(());
 6350            }
 6351            anyhow::ensure!(
 6352                server_id == *completion_server_id,
 6353                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6354            );
 6355            *lsp_completion = Box::new(resolved_completion);
 6356            *resolved = true;
 6357        }
 6358        Ok(())
 6359    }
 6360
 6361    async fn regenerate_completion_labels(
 6362        adapter: Arc<CachedLspAdapter>,
 6363        snapshot: &BufferSnapshot,
 6364        completions: Rc<RefCell<Box<[Completion]>>>,
 6365        completion_index: usize,
 6366    ) -> Result<()> {
 6367        let completion_item = completions.borrow()[completion_index]
 6368            .source
 6369            .lsp_completion(true)
 6370            .map(Cow::into_owned);
 6371        if let Some(lsp_documentation) = completion_item
 6372            .as_ref()
 6373            .and_then(|completion_item| completion_item.documentation.clone())
 6374        {
 6375            let mut completions = completions.borrow_mut();
 6376            let completion = &mut completions[completion_index];
 6377            completion.documentation = Some(lsp_documentation.into());
 6378        } else {
 6379            let mut completions = completions.borrow_mut();
 6380            let completion = &mut completions[completion_index];
 6381            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6382        }
 6383
 6384        let mut new_label = match completion_item {
 6385            Some(completion_item) => {
 6386                // 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
 6387                // So we have to update the label here anyway...
 6388                let language = snapshot.language();
 6389                match language {
 6390                    Some(language) => {
 6391                        adapter
 6392                            .labels_for_completions(
 6393                                std::slice::from_ref(&completion_item),
 6394                                language,
 6395                            )
 6396                            .await?
 6397                    }
 6398                    None => Vec::new(),
 6399                }
 6400                .pop()
 6401                .flatten()
 6402                .unwrap_or_else(|| {
 6403                    CodeLabel::fallback_for_completion(
 6404                        &completion_item,
 6405                        language.map(|language| language.as_ref()),
 6406                    )
 6407                })
 6408            }
 6409            None => CodeLabel::plain(
 6410                completions.borrow()[completion_index].new_text.clone(),
 6411                None,
 6412            ),
 6413        };
 6414        ensure_uniform_list_compatible_label(&mut new_label);
 6415
 6416        let mut completions = completions.borrow_mut();
 6417        let completion = &mut completions[completion_index];
 6418        if completion.label.filter_text() == new_label.filter_text() {
 6419            completion.label = new_label;
 6420        } else {
 6421            log::error!(
 6422                "Resolved completion changed display label from {} to {}. \
 6423                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6424                completion.label.text(),
 6425                new_label.text(),
 6426                completion.label.filter_text(),
 6427                new_label.filter_text()
 6428            );
 6429        }
 6430
 6431        Ok(())
 6432    }
 6433
 6434    async fn resolve_completion_remote(
 6435        project_id: u64,
 6436        server_id: LanguageServerId,
 6437        buffer_id: BufferId,
 6438        completions: Rc<RefCell<Box<[Completion]>>>,
 6439        completion_index: usize,
 6440        client: AnyProtoClient,
 6441    ) -> Result<()> {
 6442        let lsp_completion = {
 6443            let completion = &completions.borrow()[completion_index];
 6444            match &completion.source {
 6445                CompletionSource::Lsp {
 6446                    lsp_completion,
 6447                    resolved,
 6448                    server_id: completion_server_id,
 6449                    ..
 6450                } => {
 6451                    anyhow::ensure!(
 6452                        server_id == *completion_server_id,
 6453                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6454                    );
 6455                    if *resolved {
 6456                        return Ok(());
 6457                    }
 6458                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6459                }
 6460                CompletionSource::Custom
 6461                | CompletionSource::Dap { .. }
 6462                | CompletionSource::BufferWord { .. } => {
 6463                    return Ok(());
 6464                }
 6465            }
 6466        };
 6467        let request = proto::ResolveCompletionDocumentation {
 6468            project_id,
 6469            language_server_id: server_id.0 as u64,
 6470            lsp_completion,
 6471            buffer_id: buffer_id.into(),
 6472        };
 6473
 6474        let response = client
 6475            .request(request)
 6476            .await
 6477            .context("completion documentation resolve proto request")?;
 6478        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6479
 6480        let documentation = if response.documentation.is_empty() {
 6481            CompletionDocumentation::Undocumented
 6482        } else if response.documentation_is_markdown {
 6483            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6484        } else if response.documentation.lines().count() <= 1 {
 6485            CompletionDocumentation::SingleLine(response.documentation.into())
 6486        } else {
 6487            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6488        };
 6489
 6490        let mut completions = completions.borrow_mut();
 6491        let completion = &mut completions[completion_index];
 6492        completion.documentation = Some(documentation);
 6493        if let CompletionSource::Lsp {
 6494            insert_range,
 6495            lsp_completion,
 6496            resolved,
 6497            server_id: completion_server_id,
 6498            lsp_defaults: _,
 6499        } = &mut completion.source
 6500        {
 6501            let completion_insert_range = response
 6502                .old_insert_start
 6503                .and_then(deserialize_anchor)
 6504                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6505            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6506
 6507            if *resolved {
 6508                return Ok(());
 6509            }
 6510            anyhow::ensure!(
 6511                server_id == *completion_server_id,
 6512                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6513            );
 6514            *lsp_completion = Box::new(resolved_lsp_completion);
 6515            *resolved = true;
 6516        }
 6517
 6518        let replace_range = response
 6519            .old_replace_start
 6520            .and_then(deserialize_anchor)
 6521            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6522        if let Some((old_replace_start, old_replace_end)) = replace_range
 6523            && !response.new_text.is_empty()
 6524        {
 6525            completion.new_text = response.new_text;
 6526            completion.replace_range = old_replace_start..old_replace_end;
 6527        }
 6528
 6529        Ok(())
 6530    }
 6531
 6532    pub fn apply_additional_edits_for_completion(
 6533        &self,
 6534        buffer_handle: Entity<Buffer>,
 6535        completions: Rc<RefCell<Box<[Completion]>>>,
 6536        completion_index: usize,
 6537        push_to_history: bool,
 6538        cx: &mut Context<Self>,
 6539    ) -> Task<Result<Option<Transaction>>> {
 6540        if let Some((client, project_id)) = self.upstream_client() {
 6541            let buffer = buffer_handle.read(cx);
 6542            let buffer_id = buffer.remote_id();
 6543            cx.spawn(async move |_, cx| {
 6544                let request = {
 6545                    let completion = completions.borrow()[completion_index].clone();
 6546                    proto::ApplyCompletionAdditionalEdits {
 6547                        project_id,
 6548                        buffer_id: buffer_id.into(),
 6549                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6550                            replace_range: completion.replace_range,
 6551                            new_text: completion.new_text,
 6552                            source: completion.source,
 6553                        })),
 6554                    }
 6555                };
 6556
 6557                if let Some(transaction) = client.request(request).await?.transaction {
 6558                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6559                    buffer_handle
 6560                        .update(cx, |buffer, _| {
 6561                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6562                        })?
 6563                        .await?;
 6564                    if push_to_history {
 6565                        buffer_handle.update(cx, |buffer, _| {
 6566                            buffer.push_transaction(transaction.clone(), Instant::now());
 6567                            buffer.finalize_last_transaction();
 6568                        })?;
 6569                    }
 6570                    Ok(Some(transaction))
 6571                } else {
 6572                    Ok(None)
 6573                }
 6574            })
 6575        } else {
 6576            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6577                let completion = &completions.borrow()[completion_index];
 6578                let server_id = completion.source.server_id()?;
 6579                Some(
 6580                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6581                        .1
 6582                        .clone(),
 6583                )
 6584            }) else {
 6585                return Task::ready(Ok(None));
 6586            };
 6587
 6588            cx.spawn(async move |this, cx| {
 6589                Self::resolve_completion_local(
 6590                    server.clone(),
 6591                    completions.clone(),
 6592                    completion_index,
 6593                )
 6594                .await
 6595                .context("resolving completion")?;
 6596                let completion = completions.borrow()[completion_index].clone();
 6597                let additional_text_edits = completion
 6598                    .source
 6599                    .lsp_completion(true)
 6600                    .as_ref()
 6601                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6602                if let Some(edits) = additional_text_edits {
 6603                    let edits = this
 6604                        .update(cx, |this, cx| {
 6605                            this.as_local_mut().unwrap().edits_from_lsp(
 6606                                &buffer_handle,
 6607                                edits,
 6608                                server.server_id(),
 6609                                None,
 6610                                cx,
 6611                            )
 6612                        })?
 6613                        .await?;
 6614
 6615                    buffer_handle.update(cx, |buffer, cx| {
 6616                        buffer.finalize_last_transaction();
 6617                        buffer.start_transaction();
 6618
 6619                        for (range, text) in edits {
 6620                            let primary = &completion.replace_range;
 6621
 6622                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6623                            // and the primary completion is just an insertion (empty range), then this is likely
 6624                            // an auto-import scenario and should not be considered overlapping
 6625                            // https://github.com/zed-industries/zed/issues/26136
 6626                            let is_file_start_auto_import = {
 6627                                let snapshot = buffer.snapshot();
 6628                                let primary_start_point = primary.start.to_point(&snapshot);
 6629                                let range_start_point = range.start.to_point(&snapshot);
 6630
 6631                                let result = primary_start_point.row == 0
 6632                                    && primary_start_point.column == 0
 6633                                    && range_start_point.row == 0
 6634                                    && range_start_point.column == 0;
 6635
 6636                                result
 6637                            };
 6638
 6639                            let has_overlap = if is_file_start_auto_import {
 6640                                false
 6641                            } else {
 6642                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6643                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6644                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6645                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6646                                let result = start_within || end_within;
 6647                                result
 6648                            };
 6649
 6650                            //Skip additional edits which overlap with the primary completion edit
 6651                            //https://github.com/zed-industries/zed/pull/1871
 6652                            if !has_overlap {
 6653                                buffer.edit([(range, text)], None, cx);
 6654                            }
 6655                        }
 6656
 6657                        let transaction = if buffer.end_transaction(cx).is_some() {
 6658                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6659                            if !push_to_history {
 6660                                buffer.forget_transaction(transaction.id);
 6661                            }
 6662                            Some(transaction)
 6663                        } else {
 6664                            None
 6665                        };
 6666                        Ok(transaction)
 6667                    })?
 6668                } else {
 6669                    Ok(None)
 6670                }
 6671            })
 6672        }
 6673    }
 6674
 6675    pub fn pull_diagnostics(
 6676        &mut self,
 6677        buffer: Entity<Buffer>,
 6678        cx: &mut Context<Self>,
 6679    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6680        let buffer_id = buffer.read(cx).remote_id();
 6681
 6682        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6683            let mut suitable_capabilities = None;
 6684            // Are we capable for proto request?
 6685            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6686                &buffer,
 6687                |capabilities| {
 6688                    if let Some(caps) = &capabilities.diagnostic_provider {
 6689                        suitable_capabilities = Some(caps.clone());
 6690                        true
 6691                    } else {
 6692                        false
 6693                    }
 6694                },
 6695                cx,
 6696            );
 6697            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6698            let Some(dynamic_caps) = suitable_capabilities else {
 6699                return Task::ready(Ok(None));
 6700            };
 6701            assert!(any_server_has_diagnostics_provider);
 6702
 6703            let request = GetDocumentDiagnostics {
 6704                previous_result_id: None,
 6705                dynamic_caps,
 6706            };
 6707            let request_task = client.request_lsp(
 6708                upstream_project_id,
 6709                None,
 6710                LSP_REQUEST_TIMEOUT,
 6711                cx.background_executor().clone(),
 6712                request.to_proto(upstream_project_id, buffer.read(cx)),
 6713            );
 6714            cx.background_spawn(async move {
 6715                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6716                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6717                // Do not attempt to further process the dummy responses here.
 6718                let _response = request_task.await?;
 6719                Ok(None)
 6720            })
 6721        } else {
 6722            let servers = buffer.update(cx, |buffer, cx| {
 6723                self.language_servers_for_local_buffer(buffer, cx)
 6724                    .map(|(_, server)| server.clone())
 6725                    .collect::<Vec<_>>()
 6726            });
 6727
 6728            let pull_diagnostics = servers
 6729                .into_iter()
 6730                .flat_map(|server| {
 6731                    let result = maybe!({
 6732                        let local = self.as_local()?;
 6733                        let server_id = server.server_id();
 6734                        let providers_with_identifiers = local
 6735                            .language_server_dynamic_registrations
 6736                            .get(&server_id)
 6737                            .into_iter()
 6738                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6739                            .collect::<Vec<_>>();
 6740                        Some(
 6741                            providers_with_identifiers
 6742                                .into_iter()
 6743                                .map(|dynamic_caps| {
 6744                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6745                                    self.request_lsp(
 6746                                        buffer.clone(),
 6747                                        LanguageServerToQuery::Other(server_id),
 6748                                        GetDocumentDiagnostics {
 6749                                            previous_result_id: result_id,
 6750                                            dynamic_caps,
 6751                                        },
 6752                                        cx,
 6753                                    )
 6754                                })
 6755                                .collect::<Vec<_>>(),
 6756                        )
 6757                    });
 6758
 6759                    result.unwrap_or_default()
 6760                })
 6761                .collect::<Vec<_>>();
 6762
 6763            cx.background_spawn(async move {
 6764                let mut responses = Vec::new();
 6765                for diagnostics in join_all(pull_diagnostics).await {
 6766                    responses.extend(diagnostics?);
 6767                }
 6768                Ok(Some(responses))
 6769            })
 6770        }
 6771    }
 6772
 6773    pub fn applicable_inlay_chunks(
 6774        &mut self,
 6775        buffer: &Entity<Buffer>,
 6776        ranges: &[Range<text::Anchor>],
 6777        cx: &mut Context<Self>,
 6778    ) -> Vec<Range<BufferRow>> {
 6779        self.latest_lsp_data(buffer, cx)
 6780            .inlay_hints
 6781            .applicable_chunks(ranges)
 6782            .map(|chunk| chunk.row_range())
 6783            .collect()
 6784    }
 6785
 6786    pub fn invalidate_inlay_hints<'a>(
 6787        &'a mut self,
 6788        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6789    ) {
 6790        for buffer_id in for_buffers {
 6791            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6792                lsp_data.inlay_hints.clear();
 6793            }
 6794        }
 6795    }
 6796
 6797    pub fn inlay_hints(
 6798        &mut self,
 6799        invalidate: InvalidationStrategy,
 6800        buffer: Entity<Buffer>,
 6801        ranges: Vec<Range<text::Anchor>>,
 6802        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6803        cx: &mut Context<Self>,
 6804    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6805        let next_hint_id = self.next_hint_id.clone();
 6806        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6807        let query_version = lsp_data.buffer_version.clone();
 6808        let mut lsp_refresh_requested = false;
 6809        let for_server = if let InvalidationStrategy::RefreshRequested {
 6810            server_id,
 6811            request_id,
 6812        } = invalidate
 6813        {
 6814            let invalidated = lsp_data
 6815                .inlay_hints
 6816                .invalidate_for_server_refresh(server_id, request_id);
 6817            lsp_refresh_requested = invalidated;
 6818            Some(server_id)
 6819        } else {
 6820            None
 6821        };
 6822        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6823        let known_chunks = known_chunks
 6824            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6825            .map(|(_, known_chunks)| known_chunks)
 6826            .unwrap_or_default();
 6827
 6828        let mut hint_fetch_tasks = Vec::new();
 6829        let mut cached_inlay_hints = None;
 6830        let mut ranges_to_query = None;
 6831        let applicable_chunks = existing_inlay_hints
 6832            .applicable_chunks(ranges.as_slice())
 6833            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6834            .collect::<Vec<_>>();
 6835        if applicable_chunks.is_empty() {
 6836            return HashMap::default();
 6837        }
 6838
 6839        for row_chunk in applicable_chunks {
 6840            match (
 6841                existing_inlay_hints
 6842                    .cached_hints(&row_chunk)
 6843                    .filter(|_| !lsp_refresh_requested)
 6844                    .cloned(),
 6845                existing_inlay_hints
 6846                    .fetched_hints(&row_chunk)
 6847                    .as_ref()
 6848                    .filter(|_| !lsp_refresh_requested)
 6849                    .cloned(),
 6850            ) {
 6851                (None, None) => {
 6852                    let Some(chunk_range) = existing_inlay_hints.chunk_range(row_chunk) else {
 6853                        continue;
 6854                    };
 6855                    ranges_to_query
 6856                        .get_or_insert_with(Vec::new)
 6857                        .push((row_chunk, chunk_range));
 6858                }
 6859                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6860                (Some(cached_hints), None) => {
 6861                    for (server_id, cached_hints) in cached_hints {
 6862                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6863                            cached_inlay_hints
 6864                                .get_or_insert_with(HashMap::default)
 6865                                .entry(row_chunk.row_range())
 6866                                .or_insert_with(HashMap::default)
 6867                                .entry(server_id)
 6868                                .or_insert_with(Vec::new)
 6869                                .extend(cached_hints);
 6870                        }
 6871                    }
 6872                }
 6873                (Some(cached_hints), Some(fetched_hints)) => {
 6874                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6875                    for (server_id, cached_hints) in cached_hints {
 6876                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6877                            cached_inlay_hints
 6878                                .get_or_insert_with(HashMap::default)
 6879                                .entry(row_chunk.row_range())
 6880                                .or_insert_with(HashMap::default)
 6881                                .entry(server_id)
 6882                                .or_insert_with(Vec::new)
 6883                                .extend(cached_hints);
 6884                        }
 6885                    }
 6886                }
 6887            }
 6888        }
 6889
 6890        if hint_fetch_tasks.is_empty()
 6891            && ranges_to_query
 6892                .as_ref()
 6893                .is_none_or(|ranges| ranges.is_empty())
 6894            && let Some(cached_inlay_hints) = cached_inlay_hints
 6895        {
 6896            cached_inlay_hints
 6897                .into_iter()
 6898                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6899                .collect()
 6900        } else {
 6901            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6902                let next_hint_id = next_hint_id.clone();
 6903                let buffer = buffer.clone();
 6904                let query_version = query_version.clone();
 6905                let new_inlay_hints = cx
 6906                    .spawn(async move |lsp_store, cx| {
 6907                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6908                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6909                        })?;
 6910                        new_fetch_task
 6911                            .await
 6912                            .and_then(|new_hints_by_server| {
 6913                                lsp_store.update(cx, |lsp_store, cx| {
 6914                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6915                                    let update_cache = lsp_data.buffer_version == query_version;
 6916                                    if new_hints_by_server.is_empty() {
 6917                                        if update_cache {
 6918                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6919                                        }
 6920                                        HashMap::default()
 6921                                    } else {
 6922                                        new_hints_by_server
 6923                                            .into_iter()
 6924                                            .map(|(server_id, new_hints)| {
 6925                                                let new_hints = new_hints
 6926                                                    .into_iter()
 6927                                                    .map(|new_hint| {
 6928                                                        (
 6929                                                            InlayId::Hint(next_hint_id.fetch_add(
 6930                                                                1,
 6931                                                                atomic::Ordering::AcqRel,
 6932                                                            )),
 6933                                                            new_hint,
 6934                                                        )
 6935                                                    })
 6936                                                    .collect::<Vec<_>>();
 6937                                                if update_cache {
 6938                                                    lsp_data.inlay_hints.insert_new_hints(
 6939                                                        chunk,
 6940                                                        server_id,
 6941                                                        new_hints.clone(),
 6942                                                    );
 6943                                                }
 6944                                                (server_id, new_hints)
 6945                                            })
 6946                                            .collect()
 6947                                    }
 6948                                })
 6949                            })
 6950                            .map_err(Arc::new)
 6951                    })
 6952                    .shared();
 6953
 6954                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6955                *fetch_task = Some(new_inlay_hints.clone());
 6956                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6957            }
 6958
 6959            cached_inlay_hints
 6960                .unwrap_or_default()
 6961                .into_iter()
 6962                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6963                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6964                    (
 6965                        chunk.row_range(),
 6966                        cx.spawn(async move |_, _| {
 6967                            hints_fetch.await.map_err(|e| {
 6968                                if e.error_code() != ErrorCode::Internal {
 6969                                    anyhow!(e.error_code())
 6970                                } else {
 6971                                    anyhow!("{e:#}")
 6972                                }
 6973                            })
 6974                        }),
 6975                    )
 6976                }))
 6977                .collect()
 6978        }
 6979    }
 6980
 6981    fn fetch_inlay_hints(
 6982        &mut self,
 6983        for_server: Option<LanguageServerId>,
 6984        buffer: &Entity<Buffer>,
 6985        range: Range<Anchor>,
 6986        cx: &mut Context<Self>,
 6987    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6988        let request = InlayHints {
 6989            range: range.clone(),
 6990        };
 6991        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6992            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6993                return Task::ready(Ok(HashMap::default()));
 6994            }
 6995            let request_task = upstream_client.request_lsp(
 6996                project_id,
 6997                for_server.map(|id| id.to_proto()),
 6998                LSP_REQUEST_TIMEOUT,
 6999                cx.background_executor().clone(),
 7000                request.to_proto(project_id, buffer.read(cx)),
 7001            );
 7002            let buffer = buffer.clone();
 7003            cx.spawn(async move |weak_lsp_store, cx| {
 7004                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7005                    return Ok(HashMap::default());
 7006                };
 7007                let Some(responses) = request_task.await? else {
 7008                    return Ok(HashMap::default());
 7009                };
 7010
 7011                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7012                    let lsp_store = lsp_store.clone();
 7013                    let buffer = buffer.clone();
 7014                    let cx = cx.clone();
 7015                    let request = request.clone();
 7016                    async move {
 7017                        (
 7018                            LanguageServerId::from_proto(response.server_id),
 7019                            request
 7020                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7021                                .await,
 7022                        )
 7023                    }
 7024                }))
 7025                .await;
 7026
 7027                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7028                let mut has_errors = false;
 7029                let inlay_hints = inlay_hints
 7030                    .into_iter()
 7031                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7032                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7033                        Err(e) => {
 7034                            has_errors = true;
 7035                            log::error!("{e:#}");
 7036                            None
 7037                        }
 7038                    })
 7039                    .map(|(server_id, mut new_hints)| {
 7040                        new_hints.retain(|hint| {
 7041                            hint.position.is_valid(&buffer_snapshot)
 7042                                && range.start.is_valid(&buffer_snapshot)
 7043                                && range.end.is_valid(&buffer_snapshot)
 7044                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7045                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7046                        });
 7047                        (server_id, new_hints)
 7048                    })
 7049                    .collect::<HashMap<_, _>>();
 7050                anyhow::ensure!(
 7051                    !has_errors || !inlay_hints.is_empty(),
 7052                    "Failed to fetch inlay hints"
 7053                );
 7054                Ok(inlay_hints)
 7055            })
 7056        } else {
 7057            let inlay_hints_task = match for_server {
 7058                Some(server_id) => {
 7059                    let server_task = self.request_lsp(
 7060                        buffer.clone(),
 7061                        LanguageServerToQuery::Other(server_id),
 7062                        request,
 7063                        cx,
 7064                    );
 7065                    cx.background_spawn(async move {
 7066                        let mut responses = Vec::new();
 7067                        match server_task.await {
 7068                            Ok(response) => responses.push((server_id, response)),
 7069                            // rust-analyzer likes to error with this when its still loading up
 7070                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7071                            Err(e) => log::error!(
 7072                                "Error handling response for inlay hints request: {e:#}"
 7073                            ),
 7074                        }
 7075                        responses
 7076                    })
 7077                }
 7078                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7079            };
 7080            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7081            cx.background_spawn(async move {
 7082                Ok(inlay_hints_task
 7083                    .await
 7084                    .into_iter()
 7085                    .map(|(server_id, mut new_hints)| {
 7086                        new_hints.retain(|hint| {
 7087                            hint.position.is_valid(&buffer_snapshot)
 7088                                && range.start.is_valid(&buffer_snapshot)
 7089                                && range.end.is_valid(&buffer_snapshot)
 7090                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7091                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7092                        });
 7093                        (server_id, new_hints)
 7094                    })
 7095                    .collect())
 7096            })
 7097        }
 7098    }
 7099
 7100    pub fn pull_diagnostics_for_buffer(
 7101        &mut self,
 7102        buffer: Entity<Buffer>,
 7103        cx: &mut Context<Self>,
 7104    ) -> Task<anyhow::Result<()>> {
 7105        let diagnostics = self.pull_diagnostics(buffer, cx);
 7106        cx.spawn(async move |lsp_store, cx| {
 7107            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7108                return Ok(());
 7109            };
 7110            lsp_store.update(cx, |lsp_store, cx| {
 7111                if lsp_store.as_local().is_none() {
 7112                    return;
 7113                }
 7114
 7115                let mut unchanged_buffers = HashSet::default();
 7116                let mut changed_buffers = HashSet::default();
 7117                let server_diagnostics_updates = diagnostics
 7118                    .into_iter()
 7119                    .filter_map(|diagnostics_set| match diagnostics_set {
 7120                        LspPullDiagnostics::Response {
 7121                            server_id,
 7122                            uri,
 7123                            diagnostics,
 7124                        } => Some((server_id, uri, diagnostics)),
 7125                        LspPullDiagnostics::Default => None,
 7126                    })
 7127                    .fold(
 7128                        HashMap::default(),
 7129                        |mut acc, (server_id, uri, diagnostics)| {
 7130                            let (result_id, diagnostics) = match diagnostics {
 7131                                PulledDiagnostics::Unchanged { result_id } => {
 7132                                    unchanged_buffers.insert(uri.clone());
 7133                                    (Some(result_id), Vec::new())
 7134                                }
 7135                                PulledDiagnostics::Changed {
 7136                                    result_id,
 7137                                    diagnostics,
 7138                                } => {
 7139                                    changed_buffers.insert(uri.clone());
 7140                                    (result_id, diagnostics)
 7141                                }
 7142                            };
 7143                            let disk_based_sources = Cow::Owned(
 7144                                lsp_store
 7145                                    .language_server_adapter_for_id(server_id)
 7146                                    .as_ref()
 7147                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7148                                    .unwrap_or(&[])
 7149                                    .to_vec(),
 7150                            );
 7151                            acc.entry(server_id).or_insert_with(Vec::new).push(
 7152                                DocumentDiagnosticsUpdate {
 7153                                    server_id,
 7154                                    diagnostics: lsp::PublishDiagnosticsParams {
 7155                                        uri,
 7156                                        diagnostics,
 7157                                        version: None,
 7158                                    },
 7159                                    result_id,
 7160                                    disk_based_sources,
 7161                                },
 7162                            );
 7163                            acc
 7164                        },
 7165                    );
 7166
 7167                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7168                    lsp_store
 7169                        .merge_lsp_diagnostics(
 7170                            DiagnosticSourceKind::Pulled,
 7171                            diagnostic_updates,
 7172                            |buffer, old_diagnostic, cx| {
 7173                                File::from_dyn(buffer.file())
 7174                                    .and_then(|file| {
 7175                                        let abs_path = file.as_local()?.abs_path(cx);
 7176                                        lsp::Uri::from_file_path(abs_path).ok()
 7177                                    })
 7178                                    .is_none_or(|buffer_uri| {
 7179                                        unchanged_buffers.contains(&buffer_uri)
 7180                                            || match old_diagnostic.source_kind {
 7181                                                DiagnosticSourceKind::Pulled => {
 7182                                                    !changed_buffers.contains(&buffer_uri)
 7183                                                }
 7184                                                DiagnosticSourceKind::Other
 7185                                                | DiagnosticSourceKind::Pushed => true,
 7186                                            }
 7187                                    })
 7188                            },
 7189                            cx,
 7190                        )
 7191                        .log_err();
 7192                }
 7193            })
 7194        })
 7195    }
 7196
 7197    pub fn document_colors(
 7198        &mut self,
 7199        known_cache_version: Option<usize>,
 7200        buffer: Entity<Buffer>,
 7201        cx: &mut Context<Self>,
 7202    ) -> Option<DocumentColorTask> {
 7203        let version_queried_for = buffer.read(cx).version();
 7204        let buffer_id = buffer.read(cx).remote_id();
 7205
 7206        let current_language_servers = self.as_local().map(|local| {
 7207            local
 7208                .buffers_opened_in_servers
 7209                .get(&buffer_id)
 7210                .cloned()
 7211                .unwrap_or_default()
 7212        });
 7213
 7214        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7215            if let Some(cached_colors) = &lsp_data.document_colors {
 7216                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7217                    let has_different_servers =
 7218                        current_language_servers.is_some_and(|current_language_servers| {
 7219                            current_language_servers
 7220                                != cached_colors.colors.keys().copied().collect()
 7221                        });
 7222                    if !has_different_servers {
 7223                        let cache_version = cached_colors.cache_version;
 7224                        if Some(cache_version) == known_cache_version {
 7225                            return None;
 7226                        } else {
 7227                            return Some(
 7228                                Task::ready(Ok(DocumentColors {
 7229                                    colors: cached_colors
 7230                                        .colors
 7231                                        .values()
 7232                                        .flatten()
 7233                                        .cloned()
 7234                                        .collect(),
 7235                                    cache_version: Some(cache_version),
 7236                                }))
 7237                                .shared(),
 7238                            );
 7239                        }
 7240                    }
 7241                }
 7242            }
 7243        }
 7244
 7245        let color_lsp_data = self
 7246            .latest_lsp_data(&buffer, cx)
 7247            .document_colors
 7248            .get_or_insert_default();
 7249        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7250            && !version_queried_for.changed_since(updating_for)
 7251        {
 7252            return Some(running_update.clone());
 7253        }
 7254        let buffer_version_queried_for = version_queried_for.clone();
 7255        let new_task = cx
 7256            .spawn(async move |lsp_store, cx| {
 7257                cx.background_executor()
 7258                    .timer(Duration::from_millis(30))
 7259                    .await;
 7260                let fetched_colors = lsp_store
 7261                    .update(cx, |lsp_store, cx| {
 7262                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7263                    })?
 7264                    .await
 7265                    .context("fetching document colors")
 7266                    .map_err(Arc::new);
 7267                let fetched_colors = match fetched_colors {
 7268                    Ok(fetched_colors) => {
 7269                        if Some(true)
 7270                            == buffer
 7271                                .update(cx, |buffer, _| {
 7272                                    buffer.version() != buffer_version_queried_for
 7273                                })
 7274                                .ok()
 7275                        {
 7276                            return Ok(DocumentColors::default());
 7277                        }
 7278                        fetched_colors
 7279                    }
 7280                    Err(e) => {
 7281                        lsp_store
 7282                            .update(cx, |lsp_store, _| {
 7283                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7284                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7285                                        document_colors.colors_update = None;
 7286                                    }
 7287                                }
 7288                            })
 7289                            .ok();
 7290                        return Err(e);
 7291                    }
 7292                };
 7293
 7294                lsp_store
 7295                    .update(cx, |lsp_store, cx| {
 7296                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7297                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7298
 7299                        if let Some(fetched_colors) = fetched_colors {
 7300                            if lsp_data.buffer_version == buffer_version_queried_for {
 7301                                lsp_colors.colors.extend(fetched_colors);
 7302                                lsp_colors.cache_version += 1;
 7303                            } else if !lsp_data
 7304                                .buffer_version
 7305                                .changed_since(&buffer_version_queried_for)
 7306                            {
 7307                                lsp_data.buffer_version = buffer_version_queried_for;
 7308                                lsp_colors.colors = fetched_colors;
 7309                                lsp_colors.cache_version += 1;
 7310                            }
 7311                        }
 7312                        lsp_colors.colors_update = None;
 7313                        let colors = lsp_colors
 7314                            .colors
 7315                            .values()
 7316                            .flatten()
 7317                            .cloned()
 7318                            .collect::<HashSet<_>>();
 7319                        DocumentColors {
 7320                            colors,
 7321                            cache_version: Some(lsp_colors.cache_version),
 7322                        }
 7323                    })
 7324                    .map_err(Arc::new)
 7325            })
 7326            .shared();
 7327        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7328        Some(new_task)
 7329    }
 7330
 7331    fn fetch_document_colors_for_buffer(
 7332        &mut self,
 7333        buffer: &Entity<Buffer>,
 7334        cx: &mut Context<Self>,
 7335    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7336        if let Some((client, project_id)) = self.upstream_client() {
 7337            let request = GetDocumentColor {};
 7338            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7339                return Task::ready(Ok(None));
 7340            }
 7341
 7342            let request_task = client.request_lsp(
 7343                project_id,
 7344                None,
 7345                LSP_REQUEST_TIMEOUT,
 7346                cx.background_executor().clone(),
 7347                request.to_proto(project_id, buffer.read(cx)),
 7348            );
 7349            let buffer = buffer.clone();
 7350            cx.spawn(async move |lsp_store, cx| {
 7351                let Some(lsp_store) = lsp_store.upgrade() else {
 7352                    return Ok(None);
 7353                };
 7354                let colors = join_all(
 7355                    request_task
 7356                        .await
 7357                        .log_err()
 7358                        .flatten()
 7359                        .map(|response| response.payload)
 7360                        .unwrap_or_default()
 7361                        .into_iter()
 7362                        .map(|color_response| {
 7363                            let response = request.response_from_proto(
 7364                                color_response.response,
 7365                                lsp_store.clone(),
 7366                                buffer.clone(),
 7367                                cx.clone(),
 7368                            );
 7369                            async move {
 7370                                (
 7371                                    LanguageServerId::from_proto(color_response.server_id),
 7372                                    response.await.log_err().unwrap_or_default(),
 7373                                )
 7374                            }
 7375                        }),
 7376                )
 7377                .await
 7378                .into_iter()
 7379                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7380                    acc.entry(server_id)
 7381                        .or_insert_with(HashSet::default)
 7382                        .extend(colors);
 7383                    acc
 7384                });
 7385                Ok(Some(colors))
 7386            })
 7387        } else {
 7388            let document_colors_task =
 7389                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7390            cx.background_spawn(async move {
 7391                Ok(Some(
 7392                    document_colors_task
 7393                        .await
 7394                        .into_iter()
 7395                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7396                            acc.entry(server_id)
 7397                                .or_insert_with(HashSet::default)
 7398                                .extend(colors);
 7399                            acc
 7400                        })
 7401                        .into_iter()
 7402                        .collect(),
 7403                ))
 7404            })
 7405        }
 7406    }
 7407
 7408    pub fn signature_help<T: ToPointUtf16>(
 7409        &mut self,
 7410        buffer: &Entity<Buffer>,
 7411        position: T,
 7412        cx: &mut Context<Self>,
 7413    ) -> Task<Option<Vec<SignatureHelp>>> {
 7414        let position = position.to_point_utf16(buffer.read(cx));
 7415
 7416        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7417            let request = GetSignatureHelp { position };
 7418            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7419                return Task::ready(None);
 7420            }
 7421            let request_task = client.request_lsp(
 7422                upstream_project_id,
 7423                None,
 7424                LSP_REQUEST_TIMEOUT,
 7425                cx.background_executor().clone(),
 7426                request.to_proto(upstream_project_id, buffer.read(cx)),
 7427            );
 7428            let buffer = buffer.clone();
 7429            cx.spawn(async move |weak_lsp_store, cx| {
 7430                let lsp_store = weak_lsp_store.upgrade()?;
 7431                let signatures = join_all(
 7432                    request_task
 7433                        .await
 7434                        .log_err()
 7435                        .flatten()
 7436                        .map(|response| response.payload)
 7437                        .unwrap_or_default()
 7438                        .into_iter()
 7439                        .map(|response| {
 7440                            let response = GetSignatureHelp { position }.response_from_proto(
 7441                                response.response,
 7442                                lsp_store.clone(),
 7443                                buffer.clone(),
 7444                                cx.clone(),
 7445                            );
 7446                            async move { response.await.log_err().flatten() }
 7447                        }),
 7448                )
 7449                .await
 7450                .into_iter()
 7451                .flatten()
 7452                .collect();
 7453                Some(signatures)
 7454            })
 7455        } else {
 7456            let all_actions_task = self.request_multiple_lsp_locally(
 7457                buffer,
 7458                Some(position),
 7459                GetSignatureHelp { position },
 7460                cx,
 7461            );
 7462            cx.background_spawn(async move {
 7463                Some(
 7464                    all_actions_task
 7465                        .await
 7466                        .into_iter()
 7467                        .flat_map(|(_, actions)| actions)
 7468                        .collect::<Vec<_>>(),
 7469                )
 7470            })
 7471        }
 7472    }
 7473
 7474    pub fn hover(
 7475        &mut self,
 7476        buffer: &Entity<Buffer>,
 7477        position: PointUtf16,
 7478        cx: &mut Context<Self>,
 7479    ) -> Task<Option<Vec<Hover>>> {
 7480        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7481            let request = GetHover { position };
 7482            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7483                return Task::ready(None);
 7484            }
 7485            let request_task = client.request_lsp(
 7486                upstream_project_id,
 7487                None,
 7488                LSP_REQUEST_TIMEOUT,
 7489                cx.background_executor().clone(),
 7490                request.to_proto(upstream_project_id, buffer.read(cx)),
 7491            );
 7492            let buffer = buffer.clone();
 7493            cx.spawn(async move |weak_lsp_store, cx| {
 7494                let lsp_store = weak_lsp_store.upgrade()?;
 7495                let hovers = join_all(
 7496                    request_task
 7497                        .await
 7498                        .log_err()
 7499                        .flatten()
 7500                        .map(|response| response.payload)
 7501                        .unwrap_or_default()
 7502                        .into_iter()
 7503                        .map(|response| {
 7504                            let response = GetHover { position }.response_from_proto(
 7505                                response.response,
 7506                                lsp_store.clone(),
 7507                                buffer.clone(),
 7508                                cx.clone(),
 7509                            );
 7510                            async move {
 7511                                response
 7512                                    .await
 7513                                    .log_err()
 7514                                    .flatten()
 7515                                    .and_then(remove_empty_hover_blocks)
 7516                            }
 7517                        }),
 7518                )
 7519                .await
 7520                .into_iter()
 7521                .flatten()
 7522                .collect();
 7523                Some(hovers)
 7524            })
 7525        } else {
 7526            let all_actions_task = self.request_multiple_lsp_locally(
 7527                buffer,
 7528                Some(position),
 7529                GetHover { position },
 7530                cx,
 7531            );
 7532            cx.background_spawn(async move {
 7533                Some(
 7534                    all_actions_task
 7535                        .await
 7536                        .into_iter()
 7537                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7538                        .collect::<Vec<Hover>>(),
 7539                )
 7540            })
 7541        }
 7542    }
 7543
 7544    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7545        let language_registry = self.languages.clone();
 7546
 7547        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7548            let request = upstream_client.request(proto::GetProjectSymbols {
 7549                project_id: *project_id,
 7550                query: query.to_string(),
 7551            });
 7552            cx.foreground_executor().spawn(async move {
 7553                let response = request.await?;
 7554                let mut symbols = Vec::new();
 7555                let core_symbols = response
 7556                    .symbols
 7557                    .into_iter()
 7558                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7559                    .collect::<Vec<_>>();
 7560                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7561                    .await;
 7562                Ok(symbols)
 7563            })
 7564        } else if let Some(local) = self.as_local() {
 7565            struct WorkspaceSymbolsResult {
 7566                server_id: LanguageServerId,
 7567                lsp_adapter: Arc<CachedLspAdapter>,
 7568                worktree: WeakEntity<Worktree>,
 7569                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7570            }
 7571
 7572            let mut requests = Vec::new();
 7573            let mut requested_servers = BTreeSet::new();
 7574            for (seed, state) in local.language_server_ids.iter() {
 7575                let Some(worktree_handle) = self
 7576                    .worktree_store
 7577                    .read(cx)
 7578                    .worktree_for_id(seed.worktree_id, cx)
 7579                else {
 7580                    continue;
 7581                };
 7582                let worktree = worktree_handle.read(cx);
 7583                if !worktree.is_visible() {
 7584                    continue;
 7585                }
 7586
 7587                if !requested_servers.insert(state.id) {
 7588                    continue;
 7589                }
 7590
 7591                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7592                    Some(LanguageServerState::Running {
 7593                        adapter, server, ..
 7594                    }) => (adapter.clone(), server),
 7595
 7596                    _ => continue,
 7597                };
 7598                let supports_workspace_symbol_request =
 7599                    match server.capabilities().workspace_symbol_provider {
 7600                        Some(OneOf::Left(supported)) => supported,
 7601                        Some(OneOf::Right(_)) => true,
 7602                        None => false,
 7603                    };
 7604                if !supports_workspace_symbol_request {
 7605                    continue;
 7606                }
 7607                let worktree_handle = worktree_handle.clone();
 7608                let server_id = server.server_id();
 7609                requests.push(
 7610                        server
 7611                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7612                                lsp::WorkspaceSymbolParams {
 7613                                    query: query.to_string(),
 7614                                    ..Default::default()
 7615                                },
 7616                            )
 7617                            .map(move |response| {
 7618                                let lsp_symbols = response.into_response()
 7619                                    .context("workspace symbols request")
 7620                                    .log_err()
 7621                                    .flatten()
 7622                                    .map(|symbol_response| match symbol_response {
 7623                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7624                                            flat_responses.into_iter().map(|lsp_symbol| {
 7625                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7626                                            }).collect::<Vec<_>>()
 7627                                        }
 7628                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7629                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7630                                                let location = match lsp_symbol.location {
 7631                                                    OneOf::Left(location) => location,
 7632                                                    OneOf::Right(_) => {
 7633                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7634                                                        return None
 7635                                                    }
 7636                                                };
 7637                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7638                                            }).collect::<Vec<_>>()
 7639                                        }
 7640                                    }).unwrap_or_default();
 7641
 7642                                WorkspaceSymbolsResult {
 7643                                    server_id,
 7644                                    lsp_adapter,
 7645                                    worktree: worktree_handle.downgrade(),
 7646                                    lsp_symbols,
 7647                                }
 7648                            }),
 7649                    );
 7650            }
 7651
 7652            cx.spawn(async move |this, cx| {
 7653                let responses = futures::future::join_all(requests).await;
 7654                let this = match this.upgrade() {
 7655                    Some(this) => this,
 7656                    None => return Ok(Vec::new()),
 7657                };
 7658
 7659                let mut symbols = Vec::new();
 7660                for result in responses {
 7661                    let core_symbols = this.update(cx, |this, cx| {
 7662                        result
 7663                            .lsp_symbols
 7664                            .into_iter()
 7665                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7666                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7667                                let source_worktree = result.worktree.upgrade()?;
 7668                                let source_worktree_id = source_worktree.read(cx).id();
 7669
 7670                                let path = if let Some((tree, rel_path)) =
 7671                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7672                                {
 7673                                    let worktree_id = tree.read(cx).id();
 7674                                    SymbolLocation::InProject(ProjectPath {
 7675                                        worktree_id,
 7676                                        path: rel_path,
 7677                                    })
 7678                                } else {
 7679                                    SymbolLocation::OutsideProject {
 7680                                        signature: this.symbol_signature(&abs_path),
 7681                                        abs_path: abs_path.into(),
 7682                                    }
 7683                                };
 7684
 7685                                Some(CoreSymbol {
 7686                                    source_language_server_id: result.server_id,
 7687                                    language_server_name: result.lsp_adapter.name.clone(),
 7688                                    source_worktree_id,
 7689                                    path,
 7690                                    kind: symbol_kind,
 7691                                    name: symbol_name,
 7692                                    range: range_from_lsp(symbol_location.range),
 7693                                })
 7694                            })
 7695                            .collect()
 7696                    })?;
 7697
 7698                    populate_labels_for_symbols(
 7699                        core_symbols,
 7700                        &language_registry,
 7701                        Some(result.lsp_adapter),
 7702                        &mut symbols,
 7703                    )
 7704                    .await;
 7705                }
 7706
 7707                Ok(symbols)
 7708            })
 7709        } else {
 7710            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7711        }
 7712    }
 7713
 7714    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7715        let mut summary = DiagnosticSummary::default();
 7716        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7717            summary.error_count += path_summary.error_count;
 7718            summary.warning_count += path_summary.warning_count;
 7719        }
 7720        summary
 7721    }
 7722
 7723    /// Returns the diagnostic summary for a specific project path.
 7724    pub fn diagnostic_summary_for_path(
 7725        &self,
 7726        project_path: &ProjectPath,
 7727        _: &App,
 7728    ) -> DiagnosticSummary {
 7729        if let Some(summaries) = self
 7730            .diagnostic_summaries
 7731            .get(&project_path.worktree_id)
 7732            .and_then(|map| map.get(&project_path.path))
 7733        {
 7734            let (error_count, warning_count) = summaries.iter().fold(
 7735                (0, 0),
 7736                |(error_count, warning_count), (_language_server_id, summary)| {
 7737                    (
 7738                        error_count + summary.error_count,
 7739                        warning_count + summary.warning_count,
 7740                    )
 7741                },
 7742            );
 7743
 7744            DiagnosticSummary {
 7745                error_count,
 7746                warning_count,
 7747            }
 7748        } else {
 7749            DiagnosticSummary::default()
 7750        }
 7751    }
 7752
 7753    pub fn diagnostic_summaries<'a>(
 7754        &'a self,
 7755        include_ignored: bool,
 7756        cx: &'a App,
 7757    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7758        self.worktree_store
 7759            .read(cx)
 7760            .visible_worktrees(cx)
 7761            .filter_map(|worktree| {
 7762                let worktree = worktree.read(cx);
 7763                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7764            })
 7765            .flat_map(move |(worktree, summaries)| {
 7766                let worktree_id = worktree.id();
 7767                summaries
 7768                    .iter()
 7769                    .filter(move |(path, _)| {
 7770                        include_ignored
 7771                            || worktree
 7772                                .entry_for_path(path.as_ref())
 7773                                .is_some_and(|entry| !entry.is_ignored)
 7774                    })
 7775                    .flat_map(move |(path, summaries)| {
 7776                        summaries.iter().map(move |(server_id, summary)| {
 7777                            (
 7778                                ProjectPath {
 7779                                    worktree_id,
 7780                                    path: path.clone(),
 7781                                },
 7782                                *server_id,
 7783                                *summary,
 7784                            )
 7785                        })
 7786                    })
 7787            })
 7788    }
 7789
 7790    pub fn on_buffer_edited(
 7791        &mut self,
 7792        buffer: Entity<Buffer>,
 7793        cx: &mut Context<Self>,
 7794    ) -> Option<()> {
 7795        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7796            Some(
 7797                self.as_local()?
 7798                    .language_servers_for_buffer(buffer, cx)
 7799                    .map(|i| i.1.clone())
 7800                    .collect(),
 7801            )
 7802        })?;
 7803
 7804        let buffer = buffer.read(cx);
 7805        let file = File::from_dyn(buffer.file())?;
 7806        let abs_path = file.as_local()?.abs_path(cx);
 7807        let uri = lsp::Uri::from_file_path(&abs_path)
 7808            .ok()
 7809            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7810            .log_err()?;
 7811        let next_snapshot = buffer.text_snapshot();
 7812        for language_server in language_servers {
 7813            let language_server = language_server.clone();
 7814
 7815            let buffer_snapshots = self
 7816                .as_local_mut()?
 7817                .buffer_snapshots
 7818                .get_mut(&buffer.remote_id())
 7819                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7820            let previous_snapshot = buffer_snapshots.last()?;
 7821
 7822            let build_incremental_change = || {
 7823                buffer
 7824                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7825                        previous_snapshot.snapshot.version(),
 7826                    )
 7827                    .map(|edit| {
 7828                        let edit_start = edit.new.start.0;
 7829                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7830                        let new_text = next_snapshot
 7831                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7832                            .collect();
 7833                        lsp::TextDocumentContentChangeEvent {
 7834                            range: Some(lsp::Range::new(
 7835                                point_to_lsp(edit_start),
 7836                                point_to_lsp(edit_end),
 7837                            )),
 7838                            range_length: None,
 7839                            text: new_text,
 7840                        }
 7841                    })
 7842                    .collect()
 7843            };
 7844
 7845            let document_sync_kind = language_server
 7846                .capabilities()
 7847                .text_document_sync
 7848                .as_ref()
 7849                .and_then(|sync| match sync {
 7850                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7851                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7852                });
 7853
 7854            let content_changes: Vec<_> = match document_sync_kind {
 7855                Some(lsp::TextDocumentSyncKind::FULL) => {
 7856                    vec![lsp::TextDocumentContentChangeEvent {
 7857                        range: None,
 7858                        range_length: None,
 7859                        text: next_snapshot.text(),
 7860                    }]
 7861                }
 7862                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7863                _ => {
 7864                    #[cfg(any(test, feature = "test-support"))]
 7865                    {
 7866                        build_incremental_change()
 7867                    }
 7868
 7869                    #[cfg(not(any(test, feature = "test-support")))]
 7870                    {
 7871                        continue;
 7872                    }
 7873                }
 7874            };
 7875
 7876            let next_version = previous_snapshot.version + 1;
 7877            buffer_snapshots.push(LspBufferSnapshot {
 7878                version: next_version,
 7879                snapshot: next_snapshot.clone(),
 7880            });
 7881
 7882            language_server
 7883                .notify::<lsp::notification::DidChangeTextDocument>(
 7884                    lsp::DidChangeTextDocumentParams {
 7885                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7886                            uri.clone(),
 7887                            next_version,
 7888                        ),
 7889                        content_changes,
 7890                    },
 7891                )
 7892                .ok();
 7893            self.pull_workspace_diagnostics(language_server.server_id());
 7894        }
 7895
 7896        None
 7897    }
 7898
 7899    pub fn on_buffer_saved(
 7900        &mut self,
 7901        buffer: Entity<Buffer>,
 7902        cx: &mut Context<Self>,
 7903    ) -> Option<()> {
 7904        let file = File::from_dyn(buffer.read(cx).file())?;
 7905        let worktree_id = file.worktree_id(cx);
 7906        let abs_path = file.as_local()?.abs_path(cx);
 7907        let text_document = lsp::TextDocumentIdentifier {
 7908            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7909        };
 7910        let local = self.as_local()?;
 7911
 7912        for server in local.language_servers_for_worktree(worktree_id) {
 7913            if let Some(include_text) = include_text(server.as_ref()) {
 7914                let text = if include_text {
 7915                    Some(buffer.read(cx).text())
 7916                } else {
 7917                    None
 7918                };
 7919                server
 7920                    .notify::<lsp::notification::DidSaveTextDocument>(
 7921                        lsp::DidSaveTextDocumentParams {
 7922                            text_document: text_document.clone(),
 7923                            text,
 7924                        },
 7925                    )
 7926                    .ok();
 7927            }
 7928        }
 7929
 7930        let language_servers = buffer.update(cx, |buffer, cx| {
 7931            local.language_server_ids_for_buffer(buffer, cx)
 7932        });
 7933        for language_server_id in language_servers {
 7934            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7935        }
 7936
 7937        None
 7938    }
 7939
 7940    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7941        maybe!(async move {
 7942            let mut refreshed_servers = HashSet::default();
 7943            let servers = lsp_store
 7944                .update(cx, |lsp_store, cx| {
 7945                    let local = lsp_store.as_local()?;
 7946
 7947                    let servers = local
 7948                        .language_server_ids
 7949                        .iter()
 7950                        .filter_map(|(seed, state)| {
 7951                            let worktree = lsp_store
 7952                                .worktree_store
 7953                                .read(cx)
 7954                                .worktree_for_id(seed.worktree_id, cx);
 7955                            let delegate: Arc<dyn LspAdapterDelegate> =
 7956                                worktree.map(|worktree| {
 7957                                    LocalLspAdapterDelegate::new(
 7958                                        local.languages.clone(),
 7959                                        &local.environment,
 7960                                        cx.weak_entity(),
 7961                                        &worktree,
 7962                                        local.http_client.clone(),
 7963                                        local.fs.clone(),
 7964                                        cx,
 7965                                    )
 7966                                })?;
 7967                            let server_id = state.id;
 7968
 7969                            let states = local.language_servers.get(&server_id)?;
 7970
 7971                            match states {
 7972                                LanguageServerState::Starting { .. } => None,
 7973                                LanguageServerState::Running {
 7974                                    adapter, server, ..
 7975                                } => {
 7976                                    let adapter = adapter.clone();
 7977                                    let server = server.clone();
 7978                                    refreshed_servers.insert(server.name());
 7979                                    let toolchain = seed.toolchain.clone();
 7980                                    Some(cx.spawn(async move |_, cx| {
 7981                                        let settings =
 7982                                            LocalLspStore::workspace_configuration_for_adapter(
 7983                                                adapter.adapter.clone(),
 7984                                                &delegate,
 7985                                                toolchain,
 7986                                                None,
 7987                                                cx,
 7988                                            )
 7989                                            .await
 7990                                            .ok()?;
 7991                                        server
 7992                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7993                                                lsp::DidChangeConfigurationParams { settings },
 7994                                            )
 7995                                            .ok()?;
 7996                                        Some(())
 7997                                    }))
 7998                                }
 7999                            }
 8000                        })
 8001                        .collect::<Vec<_>>();
 8002
 8003                    Some(servers)
 8004                })
 8005                .ok()
 8006                .flatten()?;
 8007
 8008            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8009            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8010            // to stop and unregister its language server wrapper.
 8011            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8012            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8013            let _: Vec<Option<()>> = join_all(servers).await;
 8014
 8015            Some(())
 8016        })
 8017        .await;
 8018    }
 8019
 8020    fn maintain_workspace_config(
 8021        external_refresh_requests: watch::Receiver<()>,
 8022        cx: &mut Context<Self>,
 8023    ) -> Task<Result<()>> {
 8024        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8025        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8026
 8027        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8028            *settings_changed_tx.borrow_mut() = ();
 8029        });
 8030
 8031        let mut joint_future =
 8032            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8033        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8034        // - 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).
 8035        // - 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.
 8036        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8037        // - 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,
 8038        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8039        cx.spawn(async move |this, cx| {
 8040            while let Some(()) = joint_future.next().await {
 8041                this.update(cx, |this, cx| {
 8042                    this.refresh_server_tree(cx);
 8043                })
 8044                .ok();
 8045
 8046                Self::refresh_workspace_configurations(&this, cx).await;
 8047            }
 8048
 8049            drop(settings_observation);
 8050            anyhow::Ok(())
 8051        })
 8052    }
 8053
 8054    pub fn language_servers_for_local_buffer<'a>(
 8055        &'a self,
 8056        buffer: &Buffer,
 8057        cx: &mut App,
 8058    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8059        let local = self.as_local();
 8060        let language_server_ids = local
 8061            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8062            .unwrap_or_default();
 8063
 8064        language_server_ids
 8065            .into_iter()
 8066            .filter_map(
 8067                move |server_id| match local?.language_servers.get(&server_id)? {
 8068                    LanguageServerState::Running {
 8069                        adapter, server, ..
 8070                    } => Some((adapter, server)),
 8071                    _ => None,
 8072                },
 8073            )
 8074    }
 8075
 8076    pub fn language_server_for_local_buffer<'a>(
 8077        &'a self,
 8078        buffer: &'a Buffer,
 8079        server_id: LanguageServerId,
 8080        cx: &'a mut App,
 8081    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8082        self.as_local()?
 8083            .language_servers_for_buffer(buffer, cx)
 8084            .find(|(_, s)| s.server_id() == server_id)
 8085    }
 8086
 8087    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8088        self.diagnostic_summaries.remove(&id_to_remove);
 8089        if let Some(local) = self.as_local_mut() {
 8090            let to_remove = local.remove_worktree(id_to_remove, cx);
 8091            for server in to_remove {
 8092                self.language_server_statuses.remove(&server);
 8093            }
 8094        }
 8095    }
 8096
 8097    pub fn shared(
 8098        &mut self,
 8099        project_id: u64,
 8100        downstream_client: AnyProtoClient,
 8101        _: &mut Context<Self>,
 8102    ) {
 8103        self.downstream_client = Some((downstream_client.clone(), project_id));
 8104
 8105        for (server_id, status) in &self.language_server_statuses {
 8106            if let Some(server) = self.language_server_for_id(*server_id) {
 8107                downstream_client
 8108                    .send(proto::StartLanguageServer {
 8109                        project_id,
 8110                        server: Some(proto::LanguageServer {
 8111                            id: server_id.to_proto(),
 8112                            name: status.name.to_string(),
 8113                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8114                        }),
 8115                        capabilities: serde_json::to_string(&server.capabilities())
 8116                            .expect("serializing server LSP capabilities"),
 8117                    })
 8118                    .log_err();
 8119            }
 8120        }
 8121    }
 8122
 8123    pub fn disconnected_from_host(&mut self) {
 8124        self.downstream_client.take();
 8125    }
 8126
 8127    pub fn disconnected_from_ssh_remote(&mut self) {
 8128        if let LspStoreMode::Remote(RemoteLspStore {
 8129            upstream_client, ..
 8130        }) = &mut self.mode
 8131        {
 8132            upstream_client.take();
 8133        }
 8134    }
 8135
 8136    pub(crate) fn set_language_server_statuses_from_proto(
 8137        &mut self,
 8138        project: WeakEntity<Project>,
 8139        language_servers: Vec<proto::LanguageServer>,
 8140        server_capabilities: Vec<String>,
 8141        cx: &mut Context<Self>,
 8142    ) {
 8143        let lsp_logs = cx
 8144            .try_global::<GlobalLogStore>()
 8145            .map(|lsp_store| lsp_store.0.clone());
 8146
 8147        self.language_server_statuses = language_servers
 8148            .into_iter()
 8149            .zip(server_capabilities)
 8150            .map(|(server, server_capabilities)| {
 8151                let server_id = LanguageServerId(server.id as usize);
 8152                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8153                    self.lsp_server_capabilities
 8154                        .insert(server_id, server_capabilities);
 8155                }
 8156
 8157                let name = LanguageServerName::from_proto(server.name);
 8158                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8159
 8160                if let Some(lsp_logs) = &lsp_logs {
 8161                    lsp_logs.update(cx, |lsp_logs, cx| {
 8162                        lsp_logs.add_language_server(
 8163                            // Only remote clients get their language servers set from proto
 8164                            LanguageServerKind::Remote {
 8165                                project: project.clone(),
 8166                            },
 8167                            server_id,
 8168                            Some(name.clone()),
 8169                            worktree,
 8170                            None,
 8171                            cx,
 8172                        );
 8173                    });
 8174                }
 8175
 8176                (
 8177                    server_id,
 8178                    LanguageServerStatus {
 8179                        name,
 8180                        pending_work: Default::default(),
 8181                        has_pending_diagnostic_updates: false,
 8182                        progress_tokens: Default::default(),
 8183                        worktree,
 8184                        binary: None,
 8185                        configuration: None,
 8186                        workspace_folders: BTreeSet::new(),
 8187                    },
 8188                )
 8189            })
 8190            .collect();
 8191    }
 8192
 8193    #[cfg(test)]
 8194    pub fn update_diagnostic_entries(
 8195        &mut self,
 8196        server_id: LanguageServerId,
 8197        abs_path: PathBuf,
 8198        result_id: Option<String>,
 8199        version: Option<i32>,
 8200        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8201        cx: &mut Context<Self>,
 8202    ) -> anyhow::Result<()> {
 8203        self.merge_diagnostic_entries(
 8204            vec![DocumentDiagnosticsUpdate {
 8205                diagnostics: DocumentDiagnostics {
 8206                    diagnostics,
 8207                    document_abs_path: abs_path,
 8208                    version,
 8209                },
 8210                result_id,
 8211                server_id,
 8212                disk_based_sources: Cow::Borrowed(&[]),
 8213            }],
 8214            |_, _, _| false,
 8215            cx,
 8216        )?;
 8217        Ok(())
 8218    }
 8219
 8220    pub fn merge_diagnostic_entries<'a>(
 8221        &mut self,
 8222        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8223        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 8224        cx: &mut Context<Self>,
 8225    ) -> anyhow::Result<()> {
 8226        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8227        let mut updated_diagnostics_paths = HashMap::default();
 8228        for mut update in diagnostic_updates {
 8229            let abs_path = &update.diagnostics.document_abs_path;
 8230            let server_id = update.server_id;
 8231            let Some((worktree, relative_path)) =
 8232                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8233            else {
 8234                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8235                return Ok(());
 8236            };
 8237
 8238            let worktree_id = worktree.read(cx).id();
 8239            let project_path = ProjectPath {
 8240                worktree_id,
 8241                path: relative_path,
 8242            };
 8243
 8244            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8245                let snapshot = buffer_handle.read(cx).snapshot();
 8246                let buffer = buffer_handle.read(cx);
 8247                let reused_diagnostics = buffer
 8248                    .buffer_diagnostics(Some(server_id))
 8249                    .iter()
 8250                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8251                    .map(|v| {
 8252                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8253                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8254                        DiagnosticEntry {
 8255                            range: start..end,
 8256                            diagnostic: v.diagnostic.clone(),
 8257                        }
 8258                    })
 8259                    .collect::<Vec<_>>();
 8260
 8261                self.as_local_mut()
 8262                    .context("cannot merge diagnostics on a remote LspStore")?
 8263                    .update_buffer_diagnostics(
 8264                        &buffer_handle,
 8265                        server_id,
 8266                        update.result_id,
 8267                        update.diagnostics.version,
 8268                        update.diagnostics.diagnostics.clone(),
 8269                        reused_diagnostics.clone(),
 8270                        cx,
 8271                    )?;
 8272
 8273                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8274            }
 8275
 8276            let updated = worktree.update(cx, |worktree, cx| {
 8277                self.update_worktree_diagnostics(
 8278                    worktree.id(),
 8279                    server_id,
 8280                    project_path.path.clone(),
 8281                    update.diagnostics.diagnostics,
 8282                    cx,
 8283                )
 8284            })?;
 8285            match updated {
 8286                ControlFlow::Continue(new_summary) => {
 8287                    if let Some((project_id, new_summary)) = new_summary {
 8288                        match &mut diagnostics_summary {
 8289                            Some(diagnostics_summary) => {
 8290                                diagnostics_summary
 8291                                    .more_summaries
 8292                                    .push(proto::DiagnosticSummary {
 8293                                        path: project_path.path.as_ref().to_proto(),
 8294                                        language_server_id: server_id.0 as u64,
 8295                                        error_count: new_summary.error_count,
 8296                                        warning_count: new_summary.warning_count,
 8297                                    })
 8298                            }
 8299                            None => {
 8300                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8301                                    project_id,
 8302                                    worktree_id: worktree_id.to_proto(),
 8303                                    summary: Some(proto::DiagnosticSummary {
 8304                                        path: project_path.path.as_ref().to_proto(),
 8305                                        language_server_id: server_id.0 as u64,
 8306                                        error_count: new_summary.error_count,
 8307                                        warning_count: new_summary.warning_count,
 8308                                    }),
 8309                                    more_summaries: Vec::new(),
 8310                                })
 8311                            }
 8312                        }
 8313                    }
 8314                    updated_diagnostics_paths
 8315                        .entry(server_id)
 8316                        .or_insert_with(Vec::new)
 8317                        .push(project_path);
 8318                }
 8319                ControlFlow::Break(()) => {}
 8320            }
 8321        }
 8322
 8323        if let Some((diagnostics_summary, (downstream_client, _))) =
 8324            diagnostics_summary.zip(self.downstream_client.as_ref())
 8325        {
 8326            downstream_client.send(diagnostics_summary).log_err();
 8327        }
 8328        for (server_id, paths) in updated_diagnostics_paths {
 8329            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8330        }
 8331        Ok(())
 8332    }
 8333
 8334    fn update_worktree_diagnostics(
 8335        &mut self,
 8336        worktree_id: WorktreeId,
 8337        server_id: LanguageServerId,
 8338        path_in_worktree: Arc<RelPath>,
 8339        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8340        _: &mut Context<Worktree>,
 8341    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8342        let local = match &mut self.mode {
 8343            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8344            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8345        };
 8346
 8347        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8348        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8349        let summaries_by_server_id = summaries_for_tree
 8350            .entry(path_in_worktree.clone())
 8351            .or_default();
 8352
 8353        let old_summary = summaries_by_server_id
 8354            .remove(&server_id)
 8355            .unwrap_or_default();
 8356
 8357        let new_summary = DiagnosticSummary::new(&diagnostics);
 8358        if new_summary.is_empty() {
 8359            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8360            {
 8361                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8362                    diagnostics_by_server_id.remove(ix);
 8363                }
 8364                if diagnostics_by_server_id.is_empty() {
 8365                    diagnostics_for_tree.remove(&path_in_worktree);
 8366                }
 8367            }
 8368        } else {
 8369            summaries_by_server_id.insert(server_id, new_summary);
 8370            let diagnostics_by_server_id = diagnostics_for_tree
 8371                .entry(path_in_worktree.clone())
 8372                .or_default();
 8373            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8374                Ok(ix) => {
 8375                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8376                }
 8377                Err(ix) => {
 8378                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8379                }
 8380            }
 8381        }
 8382
 8383        if !old_summary.is_empty() || !new_summary.is_empty() {
 8384            if let Some((_, project_id)) = &self.downstream_client {
 8385                Ok(ControlFlow::Continue(Some((
 8386                    *project_id,
 8387                    proto::DiagnosticSummary {
 8388                        path: path_in_worktree.to_proto(),
 8389                        language_server_id: server_id.0 as u64,
 8390                        error_count: new_summary.error_count as u32,
 8391                        warning_count: new_summary.warning_count as u32,
 8392                    },
 8393                ))))
 8394            } else {
 8395                Ok(ControlFlow::Continue(None))
 8396            }
 8397        } else {
 8398            Ok(ControlFlow::Break(()))
 8399        }
 8400    }
 8401
 8402    pub fn open_buffer_for_symbol(
 8403        &mut self,
 8404        symbol: &Symbol,
 8405        cx: &mut Context<Self>,
 8406    ) -> Task<Result<Entity<Buffer>>> {
 8407        if let Some((client, project_id)) = self.upstream_client() {
 8408            let request = client.request(proto::OpenBufferForSymbol {
 8409                project_id,
 8410                symbol: Some(Self::serialize_symbol(symbol)),
 8411            });
 8412            cx.spawn(async move |this, cx| {
 8413                let response = request.await?;
 8414                let buffer_id = BufferId::new(response.buffer_id)?;
 8415                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8416                    .await
 8417            })
 8418        } else if let Some(local) = self.as_local() {
 8419            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8420                seed.worktree_id == symbol.source_worktree_id
 8421                    && state.id == symbol.source_language_server_id
 8422                    && symbol.language_server_name == seed.name
 8423            });
 8424            if !is_valid {
 8425                return Task::ready(Err(anyhow!(
 8426                    "language server for worktree and language not found"
 8427                )));
 8428            };
 8429
 8430            let symbol_abs_path = match &symbol.path {
 8431                SymbolLocation::InProject(project_path) => self
 8432                    .worktree_store
 8433                    .read(cx)
 8434                    .absolutize(&project_path, cx)
 8435                    .context("no such worktree"),
 8436                SymbolLocation::OutsideProject {
 8437                    abs_path,
 8438                    signature: _,
 8439                } => Ok(abs_path.to_path_buf()),
 8440            };
 8441            let symbol_abs_path = match symbol_abs_path {
 8442                Ok(abs_path) => abs_path,
 8443                Err(err) => return Task::ready(Err(err)),
 8444            };
 8445            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8446                uri
 8447            } else {
 8448                return Task::ready(Err(anyhow!("invalid symbol path")));
 8449            };
 8450
 8451            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8452        } else {
 8453            Task::ready(Err(anyhow!("no upstream client or local store")))
 8454        }
 8455    }
 8456
 8457    pub(crate) fn open_local_buffer_via_lsp(
 8458        &mut self,
 8459        abs_path: lsp::Uri,
 8460        language_server_id: LanguageServerId,
 8461        cx: &mut Context<Self>,
 8462    ) -> Task<Result<Entity<Buffer>>> {
 8463        cx.spawn(async move |lsp_store, cx| {
 8464            // Escape percent-encoded string.
 8465            let current_scheme = abs_path.scheme().to_owned();
 8466            // Uri is immutable, so we can't modify the scheme
 8467
 8468            let abs_path = abs_path
 8469                .to_file_path()
 8470                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8471            let p = abs_path.clone();
 8472            let yarn_worktree = lsp_store
 8473                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8474                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8475                        cx.spawn(async move |this, cx| {
 8476                            let t = this
 8477                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8478                                .ok()?;
 8479                            t.await
 8480                        })
 8481                    }),
 8482                    None => Task::ready(None),
 8483                })?
 8484                .await;
 8485            let (worktree_root_target, known_relative_path) =
 8486                if let Some((zip_root, relative_path)) = yarn_worktree {
 8487                    (zip_root, Some(relative_path))
 8488                } else {
 8489                    (Arc::<Path>::from(abs_path.as_path()), None)
 8490                };
 8491            let (worktree, relative_path) = if let Some(result) =
 8492                lsp_store.update(cx, |lsp_store, cx| {
 8493                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8494                        worktree_store.find_worktree(&worktree_root_target, cx)
 8495                    })
 8496                })? {
 8497                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8498                (result.0, relative_path)
 8499            } else {
 8500                let worktree = lsp_store
 8501                    .update(cx, |lsp_store, cx| {
 8502                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8503                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8504                        })
 8505                    })?
 8506                    .await?;
 8507                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8508                    lsp_store
 8509                        .update(cx, |lsp_store, cx| {
 8510                            if let Some(local) = lsp_store.as_local_mut() {
 8511                                local.register_language_server_for_invisible_worktree(
 8512                                    &worktree,
 8513                                    language_server_id,
 8514                                    cx,
 8515                                )
 8516                            }
 8517                        })
 8518                        .ok();
 8519                }
 8520                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8521                let relative_path = if let Some(known_path) = known_relative_path {
 8522                    known_path
 8523                } else {
 8524                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8525                        .into_arc()
 8526                };
 8527                (worktree, relative_path)
 8528            };
 8529            let project_path = ProjectPath {
 8530                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8531                path: relative_path,
 8532            };
 8533            lsp_store
 8534                .update(cx, |lsp_store, cx| {
 8535                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8536                        buffer_store.open_buffer(project_path, cx)
 8537                    })
 8538                })?
 8539                .await
 8540        })
 8541    }
 8542
 8543    fn request_multiple_lsp_locally<P, R>(
 8544        &mut self,
 8545        buffer: &Entity<Buffer>,
 8546        position: Option<P>,
 8547        request: R,
 8548        cx: &mut Context<Self>,
 8549    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8550    where
 8551        P: ToOffset,
 8552        R: LspCommand + Clone,
 8553        <R::LspRequest as lsp::request::Request>::Result: Send,
 8554        <R::LspRequest as lsp::request::Request>::Params: Send,
 8555    {
 8556        let Some(local) = self.as_local() else {
 8557            return Task::ready(Vec::new());
 8558        };
 8559
 8560        let snapshot = buffer.read(cx).snapshot();
 8561        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8562
 8563        let server_ids = buffer.update(cx, |buffer, cx| {
 8564            local
 8565                .language_servers_for_buffer(buffer, cx)
 8566                .filter(|(adapter, _)| {
 8567                    scope
 8568                        .as_ref()
 8569                        .map(|scope| scope.language_allowed(&adapter.name))
 8570                        .unwrap_or(true)
 8571                })
 8572                .map(|(_, server)| server.server_id())
 8573                .filter(|server_id| {
 8574                    self.as_local().is_none_or(|local| {
 8575                        local
 8576                            .buffers_opened_in_servers
 8577                            .get(&snapshot.remote_id())
 8578                            .is_some_and(|servers| servers.contains(server_id))
 8579                    })
 8580                })
 8581                .collect::<Vec<_>>()
 8582        });
 8583
 8584        let mut response_results = server_ids
 8585            .into_iter()
 8586            .map(|server_id| {
 8587                let task = self.request_lsp(
 8588                    buffer.clone(),
 8589                    LanguageServerToQuery::Other(server_id),
 8590                    request.clone(),
 8591                    cx,
 8592                );
 8593                async move { (server_id, task.await) }
 8594            })
 8595            .collect::<FuturesUnordered<_>>();
 8596
 8597        cx.background_spawn(async move {
 8598            let mut responses = Vec::with_capacity(response_results.len());
 8599            while let Some((server_id, response_result)) = response_results.next().await {
 8600                match response_result {
 8601                    Ok(response) => responses.push((server_id, response)),
 8602                    // rust-analyzer likes to error with this when its still loading up
 8603                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8604                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8605                }
 8606            }
 8607            responses
 8608        })
 8609    }
 8610
 8611    async fn handle_lsp_get_completions(
 8612        this: Entity<Self>,
 8613        envelope: TypedEnvelope<proto::GetCompletions>,
 8614        mut cx: AsyncApp,
 8615    ) -> Result<proto::GetCompletionsResponse> {
 8616        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8617
 8618        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8619        let buffer_handle = this.update(&mut cx, |this, cx| {
 8620            this.buffer_store.read(cx).get_existing(buffer_id)
 8621        })??;
 8622        let request = GetCompletions::from_proto(
 8623            envelope.payload,
 8624            this.clone(),
 8625            buffer_handle.clone(),
 8626            cx.clone(),
 8627        )
 8628        .await?;
 8629
 8630        let server_to_query = match request.server_id {
 8631            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8632            None => LanguageServerToQuery::FirstCapable,
 8633        };
 8634
 8635        let response = this
 8636            .update(&mut cx, |this, cx| {
 8637                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8638            })?
 8639            .await?;
 8640        this.update(&mut cx, |this, cx| {
 8641            Ok(GetCompletions::response_to_proto(
 8642                response,
 8643                this,
 8644                sender_id,
 8645                &buffer_handle.read(cx).version(),
 8646                cx,
 8647            ))
 8648        })?
 8649    }
 8650
 8651    async fn handle_lsp_command<T: LspCommand>(
 8652        this: Entity<Self>,
 8653        envelope: TypedEnvelope<T::ProtoRequest>,
 8654        mut cx: AsyncApp,
 8655    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8656    where
 8657        <T::LspRequest as lsp::request::Request>::Params: Send,
 8658        <T::LspRequest as lsp::request::Request>::Result: Send,
 8659    {
 8660        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8661        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8662        let buffer_handle = this.update(&mut cx, |this, cx| {
 8663            this.buffer_store.read(cx).get_existing(buffer_id)
 8664        })??;
 8665        let request = T::from_proto(
 8666            envelope.payload,
 8667            this.clone(),
 8668            buffer_handle.clone(),
 8669            cx.clone(),
 8670        )
 8671        .await?;
 8672        let response = this
 8673            .update(&mut cx, |this, cx| {
 8674                this.request_lsp(
 8675                    buffer_handle.clone(),
 8676                    LanguageServerToQuery::FirstCapable,
 8677                    request,
 8678                    cx,
 8679                )
 8680            })?
 8681            .await?;
 8682        this.update(&mut cx, |this, cx| {
 8683            Ok(T::response_to_proto(
 8684                response,
 8685                this,
 8686                sender_id,
 8687                &buffer_handle.read(cx).version(),
 8688                cx,
 8689            ))
 8690        })?
 8691    }
 8692
 8693    async fn handle_lsp_query(
 8694        lsp_store: Entity<Self>,
 8695        envelope: TypedEnvelope<proto::LspQuery>,
 8696        mut cx: AsyncApp,
 8697    ) -> Result<proto::Ack> {
 8698        use proto::lsp_query::Request;
 8699        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8700        let lsp_query = envelope.payload;
 8701        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8702        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8703        match lsp_query.request.context("invalid LSP query request")? {
 8704            Request::GetReferences(get_references) => {
 8705                let position = get_references.position.clone().and_then(deserialize_anchor);
 8706                Self::query_lsp_locally::<GetReferences>(
 8707                    lsp_store,
 8708                    server_id,
 8709                    sender_id,
 8710                    lsp_request_id,
 8711                    get_references,
 8712                    position,
 8713                    &mut cx,
 8714                )
 8715                .await?;
 8716            }
 8717            Request::GetDocumentColor(get_document_color) => {
 8718                Self::query_lsp_locally::<GetDocumentColor>(
 8719                    lsp_store,
 8720                    server_id,
 8721                    sender_id,
 8722                    lsp_request_id,
 8723                    get_document_color,
 8724                    None,
 8725                    &mut cx,
 8726                )
 8727                .await?;
 8728            }
 8729            Request::GetHover(get_hover) => {
 8730                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8731                Self::query_lsp_locally::<GetHover>(
 8732                    lsp_store,
 8733                    server_id,
 8734                    sender_id,
 8735                    lsp_request_id,
 8736                    get_hover,
 8737                    position,
 8738                    &mut cx,
 8739                )
 8740                .await?;
 8741            }
 8742            Request::GetCodeActions(get_code_actions) => {
 8743                Self::query_lsp_locally::<GetCodeActions>(
 8744                    lsp_store,
 8745                    server_id,
 8746                    sender_id,
 8747                    lsp_request_id,
 8748                    get_code_actions,
 8749                    None,
 8750                    &mut cx,
 8751                )
 8752                .await?;
 8753            }
 8754            Request::GetSignatureHelp(get_signature_help) => {
 8755                let position = get_signature_help
 8756                    .position
 8757                    .clone()
 8758                    .and_then(deserialize_anchor);
 8759                Self::query_lsp_locally::<GetSignatureHelp>(
 8760                    lsp_store,
 8761                    server_id,
 8762                    sender_id,
 8763                    lsp_request_id,
 8764                    get_signature_help,
 8765                    position,
 8766                    &mut cx,
 8767                )
 8768                .await?;
 8769            }
 8770            Request::GetCodeLens(get_code_lens) => {
 8771                Self::query_lsp_locally::<GetCodeLens>(
 8772                    lsp_store,
 8773                    server_id,
 8774                    sender_id,
 8775                    lsp_request_id,
 8776                    get_code_lens,
 8777                    None,
 8778                    &mut cx,
 8779                )
 8780                .await?;
 8781            }
 8782            Request::GetDefinition(get_definition) => {
 8783                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8784                Self::query_lsp_locally::<GetDefinitions>(
 8785                    lsp_store,
 8786                    server_id,
 8787                    sender_id,
 8788                    lsp_request_id,
 8789                    get_definition,
 8790                    position,
 8791                    &mut cx,
 8792                )
 8793                .await?;
 8794            }
 8795            Request::GetDeclaration(get_declaration) => {
 8796                let position = get_declaration
 8797                    .position
 8798                    .clone()
 8799                    .and_then(deserialize_anchor);
 8800                Self::query_lsp_locally::<GetDeclarations>(
 8801                    lsp_store,
 8802                    server_id,
 8803                    sender_id,
 8804                    lsp_request_id,
 8805                    get_declaration,
 8806                    position,
 8807                    &mut cx,
 8808                )
 8809                .await?;
 8810            }
 8811            Request::GetTypeDefinition(get_type_definition) => {
 8812                let position = get_type_definition
 8813                    .position
 8814                    .clone()
 8815                    .and_then(deserialize_anchor);
 8816                Self::query_lsp_locally::<GetTypeDefinitions>(
 8817                    lsp_store,
 8818                    server_id,
 8819                    sender_id,
 8820                    lsp_request_id,
 8821                    get_type_definition,
 8822                    position,
 8823                    &mut cx,
 8824                )
 8825                .await?;
 8826            }
 8827            Request::GetImplementation(get_implementation) => {
 8828                let position = get_implementation
 8829                    .position
 8830                    .clone()
 8831                    .and_then(deserialize_anchor);
 8832                Self::query_lsp_locally::<GetImplementations>(
 8833                    lsp_store,
 8834                    server_id,
 8835                    sender_id,
 8836                    lsp_request_id,
 8837                    get_implementation,
 8838                    position,
 8839                    &mut cx,
 8840                )
 8841                .await?;
 8842            }
 8843            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8844                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8845                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8846                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8847                    this.buffer_store.read(cx).get_existing(buffer_id)
 8848                })??;
 8849                buffer
 8850                    .update(&mut cx, |buffer, _| {
 8851                        buffer.wait_for_version(version.clone())
 8852                    })?
 8853                    .await?;
 8854                lsp_store.update(&mut cx, |lsp_store, cx| {
 8855                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8856                    let key = LspKey {
 8857                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8858                        server_queried: server_id,
 8859                    };
 8860                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8861                    ) {
 8862                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8863                            lsp_requests.clear();
 8864                        };
 8865                    }
 8866
 8867                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8868                    existing_queries.insert(
 8869                        lsp_request_id,
 8870                        cx.spawn(async move |lsp_store, cx| {
 8871                            let diagnostics_pull = lsp_store
 8872                                .update(cx, |lsp_store, cx| {
 8873                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8874                                })
 8875                                .ok();
 8876                            if let Some(diagnostics_pull) = diagnostics_pull {
 8877                                match diagnostics_pull.await {
 8878                                    Ok(()) => {}
 8879                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8880                                };
 8881                            }
 8882                        }),
 8883                    );
 8884                })?;
 8885            }
 8886            Request::InlayHints(inlay_hints) => {
 8887                let query_start = inlay_hints
 8888                    .start
 8889                    .clone()
 8890                    .and_then(deserialize_anchor)
 8891                    .context("invalid inlay hints range start")?;
 8892                let query_end = inlay_hints
 8893                    .end
 8894                    .clone()
 8895                    .and_then(deserialize_anchor)
 8896                    .context("invalid inlay hints range end")?;
 8897                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8898                    &lsp_store,
 8899                    server_id,
 8900                    lsp_request_id,
 8901                    &inlay_hints,
 8902                    query_start..query_end,
 8903                    &mut cx,
 8904                )
 8905                .await
 8906                .context("preparing inlay hints request")?;
 8907                Self::query_lsp_locally::<InlayHints>(
 8908                    lsp_store,
 8909                    server_id,
 8910                    sender_id,
 8911                    lsp_request_id,
 8912                    inlay_hints,
 8913                    None,
 8914                    &mut cx,
 8915                )
 8916                .await
 8917                .context("querying for inlay hints")?
 8918            }
 8919        }
 8920        Ok(proto::Ack {})
 8921    }
 8922
 8923    async fn handle_lsp_query_response(
 8924        lsp_store: Entity<Self>,
 8925        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8926        cx: AsyncApp,
 8927    ) -> Result<()> {
 8928        lsp_store.read_with(&cx, |lsp_store, _| {
 8929            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8930                upstream_client.handle_lsp_response(envelope.clone());
 8931            }
 8932        })?;
 8933        Ok(())
 8934    }
 8935
 8936    async fn handle_apply_code_action(
 8937        this: Entity<Self>,
 8938        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8939        mut cx: AsyncApp,
 8940    ) -> Result<proto::ApplyCodeActionResponse> {
 8941        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8942        let action =
 8943            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8944        let apply_code_action = this.update(&mut cx, |this, cx| {
 8945            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8946            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8947            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8948        })??;
 8949
 8950        let project_transaction = apply_code_action.await?;
 8951        let project_transaction = this.update(&mut cx, |this, cx| {
 8952            this.buffer_store.update(cx, |buffer_store, cx| {
 8953                buffer_store.serialize_project_transaction_for_peer(
 8954                    project_transaction,
 8955                    sender_id,
 8956                    cx,
 8957                )
 8958            })
 8959        })?;
 8960        Ok(proto::ApplyCodeActionResponse {
 8961            transaction: Some(project_transaction),
 8962        })
 8963    }
 8964
 8965    async fn handle_register_buffer_with_language_servers(
 8966        this: Entity<Self>,
 8967        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8968        mut cx: AsyncApp,
 8969    ) -> Result<proto::Ack> {
 8970        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8971        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8972        this.update(&mut cx, |this, cx| {
 8973            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8974                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8975                    project_id: upstream_project_id,
 8976                    buffer_id: buffer_id.to_proto(),
 8977                    only_servers: envelope.payload.only_servers,
 8978                });
 8979            }
 8980
 8981            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8982                anyhow::bail!("buffer is not open");
 8983            };
 8984
 8985            let handle = this.register_buffer_with_language_servers(
 8986                &buffer,
 8987                envelope
 8988                    .payload
 8989                    .only_servers
 8990                    .into_iter()
 8991                    .filter_map(|selector| {
 8992                        Some(match selector.selector? {
 8993                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8994                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8995                            }
 8996                            proto::language_server_selector::Selector::Name(name) => {
 8997                                LanguageServerSelector::Name(LanguageServerName(
 8998                                    SharedString::from(name),
 8999                                ))
 9000                            }
 9001                        })
 9002                    })
 9003                    .collect(),
 9004                false,
 9005                cx,
 9006            );
 9007            this.buffer_store().update(cx, |buffer_store, _| {
 9008                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9009            });
 9010
 9011            Ok(())
 9012        })??;
 9013        Ok(proto::Ack {})
 9014    }
 9015
 9016    async fn handle_rename_project_entry(
 9017        this: Entity<Self>,
 9018        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9019        mut cx: AsyncApp,
 9020    ) -> Result<proto::ProjectEntryResponse> {
 9021        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9022        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9023        let new_path =
 9024            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9025
 9026        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9027            .update(&mut cx, |this, cx| {
 9028                let (worktree, entry) = this
 9029                    .worktree_store
 9030                    .read(cx)
 9031                    .worktree_and_entry_for_id(entry_id, cx)?;
 9032                let new_worktree = this
 9033                    .worktree_store
 9034                    .read(cx)
 9035                    .worktree_for_id(new_worktree_id, cx)?;
 9036                Some((
 9037                    this.worktree_store.clone(),
 9038                    worktree,
 9039                    new_worktree,
 9040                    entry.clone(),
 9041                ))
 9042            })?
 9043            .context("worktree not found")?;
 9044        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9045            (worktree.absolutize(&old_entry.path), worktree.id())
 9046        })?;
 9047        let new_abs_path =
 9048            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9049
 9050        let _transaction = Self::will_rename_entry(
 9051            this.downgrade(),
 9052            old_worktree_id,
 9053            &old_abs_path,
 9054            &new_abs_path,
 9055            old_entry.is_dir(),
 9056            cx.clone(),
 9057        )
 9058        .await;
 9059        let response = WorktreeStore::handle_rename_project_entry(
 9060            worktree_store,
 9061            envelope.payload,
 9062            cx.clone(),
 9063        )
 9064        .await;
 9065        this.read_with(&cx, |this, _| {
 9066            this.did_rename_entry(
 9067                old_worktree_id,
 9068                &old_abs_path,
 9069                &new_abs_path,
 9070                old_entry.is_dir(),
 9071            );
 9072        })
 9073        .ok();
 9074        response
 9075    }
 9076
 9077    async fn handle_update_diagnostic_summary(
 9078        this: Entity<Self>,
 9079        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9080        mut cx: AsyncApp,
 9081    ) -> Result<()> {
 9082        this.update(&mut cx, |lsp_store, cx| {
 9083            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9084            let mut updated_diagnostics_paths = HashMap::default();
 9085            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9086            for message_summary in envelope
 9087                .payload
 9088                .summary
 9089                .into_iter()
 9090                .chain(envelope.payload.more_summaries)
 9091            {
 9092                let project_path = ProjectPath {
 9093                    worktree_id,
 9094                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9095                };
 9096                let path = project_path.path.clone();
 9097                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9098                let summary = DiagnosticSummary {
 9099                    error_count: message_summary.error_count as usize,
 9100                    warning_count: message_summary.warning_count as usize,
 9101                };
 9102
 9103                if summary.is_empty() {
 9104                    if let Some(worktree_summaries) =
 9105                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9106                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9107                    {
 9108                        summaries.remove(&server_id);
 9109                        if summaries.is_empty() {
 9110                            worktree_summaries.remove(&path);
 9111                        }
 9112                    }
 9113                } else {
 9114                    lsp_store
 9115                        .diagnostic_summaries
 9116                        .entry(worktree_id)
 9117                        .or_default()
 9118                        .entry(path)
 9119                        .or_default()
 9120                        .insert(server_id, summary);
 9121                }
 9122
 9123                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9124                    match &mut diagnostics_summary {
 9125                        Some(diagnostics_summary) => {
 9126                            diagnostics_summary
 9127                                .more_summaries
 9128                                .push(proto::DiagnosticSummary {
 9129                                    path: project_path.path.as_ref().to_proto(),
 9130                                    language_server_id: server_id.0 as u64,
 9131                                    error_count: summary.error_count as u32,
 9132                                    warning_count: summary.warning_count as u32,
 9133                                })
 9134                        }
 9135                        None => {
 9136                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9137                                project_id: *project_id,
 9138                                worktree_id: worktree_id.to_proto(),
 9139                                summary: Some(proto::DiagnosticSummary {
 9140                                    path: project_path.path.as_ref().to_proto(),
 9141                                    language_server_id: server_id.0 as u64,
 9142                                    error_count: summary.error_count as u32,
 9143                                    warning_count: summary.warning_count as u32,
 9144                                }),
 9145                                more_summaries: Vec::new(),
 9146                            })
 9147                        }
 9148                    }
 9149                }
 9150                updated_diagnostics_paths
 9151                    .entry(server_id)
 9152                    .or_insert_with(Vec::new)
 9153                    .push(project_path);
 9154            }
 9155
 9156            if let Some((diagnostics_summary, (downstream_client, _))) =
 9157                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9158            {
 9159                downstream_client.send(diagnostics_summary).log_err();
 9160            }
 9161            for (server_id, paths) in updated_diagnostics_paths {
 9162                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9163            }
 9164            Ok(())
 9165        })?
 9166    }
 9167
 9168    async fn handle_start_language_server(
 9169        lsp_store: Entity<Self>,
 9170        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9171        mut cx: AsyncApp,
 9172    ) -> Result<()> {
 9173        let server = envelope.payload.server.context("invalid server")?;
 9174        let server_capabilities =
 9175            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9176                .with_context(|| {
 9177                    format!(
 9178                        "incorrect server capabilities {}",
 9179                        envelope.payload.capabilities
 9180                    )
 9181                })?;
 9182        lsp_store.update(&mut cx, |lsp_store, cx| {
 9183            let server_id = LanguageServerId(server.id as usize);
 9184            let server_name = LanguageServerName::from_proto(server.name.clone());
 9185            lsp_store
 9186                .lsp_server_capabilities
 9187                .insert(server_id, server_capabilities);
 9188            lsp_store.language_server_statuses.insert(
 9189                server_id,
 9190                LanguageServerStatus {
 9191                    name: server_name.clone(),
 9192                    pending_work: Default::default(),
 9193                    has_pending_diagnostic_updates: false,
 9194                    progress_tokens: Default::default(),
 9195                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9196                    binary: None,
 9197                    configuration: None,
 9198                    workspace_folders: BTreeSet::new(),
 9199                },
 9200            );
 9201            cx.emit(LspStoreEvent::LanguageServerAdded(
 9202                server_id,
 9203                server_name,
 9204                server.worktree_id.map(WorktreeId::from_proto),
 9205            ));
 9206            cx.notify();
 9207        })?;
 9208        Ok(())
 9209    }
 9210
 9211    async fn handle_update_language_server(
 9212        lsp_store: Entity<Self>,
 9213        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9214        mut cx: AsyncApp,
 9215    ) -> Result<()> {
 9216        lsp_store.update(&mut cx, |lsp_store, cx| {
 9217            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9218
 9219            match envelope.payload.variant.context("invalid variant")? {
 9220                proto::update_language_server::Variant::WorkStart(payload) => {
 9221                    lsp_store.on_lsp_work_start(
 9222                        language_server_id,
 9223                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9224                            .context("invalid progress token value")?,
 9225                        LanguageServerProgress {
 9226                            title: payload.title,
 9227                            is_disk_based_diagnostics_progress: false,
 9228                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9229                            message: payload.message,
 9230                            percentage: payload.percentage.map(|p| p as usize),
 9231                            last_update_at: cx.background_executor().now(),
 9232                        },
 9233                        cx,
 9234                    );
 9235                }
 9236                proto::update_language_server::Variant::WorkProgress(payload) => {
 9237                    lsp_store.on_lsp_work_progress(
 9238                        language_server_id,
 9239                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9240                            .context("invalid progress token value")?,
 9241                        LanguageServerProgress {
 9242                            title: None,
 9243                            is_disk_based_diagnostics_progress: false,
 9244                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9245                            message: payload.message,
 9246                            percentage: payload.percentage.map(|p| p as usize),
 9247                            last_update_at: cx.background_executor().now(),
 9248                        },
 9249                        cx,
 9250                    );
 9251                }
 9252
 9253                proto::update_language_server::Variant::WorkEnd(payload) => {
 9254                    lsp_store.on_lsp_work_end(
 9255                        language_server_id,
 9256                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9257                            .context("invalid progress token value")?,
 9258                        cx,
 9259                    );
 9260                }
 9261
 9262                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9263                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9264                }
 9265
 9266                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9267                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9268                }
 9269
 9270                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9271                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9272                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9273                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9274                        language_server_id,
 9275                        name: envelope
 9276                            .payload
 9277                            .server_name
 9278                            .map(SharedString::new)
 9279                            .map(LanguageServerName),
 9280                        message: non_lsp,
 9281                    });
 9282                }
 9283            }
 9284
 9285            Ok(())
 9286        })?
 9287    }
 9288
 9289    async fn handle_language_server_log(
 9290        this: Entity<Self>,
 9291        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9292        mut cx: AsyncApp,
 9293    ) -> Result<()> {
 9294        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9295        let log_type = envelope
 9296            .payload
 9297            .log_type
 9298            .map(LanguageServerLogType::from_proto)
 9299            .context("invalid language server log type")?;
 9300
 9301        let message = envelope.payload.message;
 9302
 9303        this.update(&mut cx, |_, cx| {
 9304            cx.emit(LspStoreEvent::LanguageServerLog(
 9305                language_server_id,
 9306                log_type,
 9307                message,
 9308            ));
 9309        })
 9310    }
 9311
 9312    async fn handle_lsp_ext_cancel_flycheck(
 9313        lsp_store: Entity<Self>,
 9314        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9315        cx: AsyncApp,
 9316    ) -> Result<proto::Ack> {
 9317        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9318        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9319            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9320                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9321            } else {
 9322                None
 9323            }
 9324        })?;
 9325        if let Some(task) = task {
 9326            task.context("handling lsp ext cancel flycheck")?;
 9327        }
 9328
 9329        Ok(proto::Ack {})
 9330    }
 9331
 9332    async fn handle_lsp_ext_run_flycheck(
 9333        lsp_store: Entity<Self>,
 9334        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9335        mut cx: AsyncApp,
 9336    ) -> Result<proto::Ack> {
 9337        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9338        lsp_store.update(&mut cx, |lsp_store, cx| {
 9339            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9340                let text_document = if envelope.payload.current_file_only {
 9341                    let buffer_id = envelope
 9342                        .payload
 9343                        .buffer_id
 9344                        .map(|id| BufferId::new(id))
 9345                        .transpose()?;
 9346                    buffer_id
 9347                        .and_then(|buffer_id| {
 9348                            lsp_store
 9349                                .buffer_store()
 9350                                .read(cx)
 9351                                .get(buffer_id)
 9352                                .and_then(|buffer| {
 9353                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9354                                })
 9355                                .map(|path| make_text_document_identifier(&path))
 9356                        })
 9357                        .transpose()?
 9358                } else {
 9359                    None
 9360                };
 9361                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9362                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9363                )?;
 9364            }
 9365            anyhow::Ok(())
 9366        })??;
 9367
 9368        Ok(proto::Ack {})
 9369    }
 9370
 9371    async fn handle_lsp_ext_clear_flycheck(
 9372        lsp_store: Entity<Self>,
 9373        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9374        cx: AsyncApp,
 9375    ) -> Result<proto::Ack> {
 9376        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9377        lsp_store
 9378            .read_with(&cx, |lsp_store, _| {
 9379                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9380                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9381                } else {
 9382                    None
 9383                }
 9384            })
 9385            .context("handling lsp ext clear flycheck")?;
 9386
 9387        Ok(proto::Ack {})
 9388    }
 9389
 9390    pub fn disk_based_diagnostics_started(
 9391        &mut self,
 9392        language_server_id: LanguageServerId,
 9393        cx: &mut Context<Self>,
 9394    ) {
 9395        if let Some(language_server_status) =
 9396            self.language_server_statuses.get_mut(&language_server_id)
 9397        {
 9398            language_server_status.has_pending_diagnostic_updates = true;
 9399        }
 9400
 9401        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9402        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9403            language_server_id,
 9404            name: self
 9405                .language_server_adapter_for_id(language_server_id)
 9406                .map(|adapter| adapter.name()),
 9407            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9408                Default::default(),
 9409            ),
 9410        })
 9411    }
 9412
 9413    pub fn disk_based_diagnostics_finished(
 9414        &mut self,
 9415        language_server_id: LanguageServerId,
 9416        cx: &mut Context<Self>,
 9417    ) {
 9418        if let Some(language_server_status) =
 9419            self.language_server_statuses.get_mut(&language_server_id)
 9420        {
 9421            language_server_status.has_pending_diagnostic_updates = false;
 9422        }
 9423
 9424        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9425        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9426            language_server_id,
 9427            name: self
 9428                .language_server_adapter_for_id(language_server_id)
 9429                .map(|adapter| adapter.name()),
 9430            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9431                Default::default(),
 9432            ),
 9433        })
 9434    }
 9435
 9436    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9437    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9438    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9439    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9440    // the language server might take some time to publish diagnostics.
 9441    fn simulate_disk_based_diagnostics_events_if_needed(
 9442        &mut self,
 9443        language_server_id: LanguageServerId,
 9444        cx: &mut Context<Self>,
 9445    ) {
 9446        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9447
 9448        let Some(LanguageServerState::Running {
 9449            simulate_disk_based_diagnostics_completion,
 9450            adapter,
 9451            ..
 9452        }) = self
 9453            .as_local_mut()
 9454            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9455        else {
 9456            return;
 9457        };
 9458
 9459        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9460            return;
 9461        }
 9462
 9463        let prev_task =
 9464            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9465                cx.background_executor()
 9466                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9467                    .await;
 9468
 9469                this.update(cx, |this, cx| {
 9470                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9471
 9472                    if let Some(LanguageServerState::Running {
 9473                        simulate_disk_based_diagnostics_completion,
 9474                        ..
 9475                    }) = this.as_local_mut().and_then(|local_store| {
 9476                        local_store.language_servers.get_mut(&language_server_id)
 9477                    }) {
 9478                        *simulate_disk_based_diagnostics_completion = None;
 9479                    }
 9480                })
 9481                .ok();
 9482            }));
 9483
 9484        if prev_task.is_none() {
 9485            self.disk_based_diagnostics_started(language_server_id, cx);
 9486        }
 9487    }
 9488
 9489    pub fn language_server_statuses(
 9490        &self,
 9491    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9492        self.language_server_statuses
 9493            .iter()
 9494            .map(|(key, value)| (*key, value))
 9495    }
 9496
 9497    pub(super) fn did_rename_entry(
 9498        &self,
 9499        worktree_id: WorktreeId,
 9500        old_path: &Path,
 9501        new_path: &Path,
 9502        is_dir: bool,
 9503    ) {
 9504        maybe!({
 9505            let local_store = self.as_local()?;
 9506
 9507            let old_uri = lsp::Uri::from_file_path(old_path)
 9508                .ok()
 9509                .map(|uri| uri.to_string())?;
 9510            let new_uri = lsp::Uri::from_file_path(new_path)
 9511                .ok()
 9512                .map(|uri| uri.to_string())?;
 9513
 9514            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9515                let Some(filter) = local_store
 9516                    .language_server_paths_watched_for_rename
 9517                    .get(&language_server.server_id())
 9518                else {
 9519                    continue;
 9520                };
 9521
 9522                if filter.should_send_did_rename(&old_uri, is_dir) {
 9523                    language_server
 9524                        .notify::<DidRenameFiles>(RenameFilesParams {
 9525                            files: vec![FileRename {
 9526                                old_uri: old_uri.clone(),
 9527                                new_uri: new_uri.clone(),
 9528                            }],
 9529                        })
 9530                        .ok();
 9531                }
 9532            }
 9533            Some(())
 9534        });
 9535    }
 9536
 9537    pub(super) fn will_rename_entry(
 9538        this: WeakEntity<Self>,
 9539        worktree_id: WorktreeId,
 9540        old_path: &Path,
 9541        new_path: &Path,
 9542        is_dir: bool,
 9543        cx: AsyncApp,
 9544    ) -> Task<ProjectTransaction> {
 9545        let old_uri = lsp::Uri::from_file_path(old_path)
 9546            .ok()
 9547            .map(|uri| uri.to_string());
 9548        let new_uri = lsp::Uri::from_file_path(new_path)
 9549            .ok()
 9550            .map(|uri| uri.to_string());
 9551        cx.spawn(async move |cx| {
 9552            let mut tasks = vec![];
 9553            this.update(cx, |this, cx| {
 9554                let local_store = this.as_local()?;
 9555                let old_uri = old_uri?;
 9556                let new_uri = new_uri?;
 9557                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9558                    let Some(filter) = local_store
 9559                        .language_server_paths_watched_for_rename
 9560                        .get(&language_server.server_id())
 9561                    else {
 9562                        continue;
 9563                    };
 9564
 9565                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9566                        let apply_edit = cx.spawn({
 9567                            let old_uri = old_uri.clone();
 9568                            let new_uri = new_uri.clone();
 9569                            let language_server = language_server.clone();
 9570                            async move |this, cx| {
 9571                                let edit = language_server
 9572                                    .request::<WillRenameFiles>(RenameFilesParams {
 9573                                        files: vec![FileRename { old_uri, new_uri }],
 9574                                    })
 9575                                    .await
 9576                                    .into_response()
 9577                                    .context("will rename files")
 9578                                    .log_err()
 9579                                    .flatten()?;
 9580
 9581                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9582                                    this.upgrade()?,
 9583                                    edit,
 9584                                    false,
 9585                                    language_server.clone(),
 9586                                    cx,
 9587                                )
 9588                                .await
 9589                                .ok()?;
 9590                                Some(transaction)
 9591                            }
 9592                        });
 9593                        tasks.push(apply_edit);
 9594                    }
 9595                }
 9596                Some(())
 9597            })
 9598            .ok()
 9599            .flatten();
 9600            let mut merged_transaction = ProjectTransaction::default();
 9601            for task in tasks {
 9602                // Await on tasks sequentially so that the order of application of edits is deterministic
 9603                // (at least with regards to the order of registration of language servers)
 9604                if let Some(transaction) = task.await {
 9605                    for (buffer, buffer_transaction) in transaction.0 {
 9606                        merged_transaction.0.insert(buffer, buffer_transaction);
 9607                    }
 9608                }
 9609            }
 9610            merged_transaction
 9611        })
 9612    }
 9613
 9614    fn lsp_notify_abs_paths_changed(
 9615        &mut self,
 9616        server_id: LanguageServerId,
 9617        changes: Vec<PathEvent>,
 9618    ) {
 9619        maybe!({
 9620            let server = self.language_server_for_id(server_id)?;
 9621            let changes = changes
 9622                .into_iter()
 9623                .filter_map(|event| {
 9624                    let typ = match event.kind? {
 9625                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9626                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9627                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9628                    };
 9629                    Some(lsp::FileEvent {
 9630                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9631                        typ,
 9632                    })
 9633                })
 9634                .collect::<Vec<_>>();
 9635            if !changes.is_empty() {
 9636                server
 9637                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9638                        lsp::DidChangeWatchedFilesParams { changes },
 9639                    )
 9640                    .ok();
 9641            }
 9642            Some(())
 9643        });
 9644    }
 9645
 9646    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9647        self.as_local()?.language_server_for_id(id)
 9648    }
 9649
 9650    fn on_lsp_progress(
 9651        &mut self,
 9652        progress_params: lsp::ProgressParams,
 9653        language_server_id: LanguageServerId,
 9654        disk_based_diagnostics_progress_token: Option<String>,
 9655        cx: &mut Context<Self>,
 9656    ) {
 9657        match progress_params.value {
 9658            lsp::ProgressParamsValue::WorkDone(progress) => {
 9659                self.handle_work_done_progress(
 9660                    progress,
 9661                    language_server_id,
 9662                    disk_based_diagnostics_progress_token,
 9663                    ProgressToken::from_lsp(progress_params.token),
 9664                    cx,
 9665                );
 9666            }
 9667            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9668                let identifier = match progress_params.token {
 9669                    lsp::NumberOrString::Number(_) => None,
 9670                    lsp::NumberOrString::String(token) => token
 9671                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9672                        .map(|(_, id)| id.to_owned()),
 9673                };
 9674                if let Some(LanguageServerState::Running {
 9675                    workspace_diagnostics_refresh_tasks,
 9676                    ..
 9677                }) = self
 9678                    .as_local_mut()
 9679                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9680                    && let Some(workspace_diagnostics) =
 9681                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9682                {
 9683                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9684                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9685                }
 9686            }
 9687        }
 9688    }
 9689
 9690    fn handle_work_done_progress(
 9691        &mut self,
 9692        progress: lsp::WorkDoneProgress,
 9693        language_server_id: LanguageServerId,
 9694        disk_based_diagnostics_progress_token: Option<String>,
 9695        token: ProgressToken,
 9696        cx: &mut Context<Self>,
 9697    ) {
 9698        let language_server_status =
 9699            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9700                status
 9701            } else {
 9702                return;
 9703            };
 9704
 9705        if !language_server_status.progress_tokens.contains(&token) {
 9706            return;
 9707        }
 9708
 9709        let is_disk_based_diagnostics_progress =
 9710            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9711                (&disk_based_diagnostics_progress_token, &token)
 9712            {
 9713                token.starts_with(disk_based_token)
 9714            } else {
 9715                false
 9716            };
 9717
 9718        match progress {
 9719            lsp::WorkDoneProgress::Begin(report) => {
 9720                if is_disk_based_diagnostics_progress {
 9721                    self.disk_based_diagnostics_started(language_server_id, cx);
 9722                }
 9723                self.on_lsp_work_start(
 9724                    language_server_id,
 9725                    token.clone(),
 9726                    LanguageServerProgress {
 9727                        title: Some(report.title),
 9728                        is_disk_based_diagnostics_progress,
 9729                        is_cancellable: report.cancellable.unwrap_or(false),
 9730                        message: report.message.clone(),
 9731                        percentage: report.percentage.map(|p| p as usize),
 9732                        last_update_at: cx.background_executor().now(),
 9733                    },
 9734                    cx,
 9735                );
 9736            }
 9737            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9738                language_server_id,
 9739                token,
 9740                LanguageServerProgress {
 9741                    title: None,
 9742                    is_disk_based_diagnostics_progress,
 9743                    is_cancellable: report.cancellable.unwrap_or(false),
 9744                    message: report.message,
 9745                    percentage: report.percentage.map(|p| p as usize),
 9746                    last_update_at: cx.background_executor().now(),
 9747                },
 9748                cx,
 9749            ),
 9750            lsp::WorkDoneProgress::End(_) => {
 9751                language_server_status.progress_tokens.remove(&token);
 9752                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9753                if is_disk_based_diagnostics_progress {
 9754                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9755                }
 9756            }
 9757        }
 9758    }
 9759
 9760    fn on_lsp_work_start(
 9761        &mut self,
 9762        language_server_id: LanguageServerId,
 9763        token: ProgressToken,
 9764        progress: LanguageServerProgress,
 9765        cx: &mut Context<Self>,
 9766    ) {
 9767        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9768            status.pending_work.insert(token.clone(), progress.clone());
 9769            cx.notify();
 9770        }
 9771        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9772            language_server_id,
 9773            name: self
 9774                .language_server_adapter_for_id(language_server_id)
 9775                .map(|adapter| adapter.name()),
 9776            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9777                token: Some(token.to_proto()),
 9778                title: progress.title,
 9779                message: progress.message,
 9780                percentage: progress.percentage.map(|p| p as u32),
 9781                is_cancellable: Some(progress.is_cancellable),
 9782            }),
 9783        })
 9784    }
 9785
 9786    fn on_lsp_work_progress(
 9787        &mut self,
 9788        language_server_id: LanguageServerId,
 9789        token: ProgressToken,
 9790        progress: LanguageServerProgress,
 9791        cx: &mut Context<Self>,
 9792    ) {
 9793        let mut did_update = false;
 9794        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9795            match status.pending_work.entry(token.clone()) {
 9796                btree_map::Entry::Vacant(entry) => {
 9797                    entry.insert(progress.clone());
 9798                    did_update = true;
 9799                }
 9800                btree_map::Entry::Occupied(mut entry) => {
 9801                    let entry = entry.get_mut();
 9802                    if (progress.last_update_at - entry.last_update_at)
 9803                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9804                    {
 9805                        entry.last_update_at = progress.last_update_at;
 9806                        if progress.message.is_some() {
 9807                            entry.message = progress.message.clone();
 9808                        }
 9809                        if progress.percentage.is_some() {
 9810                            entry.percentage = progress.percentage;
 9811                        }
 9812                        if progress.is_cancellable != entry.is_cancellable {
 9813                            entry.is_cancellable = progress.is_cancellable;
 9814                        }
 9815                        did_update = true;
 9816                    }
 9817                }
 9818            }
 9819        }
 9820
 9821        if did_update {
 9822            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9823                language_server_id,
 9824                name: self
 9825                    .language_server_adapter_for_id(language_server_id)
 9826                    .map(|adapter| adapter.name()),
 9827                message: proto::update_language_server::Variant::WorkProgress(
 9828                    proto::LspWorkProgress {
 9829                        token: Some(token.to_proto()),
 9830                        message: progress.message,
 9831                        percentage: progress.percentage.map(|p| p as u32),
 9832                        is_cancellable: Some(progress.is_cancellable),
 9833                    },
 9834                ),
 9835            })
 9836        }
 9837    }
 9838
 9839    fn on_lsp_work_end(
 9840        &mut self,
 9841        language_server_id: LanguageServerId,
 9842        token: ProgressToken,
 9843        cx: &mut Context<Self>,
 9844    ) {
 9845        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9846            if let Some(work) = status.pending_work.remove(&token)
 9847                && !work.is_disk_based_diagnostics_progress
 9848            {
 9849                cx.emit(LspStoreEvent::RefreshInlayHints {
 9850                    server_id: language_server_id,
 9851                    request_id: None,
 9852                });
 9853            }
 9854            cx.notify();
 9855        }
 9856
 9857        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9858            language_server_id,
 9859            name: self
 9860                .language_server_adapter_for_id(language_server_id)
 9861                .map(|adapter| adapter.name()),
 9862            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9863                token: Some(token.to_proto()),
 9864            }),
 9865        })
 9866    }
 9867
 9868    pub async fn handle_resolve_completion_documentation(
 9869        this: Entity<Self>,
 9870        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9871        mut cx: AsyncApp,
 9872    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9873        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9874
 9875        let completion = this
 9876            .read_with(&cx, |this, cx| {
 9877                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9878                let server = this
 9879                    .language_server_for_id(id)
 9880                    .with_context(|| format!("No language server {id}"))?;
 9881
 9882                anyhow::Ok(cx.background_spawn(async move {
 9883                    let can_resolve = server
 9884                        .capabilities()
 9885                        .completion_provider
 9886                        .as_ref()
 9887                        .and_then(|options| options.resolve_provider)
 9888                        .unwrap_or(false);
 9889                    if can_resolve {
 9890                        server
 9891                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9892                            .await
 9893                            .into_response()
 9894                            .context("resolve completion item")
 9895                    } else {
 9896                        anyhow::Ok(lsp_completion)
 9897                    }
 9898                }))
 9899            })??
 9900            .await?;
 9901
 9902        let mut documentation_is_markdown = false;
 9903        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9904        let documentation = match completion.documentation {
 9905            Some(lsp::Documentation::String(text)) => text,
 9906
 9907            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9908                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9909                value
 9910            }
 9911
 9912            _ => String::new(),
 9913        };
 9914
 9915        // If we have a new buffer_id, that means we're talking to a new client
 9916        // and want to check for new text_edits in the completion too.
 9917        let mut old_replace_start = None;
 9918        let mut old_replace_end = None;
 9919        let mut old_insert_start = None;
 9920        let mut old_insert_end = None;
 9921        let mut new_text = String::default();
 9922        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9923            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9924                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9925                anyhow::Ok(buffer.read(cx).snapshot())
 9926            })??;
 9927
 9928            if let Some(text_edit) = completion.text_edit.as_ref() {
 9929                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9930
 9931                if let Some(mut edit) = edit {
 9932                    LineEnding::normalize(&mut edit.new_text);
 9933
 9934                    new_text = edit.new_text;
 9935                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9936                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9937                    if let Some(insert_range) = edit.insert_range {
 9938                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9939                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9940                    }
 9941                }
 9942            }
 9943        }
 9944
 9945        Ok(proto::ResolveCompletionDocumentationResponse {
 9946            documentation,
 9947            documentation_is_markdown,
 9948            old_replace_start,
 9949            old_replace_end,
 9950            new_text,
 9951            lsp_completion,
 9952            old_insert_start,
 9953            old_insert_end,
 9954        })
 9955    }
 9956
 9957    async fn handle_on_type_formatting(
 9958        this: Entity<Self>,
 9959        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9960        mut cx: AsyncApp,
 9961    ) -> Result<proto::OnTypeFormattingResponse> {
 9962        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9963            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9964            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9965            let position = envelope
 9966                .payload
 9967                .position
 9968                .and_then(deserialize_anchor)
 9969                .context("invalid position")?;
 9970            anyhow::Ok(this.apply_on_type_formatting(
 9971                buffer,
 9972                position,
 9973                envelope.payload.trigger.clone(),
 9974                cx,
 9975            ))
 9976        })??;
 9977
 9978        let transaction = on_type_formatting
 9979            .await?
 9980            .as_ref()
 9981            .map(language::proto::serialize_transaction);
 9982        Ok(proto::OnTypeFormattingResponse { transaction })
 9983    }
 9984
 9985    async fn handle_refresh_inlay_hints(
 9986        lsp_store: Entity<Self>,
 9987        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9988        mut cx: AsyncApp,
 9989    ) -> Result<proto::Ack> {
 9990        lsp_store.update(&mut cx, |_, cx| {
 9991            cx.emit(LspStoreEvent::RefreshInlayHints {
 9992                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
 9993                request_id: envelope.payload.request_id.map(|id| id as usize),
 9994            });
 9995        })?;
 9996        Ok(proto::Ack {})
 9997    }
 9998
 9999    async fn handle_pull_workspace_diagnostics(
10000        lsp_store: Entity<Self>,
10001        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10002        mut cx: AsyncApp,
10003    ) -> Result<proto::Ack> {
10004        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10005        lsp_store.update(&mut cx, |lsp_store, _| {
10006            lsp_store.pull_workspace_diagnostics(server_id);
10007        })?;
10008        Ok(proto::Ack {})
10009    }
10010
10011    async fn handle_get_color_presentation(
10012        lsp_store: Entity<Self>,
10013        envelope: TypedEnvelope<proto::GetColorPresentation>,
10014        mut cx: AsyncApp,
10015    ) -> Result<proto::GetColorPresentationResponse> {
10016        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10017        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10018            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10019        })??;
10020
10021        let color = envelope
10022            .payload
10023            .color
10024            .context("invalid color resolve request")?;
10025        let start = color
10026            .lsp_range_start
10027            .context("invalid color resolve request")?;
10028        let end = color
10029            .lsp_range_end
10030            .context("invalid color resolve request")?;
10031
10032        let color = DocumentColor {
10033            lsp_range: lsp::Range {
10034                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10035                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10036            },
10037            color: lsp::Color {
10038                red: color.red,
10039                green: color.green,
10040                blue: color.blue,
10041                alpha: color.alpha,
10042            },
10043            resolved: false,
10044            color_presentations: Vec::new(),
10045        };
10046        let resolved_color = lsp_store
10047            .update(&mut cx, |lsp_store, cx| {
10048                lsp_store.resolve_color_presentation(
10049                    color,
10050                    buffer.clone(),
10051                    LanguageServerId(envelope.payload.server_id as usize),
10052                    cx,
10053                )
10054            })?
10055            .await
10056            .context("resolving color presentation")?;
10057
10058        Ok(proto::GetColorPresentationResponse {
10059            presentations: resolved_color
10060                .color_presentations
10061                .into_iter()
10062                .map(|presentation| proto::ColorPresentation {
10063                    label: presentation.label.to_string(),
10064                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10065                    additional_text_edits: presentation
10066                        .additional_text_edits
10067                        .into_iter()
10068                        .map(serialize_lsp_edit)
10069                        .collect(),
10070                })
10071                .collect(),
10072        })
10073    }
10074
10075    async fn handle_resolve_inlay_hint(
10076        lsp_store: Entity<Self>,
10077        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10078        mut cx: AsyncApp,
10079    ) -> Result<proto::ResolveInlayHintResponse> {
10080        let proto_hint = envelope
10081            .payload
10082            .hint
10083            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10084        let hint = InlayHints::proto_to_project_hint(proto_hint)
10085            .context("resolved proto inlay hint conversion")?;
10086        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10087            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10088            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10089        })??;
10090        let response_hint = lsp_store
10091            .update(&mut cx, |lsp_store, cx| {
10092                lsp_store.resolve_inlay_hint(
10093                    hint,
10094                    buffer,
10095                    LanguageServerId(envelope.payload.language_server_id as usize),
10096                    cx,
10097                )
10098            })?
10099            .await
10100            .context("inlay hints fetch")?;
10101        Ok(proto::ResolveInlayHintResponse {
10102            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10103        })
10104    }
10105
10106    async fn handle_refresh_code_lens(
10107        this: Entity<Self>,
10108        _: TypedEnvelope<proto::RefreshCodeLens>,
10109        mut cx: AsyncApp,
10110    ) -> Result<proto::Ack> {
10111        this.update(&mut cx, |_, cx| {
10112            cx.emit(LspStoreEvent::RefreshCodeLens);
10113        })?;
10114        Ok(proto::Ack {})
10115    }
10116
10117    async fn handle_open_buffer_for_symbol(
10118        this: Entity<Self>,
10119        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10120        mut cx: AsyncApp,
10121    ) -> Result<proto::OpenBufferForSymbolResponse> {
10122        let peer_id = envelope.original_sender_id().unwrap_or_default();
10123        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10124        let symbol = Self::deserialize_symbol(symbol)?;
10125        this.read_with(&cx, |this, _| {
10126            if let SymbolLocation::OutsideProject {
10127                abs_path,
10128                signature,
10129            } = &symbol.path
10130            {
10131                let new_signature = this.symbol_signature(&abs_path);
10132                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10133            }
10134            Ok(())
10135        })??;
10136        let buffer = this
10137            .update(&mut cx, |this, cx| {
10138                this.open_buffer_for_symbol(
10139                    &Symbol {
10140                        language_server_name: symbol.language_server_name,
10141                        source_worktree_id: symbol.source_worktree_id,
10142                        source_language_server_id: symbol.source_language_server_id,
10143                        path: symbol.path,
10144                        name: symbol.name,
10145                        kind: symbol.kind,
10146                        range: symbol.range,
10147                        label: CodeLabel::default(),
10148                    },
10149                    cx,
10150                )
10151            })?
10152            .await?;
10153
10154        this.update(&mut cx, |this, cx| {
10155            let is_private = buffer
10156                .read(cx)
10157                .file()
10158                .map(|f| f.is_private())
10159                .unwrap_or_default();
10160            if is_private {
10161                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10162            } else {
10163                this.buffer_store
10164                    .update(cx, |buffer_store, cx| {
10165                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10166                    })
10167                    .detach_and_log_err(cx);
10168                let buffer_id = buffer.read(cx).remote_id().to_proto();
10169                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10170            }
10171        })?
10172    }
10173
10174    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10175        let mut hasher = Sha256::new();
10176        hasher.update(abs_path.to_string_lossy().as_bytes());
10177        hasher.update(self.nonce.to_be_bytes());
10178        hasher.finalize().as_slice().try_into().unwrap()
10179    }
10180
10181    pub async fn handle_get_project_symbols(
10182        this: Entity<Self>,
10183        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10184        mut cx: AsyncApp,
10185    ) -> Result<proto::GetProjectSymbolsResponse> {
10186        let symbols = this
10187            .update(&mut cx, |this, cx| {
10188                this.symbols(&envelope.payload.query, cx)
10189            })?
10190            .await?;
10191
10192        Ok(proto::GetProjectSymbolsResponse {
10193            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10194        })
10195    }
10196
10197    pub async fn handle_restart_language_servers(
10198        this: Entity<Self>,
10199        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10200        mut cx: AsyncApp,
10201    ) -> Result<proto::Ack> {
10202        this.update(&mut cx, |lsp_store, cx| {
10203            let buffers =
10204                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10205            lsp_store.restart_language_servers_for_buffers(
10206                buffers,
10207                envelope
10208                    .payload
10209                    .only_servers
10210                    .into_iter()
10211                    .filter_map(|selector| {
10212                        Some(match selector.selector? {
10213                            proto::language_server_selector::Selector::ServerId(server_id) => {
10214                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10215                            }
10216                            proto::language_server_selector::Selector::Name(name) => {
10217                                LanguageServerSelector::Name(LanguageServerName(
10218                                    SharedString::from(name),
10219                                ))
10220                            }
10221                        })
10222                    })
10223                    .collect(),
10224                cx,
10225            );
10226        })?;
10227
10228        Ok(proto::Ack {})
10229    }
10230
10231    pub async fn handle_stop_language_servers(
10232        lsp_store: Entity<Self>,
10233        envelope: TypedEnvelope<proto::StopLanguageServers>,
10234        mut cx: AsyncApp,
10235    ) -> Result<proto::Ack> {
10236        lsp_store.update(&mut cx, |lsp_store, cx| {
10237            if envelope.payload.all
10238                && envelope.payload.also_servers.is_empty()
10239                && envelope.payload.buffer_ids.is_empty()
10240            {
10241                lsp_store.stop_all_language_servers(cx);
10242            } else {
10243                let buffers =
10244                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10245                lsp_store
10246                    .stop_language_servers_for_buffers(
10247                        buffers,
10248                        envelope
10249                            .payload
10250                            .also_servers
10251                            .into_iter()
10252                            .filter_map(|selector| {
10253                                Some(match selector.selector? {
10254                                    proto::language_server_selector::Selector::ServerId(
10255                                        server_id,
10256                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10257                                        server_id,
10258                                    )),
10259                                    proto::language_server_selector::Selector::Name(name) => {
10260                                        LanguageServerSelector::Name(LanguageServerName(
10261                                            SharedString::from(name),
10262                                        ))
10263                                    }
10264                                })
10265                            })
10266                            .collect(),
10267                        cx,
10268                    )
10269                    .detach_and_log_err(cx);
10270            }
10271        })?;
10272
10273        Ok(proto::Ack {})
10274    }
10275
10276    pub async fn handle_cancel_language_server_work(
10277        lsp_store: Entity<Self>,
10278        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10279        mut cx: AsyncApp,
10280    ) -> Result<proto::Ack> {
10281        lsp_store.update(&mut cx, |lsp_store, cx| {
10282            if let Some(work) = envelope.payload.work {
10283                match work {
10284                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10285                        let buffers =
10286                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10287                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10288                    }
10289                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10290                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10291                        let token = work
10292                            .token
10293                            .map(|token| {
10294                                ProgressToken::from_proto(token)
10295                                    .context("invalid work progress token")
10296                            })
10297                            .transpose()?;
10298                        lsp_store.cancel_language_server_work(server_id, token, cx);
10299                    }
10300                }
10301            }
10302            anyhow::Ok(())
10303        })??;
10304
10305        Ok(proto::Ack {})
10306    }
10307
10308    fn buffer_ids_to_buffers(
10309        &mut self,
10310        buffer_ids: impl Iterator<Item = u64>,
10311        cx: &mut Context<Self>,
10312    ) -> Vec<Entity<Buffer>> {
10313        buffer_ids
10314            .into_iter()
10315            .flat_map(|buffer_id| {
10316                self.buffer_store
10317                    .read(cx)
10318                    .get(BufferId::new(buffer_id).log_err()?)
10319            })
10320            .collect::<Vec<_>>()
10321    }
10322
10323    async fn handle_apply_additional_edits_for_completion(
10324        this: Entity<Self>,
10325        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10326        mut cx: AsyncApp,
10327    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10328        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10329            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10330            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10331            let completion = Self::deserialize_completion(
10332                envelope.payload.completion.context("invalid completion")?,
10333            )?;
10334            anyhow::Ok((buffer, completion))
10335        })??;
10336
10337        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10338            this.apply_additional_edits_for_completion(
10339                buffer,
10340                Rc::new(RefCell::new(Box::new([Completion {
10341                    replace_range: completion.replace_range,
10342                    new_text: completion.new_text,
10343                    source: completion.source,
10344                    documentation: None,
10345                    label: CodeLabel::default(),
10346                    match_start: None,
10347                    snippet_deduplication_key: None,
10348                    insert_text_mode: None,
10349                    icon_path: None,
10350                    confirm: None,
10351                }]))),
10352                0,
10353                false,
10354                cx,
10355            )
10356        })?;
10357
10358        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10359            transaction: apply_additional_edits
10360                .await?
10361                .as_ref()
10362                .map(language::proto::serialize_transaction),
10363        })
10364    }
10365
10366    pub fn last_formatting_failure(&self) -> Option<&str> {
10367        self.last_formatting_failure.as_deref()
10368    }
10369
10370    pub fn reset_last_formatting_failure(&mut self) {
10371        self.last_formatting_failure = None;
10372    }
10373
10374    pub fn environment_for_buffer(
10375        &self,
10376        buffer: &Entity<Buffer>,
10377        cx: &mut Context<Self>,
10378    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10379        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10380            environment.update(cx, |env, cx| {
10381                env.buffer_environment(buffer, &self.worktree_store, cx)
10382            })
10383        } else {
10384            Task::ready(None).shared()
10385        }
10386    }
10387
10388    pub fn format(
10389        &mut self,
10390        buffers: HashSet<Entity<Buffer>>,
10391        target: LspFormatTarget,
10392        push_to_history: bool,
10393        trigger: FormatTrigger,
10394        cx: &mut Context<Self>,
10395    ) -> Task<anyhow::Result<ProjectTransaction>> {
10396        let logger = zlog::scoped!("format");
10397        if self.as_local().is_some() {
10398            zlog::trace!(logger => "Formatting locally");
10399            let logger = zlog::scoped!(logger => "local");
10400            let buffers = buffers
10401                .into_iter()
10402                .map(|buffer_handle| {
10403                    let buffer = buffer_handle.read(cx);
10404                    let buffer_abs_path = File::from_dyn(buffer.file())
10405                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10406
10407                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10408                })
10409                .collect::<Vec<_>>();
10410
10411            cx.spawn(async move |lsp_store, cx| {
10412                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10413
10414                for (handle, abs_path, id) in buffers {
10415                    let env = lsp_store
10416                        .update(cx, |lsp_store, cx| {
10417                            lsp_store.environment_for_buffer(&handle, cx)
10418                        })?
10419                        .await;
10420
10421                    let ranges = match &target {
10422                        LspFormatTarget::Buffers => None,
10423                        LspFormatTarget::Ranges(ranges) => {
10424                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10425                        }
10426                    };
10427
10428                    formattable_buffers.push(FormattableBuffer {
10429                        handle,
10430                        abs_path,
10431                        env,
10432                        ranges,
10433                    });
10434                }
10435                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10436
10437                let format_timer = zlog::time!(logger => "Formatting buffers");
10438                let result = LocalLspStore::format_locally(
10439                    lsp_store.clone(),
10440                    formattable_buffers,
10441                    push_to_history,
10442                    trigger,
10443                    logger,
10444                    cx,
10445                )
10446                .await;
10447                format_timer.end();
10448
10449                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10450
10451                lsp_store.update(cx, |lsp_store, _| {
10452                    lsp_store.update_last_formatting_failure(&result);
10453                })?;
10454
10455                result
10456            })
10457        } else if let Some((client, project_id)) = self.upstream_client() {
10458            zlog::trace!(logger => "Formatting remotely");
10459            let logger = zlog::scoped!(logger => "remote");
10460            // Don't support formatting ranges via remote
10461            match target {
10462                LspFormatTarget::Buffers => {}
10463                LspFormatTarget::Ranges(_) => {
10464                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10465                    return Task::ready(Ok(ProjectTransaction::default()));
10466                }
10467            }
10468
10469            let buffer_store = self.buffer_store();
10470            cx.spawn(async move |lsp_store, cx| {
10471                zlog::trace!(logger => "Sending remote format request");
10472                let request_timer = zlog::time!(logger => "remote format request");
10473                let result = client
10474                    .request(proto::FormatBuffers {
10475                        project_id,
10476                        trigger: trigger as i32,
10477                        buffer_ids: buffers
10478                            .iter()
10479                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10480                            .collect::<Result<_>>()?,
10481                    })
10482                    .await
10483                    .and_then(|result| result.transaction.context("missing transaction"));
10484                request_timer.end();
10485
10486                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10487
10488                lsp_store.update(cx, |lsp_store, _| {
10489                    lsp_store.update_last_formatting_failure(&result);
10490                })?;
10491
10492                let transaction_response = result?;
10493                let _timer = zlog::time!(logger => "deserializing project transaction");
10494                buffer_store
10495                    .update(cx, |buffer_store, cx| {
10496                        buffer_store.deserialize_project_transaction(
10497                            transaction_response,
10498                            push_to_history,
10499                            cx,
10500                        )
10501                    })?
10502                    .await
10503            })
10504        } else {
10505            zlog::trace!(logger => "Not formatting");
10506            Task::ready(Ok(ProjectTransaction::default()))
10507        }
10508    }
10509
10510    async fn handle_format_buffers(
10511        this: Entity<Self>,
10512        envelope: TypedEnvelope<proto::FormatBuffers>,
10513        mut cx: AsyncApp,
10514    ) -> Result<proto::FormatBuffersResponse> {
10515        let sender_id = envelope.original_sender_id().unwrap_or_default();
10516        let format = this.update(&mut cx, |this, cx| {
10517            let mut buffers = HashSet::default();
10518            for buffer_id in &envelope.payload.buffer_ids {
10519                let buffer_id = BufferId::new(*buffer_id)?;
10520                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10521            }
10522            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10523            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10524        })??;
10525
10526        let project_transaction = format.await?;
10527        let project_transaction = this.update(&mut cx, |this, cx| {
10528            this.buffer_store.update(cx, |buffer_store, cx| {
10529                buffer_store.serialize_project_transaction_for_peer(
10530                    project_transaction,
10531                    sender_id,
10532                    cx,
10533                )
10534            })
10535        })?;
10536        Ok(proto::FormatBuffersResponse {
10537            transaction: Some(project_transaction),
10538        })
10539    }
10540
10541    async fn handle_apply_code_action_kind(
10542        this: Entity<Self>,
10543        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10544        mut cx: AsyncApp,
10545    ) -> Result<proto::ApplyCodeActionKindResponse> {
10546        let sender_id = envelope.original_sender_id().unwrap_or_default();
10547        let format = this.update(&mut cx, |this, cx| {
10548            let mut buffers = HashSet::default();
10549            for buffer_id in &envelope.payload.buffer_ids {
10550                let buffer_id = BufferId::new(*buffer_id)?;
10551                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10552            }
10553            let kind = match envelope.payload.kind.as_str() {
10554                "" => CodeActionKind::EMPTY,
10555                "quickfix" => CodeActionKind::QUICKFIX,
10556                "refactor" => CodeActionKind::REFACTOR,
10557                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10558                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10559                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10560                "source" => CodeActionKind::SOURCE,
10561                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10562                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10563                _ => anyhow::bail!(
10564                    "Invalid code action kind {}",
10565                    envelope.payload.kind.as_str()
10566                ),
10567            };
10568            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10569        })??;
10570
10571        let project_transaction = format.await?;
10572        let project_transaction = this.update(&mut cx, |this, cx| {
10573            this.buffer_store.update(cx, |buffer_store, cx| {
10574                buffer_store.serialize_project_transaction_for_peer(
10575                    project_transaction,
10576                    sender_id,
10577                    cx,
10578                )
10579            })
10580        })?;
10581        Ok(proto::ApplyCodeActionKindResponse {
10582            transaction: Some(project_transaction),
10583        })
10584    }
10585
10586    async fn shutdown_language_server(
10587        server_state: Option<LanguageServerState>,
10588        name: LanguageServerName,
10589        cx: &mut AsyncApp,
10590    ) {
10591        let server = match server_state {
10592            Some(LanguageServerState::Starting { startup, .. }) => {
10593                let mut timer = cx
10594                    .background_executor()
10595                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10596                    .fuse();
10597
10598                select! {
10599                    server = startup.fuse() => server,
10600                    () = timer => {
10601                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10602                        None
10603                    },
10604                }
10605            }
10606
10607            Some(LanguageServerState::Running { server, .. }) => Some(server),
10608
10609            None => None,
10610        };
10611
10612        if let Some(server) = server
10613            && let Some(shutdown) = server.shutdown()
10614        {
10615            shutdown.await;
10616        }
10617    }
10618
10619    // Returns a list of all of the worktrees which no longer have a language server and the root path
10620    // for the stopped server
10621    fn stop_local_language_server(
10622        &mut self,
10623        server_id: LanguageServerId,
10624        cx: &mut Context<Self>,
10625    ) -> Task<()> {
10626        let local = match &mut self.mode {
10627            LspStoreMode::Local(local) => local,
10628            _ => {
10629                return Task::ready(());
10630            }
10631        };
10632
10633        // Remove this server ID from all entries in the given worktree.
10634        local
10635            .language_server_ids
10636            .retain(|_, state| state.id != server_id);
10637        self.buffer_store.update(cx, |buffer_store, cx| {
10638            for buffer in buffer_store.buffers() {
10639                buffer.update(cx, |buffer, cx| {
10640                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10641                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10642                });
10643            }
10644        });
10645
10646        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10647            summaries.retain(|path, summaries_by_server_id| {
10648                if summaries_by_server_id.remove(&server_id).is_some() {
10649                    if let Some((client, project_id)) = self.downstream_client.clone() {
10650                        client
10651                            .send(proto::UpdateDiagnosticSummary {
10652                                project_id,
10653                                worktree_id: worktree_id.to_proto(),
10654                                summary: Some(proto::DiagnosticSummary {
10655                                    path: path.as_ref().to_proto(),
10656                                    language_server_id: server_id.0 as u64,
10657                                    error_count: 0,
10658                                    warning_count: 0,
10659                                }),
10660                                more_summaries: Vec::new(),
10661                            })
10662                            .log_err();
10663                    }
10664                    !summaries_by_server_id.is_empty()
10665                } else {
10666                    true
10667                }
10668            });
10669        }
10670
10671        let local = self.as_local_mut().unwrap();
10672        for diagnostics in local.diagnostics.values_mut() {
10673            diagnostics.retain(|_, diagnostics_by_server_id| {
10674                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10675                    diagnostics_by_server_id.remove(ix);
10676                    !diagnostics_by_server_id.is_empty()
10677                } else {
10678                    true
10679                }
10680            });
10681        }
10682        local.language_server_watched_paths.remove(&server_id);
10683
10684        let server_state = local.language_servers.remove(&server_id);
10685        self.cleanup_lsp_data(server_id);
10686        let name = self
10687            .language_server_statuses
10688            .remove(&server_id)
10689            .map(|status| status.name)
10690            .or_else(|| {
10691                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10692                    Some(adapter.name())
10693                } else {
10694                    None
10695                }
10696            });
10697
10698        if let Some(name) = name {
10699            log::info!("stopping language server {name}");
10700            self.languages
10701                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10702            cx.notify();
10703
10704            return cx.spawn(async move |lsp_store, cx| {
10705                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10706                lsp_store
10707                    .update(cx, |lsp_store, cx| {
10708                        lsp_store
10709                            .languages
10710                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10711                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10712                        cx.notify();
10713                    })
10714                    .ok();
10715            });
10716        }
10717
10718        if server_state.is_some() {
10719            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10720        }
10721        Task::ready(())
10722    }
10723
10724    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10725        if let Some((client, project_id)) = self.upstream_client() {
10726            let request = client.request(proto::StopLanguageServers {
10727                project_id,
10728                buffer_ids: Vec::new(),
10729                also_servers: Vec::new(),
10730                all: true,
10731            });
10732            cx.background_spawn(request).detach_and_log_err(cx);
10733        } else {
10734            let Some(local) = self.as_local_mut() else {
10735                return;
10736            };
10737            let language_servers_to_stop = local
10738                .language_server_ids
10739                .values()
10740                .map(|state| state.id)
10741                .collect();
10742            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10743            let tasks = language_servers_to_stop
10744                .into_iter()
10745                .map(|server| self.stop_local_language_server(server, cx))
10746                .collect::<Vec<_>>();
10747            cx.background_spawn(async move {
10748                futures::future::join_all(tasks).await;
10749            })
10750            .detach();
10751        }
10752    }
10753
10754    pub fn restart_language_servers_for_buffers(
10755        &mut self,
10756        buffers: Vec<Entity<Buffer>>,
10757        only_restart_servers: HashSet<LanguageServerSelector>,
10758        cx: &mut Context<Self>,
10759    ) {
10760        if let Some((client, project_id)) = self.upstream_client() {
10761            let request = client.request(proto::RestartLanguageServers {
10762                project_id,
10763                buffer_ids: buffers
10764                    .into_iter()
10765                    .map(|b| b.read(cx).remote_id().to_proto())
10766                    .collect(),
10767                only_servers: only_restart_servers
10768                    .into_iter()
10769                    .map(|selector| {
10770                        let selector = match selector {
10771                            LanguageServerSelector::Id(language_server_id) => {
10772                                proto::language_server_selector::Selector::ServerId(
10773                                    language_server_id.to_proto(),
10774                                )
10775                            }
10776                            LanguageServerSelector::Name(language_server_name) => {
10777                                proto::language_server_selector::Selector::Name(
10778                                    language_server_name.to_string(),
10779                                )
10780                            }
10781                        };
10782                        proto::LanguageServerSelector {
10783                            selector: Some(selector),
10784                        }
10785                    })
10786                    .collect(),
10787                all: false,
10788            });
10789            cx.background_spawn(request).detach_and_log_err(cx);
10790        } else {
10791            let stop_task = if only_restart_servers.is_empty() {
10792                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10793            } else {
10794                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10795            };
10796            cx.spawn(async move |lsp_store, cx| {
10797                stop_task.await;
10798                lsp_store
10799                    .update(cx, |lsp_store, cx| {
10800                        for buffer in buffers {
10801                            lsp_store.register_buffer_with_language_servers(
10802                                &buffer,
10803                                only_restart_servers.clone(),
10804                                true,
10805                                cx,
10806                            );
10807                        }
10808                    })
10809                    .ok()
10810            })
10811            .detach();
10812        }
10813    }
10814
10815    pub fn stop_language_servers_for_buffers(
10816        &mut self,
10817        buffers: Vec<Entity<Buffer>>,
10818        also_stop_servers: HashSet<LanguageServerSelector>,
10819        cx: &mut Context<Self>,
10820    ) -> Task<Result<()>> {
10821        if let Some((client, project_id)) = self.upstream_client() {
10822            let request = client.request(proto::StopLanguageServers {
10823                project_id,
10824                buffer_ids: buffers
10825                    .into_iter()
10826                    .map(|b| b.read(cx).remote_id().to_proto())
10827                    .collect(),
10828                also_servers: also_stop_servers
10829                    .into_iter()
10830                    .map(|selector| {
10831                        let selector = match selector {
10832                            LanguageServerSelector::Id(language_server_id) => {
10833                                proto::language_server_selector::Selector::ServerId(
10834                                    language_server_id.to_proto(),
10835                                )
10836                            }
10837                            LanguageServerSelector::Name(language_server_name) => {
10838                                proto::language_server_selector::Selector::Name(
10839                                    language_server_name.to_string(),
10840                                )
10841                            }
10842                        };
10843                        proto::LanguageServerSelector {
10844                            selector: Some(selector),
10845                        }
10846                    })
10847                    .collect(),
10848                all: false,
10849            });
10850            cx.background_spawn(async move {
10851                let _ = request.await?;
10852                Ok(())
10853            })
10854        } else {
10855            let task =
10856                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10857            cx.background_spawn(async move {
10858                task.await;
10859                Ok(())
10860            })
10861        }
10862    }
10863
10864    fn stop_local_language_servers_for_buffers(
10865        &mut self,
10866        buffers: &[Entity<Buffer>],
10867        also_stop_servers: HashSet<LanguageServerSelector>,
10868        cx: &mut Context<Self>,
10869    ) -> Task<()> {
10870        let Some(local) = self.as_local_mut() else {
10871            return Task::ready(());
10872        };
10873        let mut language_server_names_to_stop = BTreeSet::default();
10874        let mut language_servers_to_stop = also_stop_servers
10875            .into_iter()
10876            .flat_map(|selector| match selector {
10877                LanguageServerSelector::Id(id) => Some(id),
10878                LanguageServerSelector::Name(name) => {
10879                    language_server_names_to_stop.insert(name);
10880                    None
10881                }
10882            })
10883            .collect::<BTreeSet<_>>();
10884
10885        let mut covered_worktrees = HashSet::default();
10886        for buffer in buffers {
10887            buffer.update(cx, |buffer, cx| {
10888                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10889                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10890                    && covered_worktrees.insert(worktree_id)
10891                {
10892                    language_server_names_to_stop.retain(|name| {
10893                        let old_ids_count = language_servers_to_stop.len();
10894                        let all_language_servers_with_this_name = local
10895                            .language_server_ids
10896                            .iter()
10897                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10898                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10899                        old_ids_count == language_servers_to_stop.len()
10900                    });
10901                }
10902            });
10903        }
10904        for name in language_server_names_to_stop {
10905            language_servers_to_stop.extend(
10906                local
10907                    .language_server_ids
10908                    .iter()
10909                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10910            );
10911        }
10912
10913        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10914        let tasks = language_servers_to_stop
10915            .into_iter()
10916            .map(|server| self.stop_local_language_server(server, cx))
10917            .collect::<Vec<_>>();
10918
10919        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10920    }
10921
10922    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10923        let (worktree, relative_path) =
10924            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10925
10926        let project_path = ProjectPath {
10927            worktree_id: worktree.read(cx).id(),
10928            path: relative_path,
10929        };
10930
10931        Some(
10932            self.buffer_store()
10933                .read(cx)
10934                .get_by_path(&project_path)?
10935                .read(cx),
10936        )
10937    }
10938
10939    #[cfg(any(test, feature = "test-support"))]
10940    pub fn update_diagnostics(
10941        &mut self,
10942        server_id: LanguageServerId,
10943        diagnostics: lsp::PublishDiagnosticsParams,
10944        result_id: Option<String>,
10945        source_kind: DiagnosticSourceKind,
10946        disk_based_sources: &[String],
10947        cx: &mut Context<Self>,
10948    ) -> Result<()> {
10949        self.merge_lsp_diagnostics(
10950            source_kind,
10951            vec![DocumentDiagnosticsUpdate {
10952                diagnostics,
10953                result_id,
10954                server_id,
10955                disk_based_sources: Cow::Borrowed(disk_based_sources),
10956            }],
10957            |_, _, _| false,
10958            cx,
10959        )
10960    }
10961
10962    pub fn merge_lsp_diagnostics(
10963        &mut self,
10964        source_kind: DiagnosticSourceKind,
10965        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10966        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10967        cx: &mut Context<Self>,
10968    ) -> Result<()> {
10969        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10970        let updates = lsp_diagnostics
10971            .into_iter()
10972            .filter_map(|update| {
10973                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10974                Some(DocumentDiagnosticsUpdate {
10975                    diagnostics: self.lsp_to_document_diagnostics(
10976                        abs_path,
10977                        source_kind,
10978                        update.server_id,
10979                        update.diagnostics,
10980                        &update.disk_based_sources,
10981                    ),
10982                    result_id: update.result_id,
10983                    server_id: update.server_id,
10984                    disk_based_sources: update.disk_based_sources,
10985                })
10986            })
10987            .collect();
10988        self.merge_diagnostic_entries(updates, merge, cx)?;
10989        Ok(())
10990    }
10991
10992    fn lsp_to_document_diagnostics(
10993        &mut self,
10994        document_abs_path: PathBuf,
10995        source_kind: DiagnosticSourceKind,
10996        server_id: LanguageServerId,
10997        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10998        disk_based_sources: &[String],
10999    ) -> DocumentDiagnostics {
11000        let mut diagnostics = Vec::default();
11001        let mut primary_diagnostic_group_ids = HashMap::default();
11002        let mut sources_by_group_id = HashMap::default();
11003        let mut supporting_diagnostics = HashMap::default();
11004
11005        let adapter = self.language_server_adapter_for_id(server_id);
11006
11007        // Ensure that primary diagnostics are always the most severe
11008        lsp_diagnostics
11009            .diagnostics
11010            .sort_by_key(|item| item.severity);
11011
11012        for diagnostic in &lsp_diagnostics.diagnostics {
11013            let source = diagnostic.source.as_ref();
11014            let range = range_from_lsp(diagnostic.range);
11015            let is_supporting = diagnostic
11016                .related_information
11017                .as_ref()
11018                .is_some_and(|infos| {
11019                    infos.iter().any(|info| {
11020                        primary_diagnostic_group_ids.contains_key(&(
11021                            source,
11022                            diagnostic.code.clone(),
11023                            range_from_lsp(info.location.range),
11024                        ))
11025                    })
11026                });
11027
11028            let is_unnecessary = diagnostic
11029                .tags
11030                .as_ref()
11031                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11032
11033            let underline = self
11034                .language_server_adapter_for_id(server_id)
11035                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11036
11037            if is_supporting {
11038                supporting_diagnostics.insert(
11039                    (source, diagnostic.code.clone(), range),
11040                    (diagnostic.severity, is_unnecessary),
11041                );
11042            } else {
11043                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11044                let is_disk_based =
11045                    source.is_some_and(|source| disk_based_sources.contains(source));
11046
11047                sources_by_group_id.insert(group_id, source);
11048                primary_diagnostic_group_ids
11049                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11050
11051                diagnostics.push(DiagnosticEntry {
11052                    range,
11053                    diagnostic: Diagnostic {
11054                        source: diagnostic.source.clone(),
11055                        source_kind,
11056                        code: diagnostic.code.clone(),
11057                        code_description: diagnostic
11058                            .code_description
11059                            .as_ref()
11060                            .and_then(|d| d.href.clone()),
11061                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11062                        markdown: adapter.as_ref().and_then(|adapter| {
11063                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11064                        }),
11065                        message: diagnostic.message.trim().to_string(),
11066                        group_id,
11067                        is_primary: true,
11068                        is_disk_based,
11069                        is_unnecessary,
11070                        underline,
11071                        data: diagnostic.data.clone(),
11072                    },
11073                });
11074                if let Some(infos) = &diagnostic.related_information {
11075                    for info in infos {
11076                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11077                            let range = range_from_lsp(info.location.range);
11078                            diagnostics.push(DiagnosticEntry {
11079                                range,
11080                                diagnostic: Diagnostic {
11081                                    source: diagnostic.source.clone(),
11082                                    source_kind,
11083                                    code: diagnostic.code.clone(),
11084                                    code_description: diagnostic
11085                                        .code_description
11086                                        .as_ref()
11087                                        .and_then(|d| d.href.clone()),
11088                                    severity: DiagnosticSeverity::INFORMATION,
11089                                    markdown: adapter.as_ref().and_then(|adapter| {
11090                                        adapter.diagnostic_message_to_markdown(&info.message)
11091                                    }),
11092                                    message: info.message.trim().to_string(),
11093                                    group_id,
11094                                    is_primary: false,
11095                                    is_disk_based,
11096                                    is_unnecessary: false,
11097                                    underline,
11098                                    data: diagnostic.data.clone(),
11099                                },
11100                            });
11101                        }
11102                    }
11103                }
11104            }
11105        }
11106
11107        for entry in &mut diagnostics {
11108            let diagnostic = &mut entry.diagnostic;
11109            if !diagnostic.is_primary {
11110                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11111                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11112                    source,
11113                    diagnostic.code.clone(),
11114                    entry.range.clone(),
11115                )) {
11116                    if let Some(severity) = severity {
11117                        diagnostic.severity = severity;
11118                    }
11119                    diagnostic.is_unnecessary = is_unnecessary;
11120                }
11121            }
11122        }
11123
11124        DocumentDiagnostics {
11125            diagnostics,
11126            document_abs_path,
11127            version: lsp_diagnostics.version,
11128        }
11129    }
11130
11131    fn insert_newly_running_language_server(
11132        &mut self,
11133        adapter: Arc<CachedLspAdapter>,
11134        language_server: Arc<LanguageServer>,
11135        server_id: LanguageServerId,
11136        key: LanguageServerSeed,
11137        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11138        cx: &mut Context<Self>,
11139    ) {
11140        let Some(local) = self.as_local_mut() else {
11141            return;
11142        };
11143        // If the language server for this key doesn't match the server id, don't store the
11144        // server. Which will cause it to be dropped, killing the process
11145        if local
11146            .language_server_ids
11147            .get(&key)
11148            .map(|state| state.id != server_id)
11149            .unwrap_or(false)
11150        {
11151            return;
11152        }
11153
11154        // Update language_servers collection with Running variant of LanguageServerState
11155        // indicating that the server is up and running and ready
11156        let workspace_folders = workspace_folders.lock().clone();
11157        language_server.set_workspace_folders(workspace_folders);
11158
11159        let workspace_diagnostics_refresh_tasks = language_server
11160            .capabilities()
11161            .diagnostic_provider
11162            .and_then(|provider| {
11163                local
11164                    .language_server_dynamic_registrations
11165                    .entry(server_id)
11166                    .or_default()
11167                    .diagnostics
11168                    .entry(None)
11169                    .or_insert(provider.clone());
11170                let workspace_refresher =
11171                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11172
11173                Some((None, workspace_refresher))
11174            })
11175            .into_iter()
11176            .collect();
11177        local.language_servers.insert(
11178            server_id,
11179            LanguageServerState::Running {
11180                workspace_diagnostics_refresh_tasks,
11181                adapter: adapter.clone(),
11182                server: language_server.clone(),
11183                simulate_disk_based_diagnostics_completion: None,
11184            },
11185        );
11186        local
11187            .languages
11188            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11189        if let Some(file_ops_caps) = language_server
11190            .capabilities()
11191            .workspace
11192            .as_ref()
11193            .and_then(|ws| ws.file_operations.as_ref())
11194        {
11195            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11196            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11197            if did_rename_caps.or(will_rename_caps).is_some() {
11198                let watcher = RenamePathsWatchedForServer::default()
11199                    .with_did_rename_patterns(did_rename_caps)
11200                    .with_will_rename_patterns(will_rename_caps);
11201                local
11202                    .language_server_paths_watched_for_rename
11203                    .insert(server_id, watcher);
11204            }
11205        }
11206
11207        self.language_server_statuses.insert(
11208            server_id,
11209            LanguageServerStatus {
11210                name: language_server.name(),
11211                pending_work: Default::default(),
11212                has_pending_diagnostic_updates: false,
11213                progress_tokens: Default::default(),
11214                worktree: Some(key.worktree_id),
11215                binary: Some(language_server.binary().clone()),
11216                configuration: Some(language_server.configuration().clone()),
11217                workspace_folders: language_server.workspace_folders(),
11218            },
11219        );
11220
11221        cx.emit(LspStoreEvent::LanguageServerAdded(
11222            server_id,
11223            language_server.name(),
11224            Some(key.worktree_id),
11225        ));
11226
11227        let server_capabilities = language_server.capabilities();
11228        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11229            downstream_client
11230                .send(proto::StartLanguageServer {
11231                    project_id: *project_id,
11232                    server: Some(proto::LanguageServer {
11233                        id: server_id.to_proto(),
11234                        name: language_server.name().to_string(),
11235                        worktree_id: Some(key.worktree_id.to_proto()),
11236                    }),
11237                    capabilities: serde_json::to_string(&server_capabilities)
11238                        .expect("serializing server LSP capabilities"),
11239                })
11240                .log_err();
11241        }
11242        self.lsp_server_capabilities
11243            .insert(server_id, server_capabilities);
11244
11245        // Tell the language server about every open buffer in the worktree that matches the language.
11246        // Also check for buffers in worktrees that reused this server
11247        let mut worktrees_using_server = vec![key.worktree_id];
11248        if let Some(local) = self.as_local() {
11249            // Find all worktrees that have this server in their language server tree
11250            for (worktree_id, servers) in &local.lsp_tree.instances {
11251                if *worktree_id != key.worktree_id {
11252                    for server_map in servers.roots.values() {
11253                        if server_map
11254                            .values()
11255                            .any(|(node, _)| node.id() == Some(server_id))
11256                        {
11257                            worktrees_using_server.push(*worktree_id);
11258                        }
11259                    }
11260                }
11261            }
11262        }
11263
11264        let mut buffer_paths_registered = Vec::new();
11265        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11266            let mut lsp_adapters = HashMap::default();
11267            for buffer_handle in buffer_store.buffers() {
11268                let buffer = buffer_handle.read(cx);
11269                let file = match File::from_dyn(buffer.file()) {
11270                    Some(file) => file,
11271                    None => continue,
11272                };
11273                let language = match buffer.language() {
11274                    Some(language) => language,
11275                    None => continue,
11276                };
11277
11278                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11279                    || !lsp_adapters
11280                        .entry(language.name())
11281                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11282                        .iter()
11283                        .any(|a| a.name == key.name)
11284                {
11285                    continue;
11286                }
11287                // didOpen
11288                let file = match file.as_local() {
11289                    Some(file) => file,
11290                    None => continue,
11291                };
11292
11293                let local = self.as_local_mut().unwrap();
11294
11295                let buffer_id = buffer.remote_id();
11296                if local.registered_buffers.contains_key(&buffer_id) {
11297                    let versions = local
11298                        .buffer_snapshots
11299                        .entry(buffer_id)
11300                        .or_default()
11301                        .entry(server_id)
11302                        .and_modify(|_| {
11303                            assert!(
11304                            false,
11305                            "There should not be an existing snapshot for a newly inserted buffer"
11306                        )
11307                        })
11308                        .or_insert_with(|| {
11309                            vec![LspBufferSnapshot {
11310                                version: 0,
11311                                snapshot: buffer.text_snapshot(),
11312                            }]
11313                        });
11314
11315                    let snapshot = versions.last().unwrap();
11316                    let version = snapshot.version;
11317                    let initial_snapshot = &snapshot.snapshot;
11318                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11319                    language_server.register_buffer(
11320                        uri,
11321                        adapter.language_id(&language.name()),
11322                        version,
11323                        initial_snapshot.text(),
11324                    );
11325                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11326                    local
11327                        .buffers_opened_in_servers
11328                        .entry(buffer_id)
11329                        .or_default()
11330                        .insert(server_id);
11331                }
11332                buffer_handle.update(cx, |buffer, cx| {
11333                    buffer.set_completion_triggers(
11334                        server_id,
11335                        language_server
11336                            .capabilities()
11337                            .completion_provider
11338                            .as_ref()
11339                            .and_then(|provider| {
11340                                provider
11341                                    .trigger_characters
11342                                    .as_ref()
11343                                    .map(|characters| characters.iter().cloned().collect())
11344                            })
11345                            .unwrap_or_default(),
11346                        cx,
11347                    )
11348                });
11349            }
11350        });
11351
11352        for (buffer_id, abs_path) in buffer_paths_registered {
11353            cx.emit(LspStoreEvent::LanguageServerUpdate {
11354                language_server_id: server_id,
11355                name: Some(adapter.name()),
11356                message: proto::update_language_server::Variant::RegisteredForBuffer(
11357                    proto::RegisteredForBuffer {
11358                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11359                        buffer_id: buffer_id.to_proto(),
11360                    },
11361                ),
11362            });
11363        }
11364
11365        cx.notify();
11366    }
11367
11368    pub fn language_servers_running_disk_based_diagnostics(
11369        &self,
11370    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11371        self.language_server_statuses
11372            .iter()
11373            .filter_map(|(id, status)| {
11374                if status.has_pending_diagnostic_updates {
11375                    Some(*id)
11376                } else {
11377                    None
11378                }
11379            })
11380    }
11381
11382    pub(crate) fn cancel_language_server_work_for_buffers(
11383        &mut self,
11384        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11385        cx: &mut Context<Self>,
11386    ) {
11387        if let Some((client, project_id)) = self.upstream_client() {
11388            let request = client.request(proto::CancelLanguageServerWork {
11389                project_id,
11390                work: Some(proto::cancel_language_server_work::Work::Buffers(
11391                    proto::cancel_language_server_work::Buffers {
11392                        buffer_ids: buffers
11393                            .into_iter()
11394                            .map(|b| b.read(cx).remote_id().to_proto())
11395                            .collect(),
11396                    },
11397                )),
11398            });
11399            cx.background_spawn(request).detach_and_log_err(cx);
11400        } else if let Some(local) = self.as_local() {
11401            let servers = buffers
11402                .into_iter()
11403                .flat_map(|buffer| {
11404                    buffer.update(cx, |buffer, cx| {
11405                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11406                    })
11407                })
11408                .collect::<HashSet<_>>();
11409            for server_id in servers {
11410                self.cancel_language_server_work(server_id, None, cx);
11411            }
11412        }
11413    }
11414
11415    pub(crate) fn cancel_language_server_work(
11416        &mut self,
11417        server_id: LanguageServerId,
11418        token_to_cancel: Option<ProgressToken>,
11419        cx: &mut Context<Self>,
11420    ) {
11421        if let Some(local) = self.as_local() {
11422            let status = self.language_server_statuses.get(&server_id);
11423            let server = local.language_servers.get(&server_id);
11424            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11425            {
11426                for (token, progress) in &status.pending_work {
11427                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11428                        && token != token_to_cancel
11429                    {
11430                        continue;
11431                    }
11432                    if progress.is_cancellable {
11433                        server
11434                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11435                                WorkDoneProgressCancelParams {
11436                                    token: token.to_lsp(),
11437                                },
11438                            )
11439                            .ok();
11440                    }
11441                }
11442            }
11443        } else if let Some((client, project_id)) = self.upstream_client() {
11444            let request = client.request(proto::CancelLanguageServerWork {
11445                project_id,
11446                work: Some(
11447                    proto::cancel_language_server_work::Work::LanguageServerWork(
11448                        proto::cancel_language_server_work::LanguageServerWork {
11449                            language_server_id: server_id.to_proto(),
11450                            token: token_to_cancel.map(|token| token.to_proto()),
11451                        },
11452                    ),
11453                ),
11454            });
11455            cx.background_spawn(request).detach_and_log_err(cx);
11456        }
11457    }
11458
11459    fn register_supplementary_language_server(
11460        &mut self,
11461        id: LanguageServerId,
11462        name: LanguageServerName,
11463        server: Arc<LanguageServer>,
11464        cx: &mut Context<Self>,
11465    ) {
11466        if let Some(local) = self.as_local_mut() {
11467            local
11468                .supplementary_language_servers
11469                .insert(id, (name.clone(), server));
11470            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11471        }
11472    }
11473
11474    fn unregister_supplementary_language_server(
11475        &mut self,
11476        id: LanguageServerId,
11477        cx: &mut Context<Self>,
11478    ) {
11479        if let Some(local) = self.as_local_mut() {
11480            local.supplementary_language_servers.remove(&id);
11481            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11482        }
11483    }
11484
11485    pub(crate) fn supplementary_language_servers(
11486        &self,
11487    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11488        self.as_local().into_iter().flat_map(|local| {
11489            local
11490                .supplementary_language_servers
11491                .iter()
11492                .map(|(id, (name, _))| (*id, name.clone()))
11493        })
11494    }
11495
11496    pub fn language_server_adapter_for_id(
11497        &self,
11498        id: LanguageServerId,
11499    ) -> Option<Arc<CachedLspAdapter>> {
11500        self.as_local()
11501            .and_then(|local| local.language_servers.get(&id))
11502            .and_then(|language_server_state| match language_server_state {
11503                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11504                _ => None,
11505            })
11506    }
11507
11508    pub(super) fn update_local_worktree_language_servers(
11509        &mut self,
11510        worktree_handle: &Entity<Worktree>,
11511        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11512        cx: &mut Context<Self>,
11513    ) {
11514        if changes.is_empty() {
11515            return;
11516        }
11517
11518        let Some(local) = self.as_local() else { return };
11519
11520        local.prettier_store.update(cx, |prettier_store, cx| {
11521            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11522        });
11523
11524        let worktree_id = worktree_handle.read(cx).id();
11525        let mut language_server_ids = local
11526            .language_server_ids
11527            .iter()
11528            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11529            .collect::<Vec<_>>();
11530        language_server_ids.sort();
11531        language_server_ids.dedup();
11532
11533        // let abs_path = worktree_handle.read(cx).abs_path();
11534        for server_id in &language_server_ids {
11535            if let Some(LanguageServerState::Running { server, .. }) =
11536                local.language_servers.get(server_id)
11537                && let Some(watched_paths) = local
11538                    .language_server_watched_paths
11539                    .get(server_id)
11540                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11541            {
11542                let params = lsp::DidChangeWatchedFilesParams {
11543                    changes: changes
11544                        .iter()
11545                        .filter_map(|(path, _, change)| {
11546                            if !watched_paths.is_match(path.as_std_path()) {
11547                                return None;
11548                            }
11549                            let typ = match change {
11550                                PathChange::Loaded => return None,
11551                                PathChange::Added => lsp::FileChangeType::CREATED,
11552                                PathChange::Removed => lsp::FileChangeType::DELETED,
11553                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11554                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11555                            };
11556                            let uri = lsp::Uri::from_file_path(
11557                                worktree_handle.read(cx).absolutize(&path),
11558                            )
11559                            .ok()?;
11560                            Some(lsp::FileEvent { uri, typ })
11561                        })
11562                        .collect(),
11563                };
11564                if !params.changes.is_empty() {
11565                    server
11566                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11567                        .ok();
11568                }
11569            }
11570        }
11571        for (path, _, _) in changes {
11572            if let Some(file_name) = path.file_name()
11573                && local.watched_manifest_filenames.contains(file_name)
11574            {
11575                self.request_workspace_config_refresh();
11576                break;
11577            }
11578        }
11579    }
11580
11581    pub fn wait_for_remote_buffer(
11582        &mut self,
11583        id: BufferId,
11584        cx: &mut Context<Self>,
11585    ) -> Task<Result<Entity<Buffer>>> {
11586        self.buffer_store.update(cx, |buffer_store, cx| {
11587            buffer_store.wait_for_remote_buffer(id, cx)
11588        })
11589    }
11590
11591    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11592        let mut result = proto::Symbol {
11593            language_server_name: symbol.language_server_name.0.to_string(),
11594            source_worktree_id: symbol.source_worktree_id.to_proto(),
11595            language_server_id: symbol.source_language_server_id.to_proto(),
11596            name: symbol.name.clone(),
11597            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11598            start: Some(proto::PointUtf16 {
11599                row: symbol.range.start.0.row,
11600                column: symbol.range.start.0.column,
11601            }),
11602            end: Some(proto::PointUtf16 {
11603                row: symbol.range.end.0.row,
11604                column: symbol.range.end.0.column,
11605            }),
11606            worktree_id: Default::default(),
11607            path: Default::default(),
11608            signature: Default::default(),
11609        };
11610        match &symbol.path {
11611            SymbolLocation::InProject(path) => {
11612                result.worktree_id = path.worktree_id.to_proto();
11613                result.path = path.path.to_proto();
11614            }
11615            SymbolLocation::OutsideProject {
11616                abs_path,
11617                signature,
11618            } => {
11619                result.path = abs_path.to_string_lossy().into_owned();
11620                result.signature = signature.to_vec();
11621            }
11622        }
11623        result
11624    }
11625
11626    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11627        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11628        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11629        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11630
11631        let path = if serialized_symbol.signature.is_empty() {
11632            SymbolLocation::InProject(ProjectPath {
11633                worktree_id,
11634                path: RelPath::from_proto(&serialized_symbol.path)
11635                    .context("invalid symbol path")?,
11636            })
11637        } else {
11638            SymbolLocation::OutsideProject {
11639                abs_path: Path::new(&serialized_symbol.path).into(),
11640                signature: serialized_symbol
11641                    .signature
11642                    .try_into()
11643                    .map_err(|_| anyhow!("invalid signature"))?,
11644            }
11645        };
11646
11647        let start = serialized_symbol.start.context("invalid start")?;
11648        let end = serialized_symbol.end.context("invalid end")?;
11649        Ok(CoreSymbol {
11650            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11651            source_worktree_id,
11652            source_language_server_id: LanguageServerId::from_proto(
11653                serialized_symbol.language_server_id,
11654            ),
11655            path,
11656            name: serialized_symbol.name,
11657            range: Unclipped(PointUtf16::new(start.row, start.column))
11658                ..Unclipped(PointUtf16::new(end.row, end.column)),
11659            kind,
11660        })
11661    }
11662
11663    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11664        let mut serialized_completion = proto::Completion {
11665            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11666            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11667            new_text: completion.new_text.clone(),
11668            ..proto::Completion::default()
11669        };
11670        match &completion.source {
11671            CompletionSource::Lsp {
11672                insert_range,
11673                server_id,
11674                lsp_completion,
11675                lsp_defaults,
11676                resolved,
11677            } => {
11678                let (old_insert_start, old_insert_end) = insert_range
11679                    .as_ref()
11680                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11681                    .unzip();
11682
11683                serialized_completion.old_insert_start = old_insert_start;
11684                serialized_completion.old_insert_end = old_insert_end;
11685                serialized_completion.source = proto::completion::Source::Lsp as i32;
11686                serialized_completion.server_id = server_id.0 as u64;
11687                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11688                serialized_completion.lsp_defaults = lsp_defaults
11689                    .as_deref()
11690                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11691                serialized_completion.resolved = *resolved;
11692            }
11693            CompletionSource::BufferWord {
11694                word_range,
11695                resolved,
11696            } => {
11697                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11698                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11699                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11700                serialized_completion.resolved = *resolved;
11701            }
11702            CompletionSource::Custom => {
11703                serialized_completion.source = proto::completion::Source::Custom as i32;
11704                serialized_completion.resolved = true;
11705            }
11706            CompletionSource::Dap { sort_text } => {
11707                serialized_completion.source = proto::completion::Source::Dap as i32;
11708                serialized_completion.sort_text = Some(sort_text.clone());
11709            }
11710        }
11711
11712        serialized_completion
11713    }
11714
11715    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11716        let old_replace_start = completion
11717            .old_replace_start
11718            .and_then(deserialize_anchor)
11719            .context("invalid old start")?;
11720        let old_replace_end = completion
11721            .old_replace_end
11722            .and_then(deserialize_anchor)
11723            .context("invalid old end")?;
11724        let insert_range = {
11725            match completion.old_insert_start.zip(completion.old_insert_end) {
11726                Some((start, end)) => {
11727                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11728                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11729                    Some(start..end)
11730                }
11731                None => None,
11732            }
11733        };
11734        Ok(CoreCompletion {
11735            replace_range: old_replace_start..old_replace_end,
11736            new_text: completion.new_text,
11737            source: match proto::completion::Source::from_i32(completion.source) {
11738                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11739                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11740                    insert_range,
11741                    server_id: LanguageServerId::from_proto(completion.server_id),
11742                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11743                    lsp_defaults: completion
11744                        .lsp_defaults
11745                        .as_deref()
11746                        .map(serde_json::from_slice)
11747                        .transpose()?,
11748                    resolved: completion.resolved,
11749                },
11750                Some(proto::completion::Source::BufferWord) => {
11751                    let word_range = completion
11752                        .buffer_word_start
11753                        .and_then(deserialize_anchor)
11754                        .context("invalid buffer word start")?
11755                        ..completion
11756                            .buffer_word_end
11757                            .and_then(deserialize_anchor)
11758                            .context("invalid buffer word end")?;
11759                    CompletionSource::BufferWord {
11760                        word_range,
11761                        resolved: completion.resolved,
11762                    }
11763                }
11764                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11765                    sort_text: completion
11766                        .sort_text
11767                        .context("expected sort text to exist")?,
11768                },
11769                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11770            },
11771        })
11772    }
11773
11774    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11775        let (kind, lsp_action) = match &action.lsp_action {
11776            LspAction::Action(code_action) => (
11777                proto::code_action::Kind::Action as i32,
11778                serde_json::to_vec(code_action).unwrap(),
11779            ),
11780            LspAction::Command(command) => (
11781                proto::code_action::Kind::Command as i32,
11782                serde_json::to_vec(command).unwrap(),
11783            ),
11784            LspAction::CodeLens(code_lens) => (
11785                proto::code_action::Kind::CodeLens as i32,
11786                serde_json::to_vec(code_lens).unwrap(),
11787            ),
11788        };
11789
11790        proto::CodeAction {
11791            server_id: action.server_id.0 as u64,
11792            start: Some(serialize_anchor(&action.range.start)),
11793            end: Some(serialize_anchor(&action.range.end)),
11794            lsp_action,
11795            kind,
11796            resolved: action.resolved,
11797        }
11798    }
11799
11800    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11801        let start = action
11802            .start
11803            .and_then(deserialize_anchor)
11804            .context("invalid start")?;
11805        let end = action
11806            .end
11807            .and_then(deserialize_anchor)
11808            .context("invalid end")?;
11809        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11810            Some(proto::code_action::Kind::Action) => {
11811                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11812            }
11813            Some(proto::code_action::Kind::Command) => {
11814                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11815            }
11816            Some(proto::code_action::Kind::CodeLens) => {
11817                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11818            }
11819            None => anyhow::bail!("Unknown action kind {}", action.kind),
11820        };
11821        Ok(CodeAction {
11822            server_id: LanguageServerId(action.server_id as usize),
11823            range: start..end,
11824            resolved: action.resolved,
11825            lsp_action,
11826        })
11827    }
11828
11829    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11830        match &formatting_result {
11831            Ok(_) => self.last_formatting_failure = None,
11832            Err(error) => {
11833                let error_string = format!("{error:#}");
11834                log::error!("Formatting failed: {error_string}");
11835                self.last_formatting_failure
11836                    .replace(error_string.lines().join(" "));
11837            }
11838        }
11839    }
11840
11841    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11842        self.lsp_server_capabilities.remove(&for_server);
11843        for lsp_data in self.lsp_data.values_mut() {
11844            lsp_data.remove_server_data(for_server);
11845        }
11846        if let Some(local) = self.as_local_mut() {
11847            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11848            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11849                buffer_servers.remove(&for_server);
11850            }
11851        }
11852    }
11853
11854    pub fn result_id(
11855        &self,
11856        server_id: LanguageServerId,
11857        buffer_id: BufferId,
11858        cx: &App,
11859    ) -> Option<String> {
11860        let abs_path = self
11861            .buffer_store
11862            .read(cx)
11863            .get(buffer_id)
11864            .and_then(|b| File::from_dyn(b.read(cx).file()))
11865            .map(|f| f.abs_path(cx))?;
11866        self.as_local()?
11867            .buffer_pull_diagnostics_result_ids
11868            .get(&server_id)?
11869            .get(&abs_path)?
11870            .clone()
11871    }
11872
11873    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11874        let Some(local) = self.as_local() else {
11875            return HashMap::default();
11876        };
11877        local
11878            .buffer_pull_diagnostics_result_ids
11879            .get(&server_id)
11880            .into_iter()
11881            .flatten()
11882            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11883            .collect()
11884    }
11885
11886    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11887        if let Some(LanguageServerState::Running {
11888            workspace_diagnostics_refresh_tasks,
11889            ..
11890        }) = self
11891            .as_local_mut()
11892            .and_then(|local| local.language_servers.get_mut(&server_id))
11893        {
11894            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11895                diagnostics.refresh_tx.try_send(()).ok();
11896            }
11897        }
11898    }
11899
11900    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11901        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11902            return;
11903        };
11904        let Some(local) = self.as_local_mut() else {
11905            return;
11906        };
11907
11908        for server_id in buffer.update(cx, |buffer, cx| {
11909            local.language_server_ids_for_buffer(buffer, cx)
11910        }) {
11911            if let Some(LanguageServerState::Running {
11912                workspace_diagnostics_refresh_tasks,
11913                ..
11914            }) = local.language_servers.get_mut(&server_id)
11915            {
11916                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11917                    diagnostics.refresh_tx.try_send(()).ok();
11918                }
11919            }
11920        }
11921    }
11922
11923    fn apply_workspace_diagnostic_report(
11924        &mut self,
11925        server_id: LanguageServerId,
11926        report: lsp::WorkspaceDiagnosticReportResult,
11927        cx: &mut Context<Self>,
11928    ) {
11929        let workspace_diagnostics =
11930            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11931        let mut unchanged_buffers = HashSet::default();
11932        let mut changed_buffers = HashSet::default();
11933        let workspace_diagnostics_updates = workspace_diagnostics
11934            .into_iter()
11935            .filter_map(
11936                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11937                    LspPullDiagnostics::Response {
11938                        server_id,
11939                        uri,
11940                        diagnostics,
11941                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11942                    LspPullDiagnostics::Default => None,
11943                },
11944            )
11945            .fold(
11946                HashMap::default(),
11947                |mut acc, (server_id, uri, diagnostics, version)| {
11948                    let (result_id, diagnostics) = match diagnostics {
11949                        PulledDiagnostics::Unchanged { result_id } => {
11950                            unchanged_buffers.insert(uri.clone());
11951                            (Some(result_id), Vec::new())
11952                        }
11953                        PulledDiagnostics::Changed {
11954                            result_id,
11955                            diagnostics,
11956                        } => {
11957                            changed_buffers.insert(uri.clone());
11958                            (result_id, diagnostics)
11959                        }
11960                    };
11961                    let disk_based_sources = Cow::Owned(
11962                        self.language_server_adapter_for_id(server_id)
11963                            .as_ref()
11964                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11965                            .unwrap_or(&[])
11966                            .to_vec(),
11967                    );
11968                    acc.entry(server_id)
11969                        .or_insert_with(Vec::new)
11970                        .push(DocumentDiagnosticsUpdate {
11971                            server_id,
11972                            diagnostics: lsp::PublishDiagnosticsParams {
11973                                uri,
11974                                diagnostics,
11975                                version,
11976                            },
11977                            result_id,
11978                            disk_based_sources,
11979                        });
11980                    acc
11981                },
11982            );
11983
11984        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11985            self.merge_lsp_diagnostics(
11986                DiagnosticSourceKind::Pulled,
11987                diagnostic_updates,
11988                |buffer, old_diagnostic, cx| {
11989                    File::from_dyn(buffer.file())
11990                        .and_then(|file| {
11991                            let abs_path = file.as_local()?.abs_path(cx);
11992                            lsp::Uri::from_file_path(abs_path).ok()
11993                        })
11994                        .is_none_or(|buffer_uri| {
11995                            unchanged_buffers.contains(&buffer_uri)
11996                                || match old_diagnostic.source_kind {
11997                                    DiagnosticSourceKind::Pulled => {
11998                                        !changed_buffers.contains(&buffer_uri)
11999                                    }
12000                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
12001                                        true
12002                                    }
12003                                }
12004                        })
12005                },
12006                cx,
12007            )
12008            .log_err();
12009        }
12010    }
12011
12012    fn register_server_capabilities(
12013        &mut self,
12014        server_id: LanguageServerId,
12015        params: lsp::RegistrationParams,
12016        cx: &mut Context<Self>,
12017    ) -> anyhow::Result<()> {
12018        let server = self
12019            .language_server_for_id(server_id)
12020            .with_context(|| format!("no server {server_id} found"))?;
12021        for reg in params.registrations {
12022            match reg.method.as_str() {
12023                "workspace/didChangeWatchedFiles" => {
12024                    if let Some(options) = reg.register_options {
12025                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12026                            let caps = serde_json::from_value(options)?;
12027                            local_lsp_store
12028                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12029                            true
12030                        } else {
12031                            false
12032                        };
12033                        if notify {
12034                            notify_server_capabilities_updated(&server, cx);
12035                        }
12036                    }
12037                }
12038                "workspace/didChangeConfiguration" => {
12039                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12040                }
12041                "workspace/didChangeWorkspaceFolders" => {
12042                    // In this case register options is an empty object, we can ignore it
12043                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12044                        supported: Some(true),
12045                        change_notifications: Some(OneOf::Right(reg.id)),
12046                    };
12047                    server.update_capabilities(|capabilities| {
12048                        capabilities
12049                            .workspace
12050                            .get_or_insert_default()
12051                            .workspace_folders = Some(caps);
12052                    });
12053                    notify_server_capabilities_updated(&server, cx);
12054                }
12055                "workspace/symbol" => {
12056                    let options = parse_register_capabilities(reg)?;
12057                    server.update_capabilities(|capabilities| {
12058                        capabilities.workspace_symbol_provider = Some(options);
12059                    });
12060                    notify_server_capabilities_updated(&server, cx);
12061                }
12062                "workspace/fileOperations" => {
12063                    if let Some(options) = reg.register_options {
12064                        let caps = serde_json::from_value(options)?;
12065                        server.update_capabilities(|capabilities| {
12066                            capabilities
12067                                .workspace
12068                                .get_or_insert_default()
12069                                .file_operations = Some(caps);
12070                        });
12071                        notify_server_capabilities_updated(&server, cx);
12072                    }
12073                }
12074                "workspace/executeCommand" => {
12075                    if let Some(options) = reg.register_options {
12076                        let options = serde_json::from_value(options)?;
12077                        server.update_capabilities(|capabilities| {
12078                            capabilities.execute_command_provider = Some(options);
12079                        });
12080                        notify_server_capabilities_updated(&server, cx);
12081                    }
12082                }
12083                "textDocument/rangeFormatting" => {
12084                    let options = parse_register_capabilities(reg)?;
12085                    server.update_capabilities(|capabilities| {
12086                        capabilities.document_range_formatting_provider = Some(options);
12087                    });
12088                    notify_server_capabilities_updated(&server, cx);
12089                }
12090                "textDocument/onTypeFormatting" => {
12091                    if let Some(options) = reg
12092                        .register_options
12093                        .map(serde_json::from_value)
12094                        .transpose()?
12095                    {
12096                        server.update_capabilities(|capabilities| {
12097                            capabilities.document_on_type_formatting_provider = Some(options);
12098                        });
12099                        notify_server_capabilities_updated(&server, cx);
12100                    }
12101                }
12102                "textDocument/formatting" => {
12103                    let options = parse_register_capabilities(reg)?;
12104                    server.update_capabilities(|capabilities| {
12105                        capabilities.document_formatting_provider = Some(options);
12106                    });
12107                    notify_server_capabilities_updated(&server, cx);
12108                }
12109                "textDocument/rename" => {
12110                    let options = parse_register_capabilities(reg)?;
12111                    server.update_capabilities(|capabilities| {
12112                        capabilities.rename_provider = Some(options);
12113                    });
12114                    notify_server_capabilities_updated(&server, cx);
12115                }
12116                "textDocument/inlayHint" => {
12117                    let options = parse_register_capabilities(reg)?;
12118                    server.update_capabilities(|capabilities| {
12119                        capabilities.inlay_hint_provider = Some(options);
12120                    });
12121                    notify_server_capabilities_updated(&server, cx);
12122                }
12123                "textDocument/documentSymbol" => {
12124                    let options = parse_register_capabilities(reg)?;
12125                    server.update_capabilities(|capabilities| {
12126                        capabilities.document_symbol_provider = Some(options);
12127                    });
12128                    notify_server_capabilities_updated(&server, cx);
12129                }
12130                "textDocument/codeAction" => {
12131                    let options = parse_register_capabilities(reg)?;
12132                    let provider = match options {
12133                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12134                        OneOf::Right(caps) => caps,
12135                    };
12136                    server.update_capabilities(|capabilities| {
12137                        capabilities.code_action_provider = Some(provider);
12138                    });
12139                    notify_server_capabilities_updated(&server, cx);
12140                }
12141                "textDocument/definition" => {
12142                    let options = parse_register_capabilities(reg)?;
12143                    server.update_capabilities(|capabilities| {
12144                        capabilities.definition_provider = Some(options);
12145                    });
12146                    notify_server_capabilities_updated(&server, cx);
12147                }
12148                "textDocument/completion" => {
12149                    if let Some(caps) = reg
12150                        .register_options
12151                        .map(serde_json::from_value::<CompletionOptions>)
12152                        .transpose()?
12153                    {
12154                        server.update_capabilities(|capabilities| {
12155                            capabilities.completion_provider = Some(caps.clone());
12156                        });
12157
12158                        if let Some(local) = self.as_local() {
12159                            let mut buffers_with_language_server = Vec::new();
12160                            for handle in self.buffer_store.read(cx).buffers() {
12161                                let buffer_id = handle.read(cx).remote_id();
12162                                if local
12163                                    .buffers_opened_in_servers
12164                                    .get(&buffer_id)
12165                                    .filter(|s| s.contains(&server_id))
12166                                    .is_some()
12167                                {
12168                                    buffers_with_language_server.push(handle);
12169                                }
12170                            }
12171                            let triggers = caps
12172                                .trigger_characters
12173                                .unwrap_or_default()
12174                                .into_iter()
12175                                .collect::<BTreeSet<_>>();
12176                            for handle in buffers_with_language_server {
12177                                let triggers = triggers.clone();
12178                                let _ = handle.update(cx, move |buffer, cx| {
12179                                    buffer.set_completion_triggers(server_id, triggers, cx);
12180                                });
12181                            }
12182                        }
12183                        notify_server_capabilities_updated(&server, cx);
12184                    }
12185                }
12186                "textDocument/hover" => {
12187                    let options = parse_register_capabilities(reg)?;
12188                    let provider = match options {
12189                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12190                        OneOf::Right(caps) => caps,
12191                    };
12192                    server.update_capabilities(|capabilities| {
12193                        capabilities.hover_provider = Some(provider);
12194                    });
12195                    notify_server_capabilities_updated(&server, cx);
12196                }
12197                "textDocument/signatureHelp" => {
12198                    if let Some(caps) = reg
12199                        .register_options
12200                        .map(serde_json::from_value)
12201                        .transpose()?
12202                    {
12203                        server.update_capabilities(|capabilities| {
12204                            capabilities.signature_help_provider = Some(caps);
12205                        });
12206                        notify_server_capabilities_updated(&server, cx);
12207                    }
12208                }
12209                "textDocument/didChange" => {
12210                    if let Some(sync_kind) = reg
12211                        .register_options
12212                        .and_then(|opts| opts.get("syncKind").cloned())
12213                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12214                        .transpose()?
12215                    {
12216                        server.update_capabilities(|capabilities| {
12217                            let mut sync_options =
12218                                Self::take_text_document_sync_options(capabilities);
12219                            sync_options.change = Some(sync_kind);
12220                            capabilities.text_document_sync =
12221                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12222                        });
12223                        notify_server_capabilities_updated(&server, cx);
12224                    }
12225                }
12226                "textDocument/didSave" => {
12227                    if let Some(include_text) = reg
12228                        .register_options
12229                        .map(|opts| {
12230                            let transpose = opts
12231                                .get("includeText")
12232                                .cloned()
12233                                .map(serde_json::from_value::<Option<bool>>)
12234                                .transpose();
12235                            match transpose {
12236                                Ok(value) => Ok(value.flatten()),
12237                                Err(e) => Err(e),
12238                            }
12239                        })
12240                        .transpose()?
12241                    {
12242                        server.update_capabilities(|capabilities| {
12243                            let mut sync_options =
12244                                Self::take_text_document_sync_options(capabilities);
12245                            sync_options.save =
12246                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12247                                    include_text,
12248                                }));
12249                            capabilities.text_document_sync =
12250                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12251                        });
12252                        notify_server_capabilities_updated(&server, cx);
12253                    }
12254                }
12255                "textDocument/codeLens" => {
12256                    if let Some(caps) = reg
12257                        .register_options
12258                        .map(serde_json::from_value)
12259                        .transpose()?
12260                    {
12261                        server.update_capabilities(|capabilities| {
12262                            capabilities.code_lens_provider = Some(caps);
12263                        });
12264                        notify_server_capabilities_updated(&server, cx);
12265                    }
12266                }
12267                "textDocument/diagnostic" => {
12268                    if let Some(caps) = reg
12269                        .register_options
12270                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12271                        .transpose()?
12272                    {
12273                        let local = self
12274                            .as_local_mut()
12275                            .context("Expected LSP Store to be local")?;
12276                        let state = local
12277                            .language_servers
12278                            .get_mut(&server_id)
12279                            .context("Could not obtain Language Servers state")?;
12280                        local
12281                            .language_server_dynamic_registrations
12282                            .entry(server_id)
12283                            .or_default()
12284                            .diagnostics
12285                            .insert(Some(reg.id.clone()), caps.clone());
12286
12287                        if let LanguageServerState::Running {
12288                            workspace_diagnostics_refresh_tasks,
12289                            ..
12290                        } = state
12291                            && let Some(task) = lsp_workspace_diagnostics_refresh(
12292                                Some(reg.id.clone()),
12293                                caps.clone(),
12294                                server.clone(),
12295                                cx,
12296                            )
12297                        {
12298                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12299                        }
12300
12301                        let mut did_update_caps = false;
12302                        server.update_capabilities(|capabilities| {
12303                            if capabilities.diagnostic_provider.as_ref().is_none_or(
12304                                |current_caps| {
12305                                    let supports_workspace_diagnostics =
12306                                        |capabilities: &DiagnosticServerCapabilities| {
12307                                            match capabilities {
12308                                            DiagnosticServerCapabilities::Options(
12309                                                diagnostic_options,
12310                                            ) => diagnostic_options.workspace_diagnostics,
12311                                            DiagnosticServerCapabilities::RegistrationOptions(
12312                                                diagnostic_registration_options,
12313                                            ) => {
12314                                                diagnostic_registration_options
12315                                                    .diagnostic_options
12316                                                    .workspace_diagnostics
12317                                            }
12318                                        }
12319                                        };
12320                                    // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
12321                                    // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
12322                                    // as it'll think that they're not supported.
12323                                    // If we did not support any workspace diagnostics up to this point but now do, let's update.
12324                                    !supports_workspace_diagnostics(current_caps)
12325                                        & supports_workspace_diagnostics(&caps)
12326                                },
12327                            ) {
12328                                did_update_caps = true;
12329                                capabilities.diagnostic_provider = Some(caps);
12330                            }
12331                        });
12332                        if did_update_caps {
12333                            notify_server_capabilities_updated(&server, cx);
12334                        }
12335                    }
12336                }
12337                "textDocument/documentColor" => {
12338                    let options = parse_register_capabilities(reg)?;
12339                    let provider = match options {
12340                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12341                        OneOf::Right(caps) => caps,
12342                    };
12343                    server.update_capabilities(|capabilities| {
12344                        capabilities.color_provider = Some(provider);
12345                    });
12346                    notify_server_capabilities_updated(&server, cx);
12347                }
12348                _ => log::warn!("unhandled capability registration: {reg:?}"),
12349            }
12350        }
12351
12352        Ok(())
12353    }
12354
12355    fn unregister_server_capabilities(
12356        &mut self,
12357        server_id: LanguageServerId,
12358        params: lsp::UnregistrationParams,
12359        cx: &mut Context<Self>,
12360    ) -> anyhow::Result<()> {
12361        let server = self
12362            .language_server_for_id(server_id)
12363            .with_context(|| format!("no server {server_id} found"))?;
12364        for unreg in params.unregisterations.iter() {
12365            match unreg.method.as_str() {
12366                "workspace/didChangeWatchedFiles" => {
12367                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12368                        local_lsp_store
12369                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12370                        true
12371                    } else {
12372                        false
12373                    };
12374                    if notify {
12375                        notify_server_capabilities_updated(&server, cx);
12376                    }
12377                }
12378                "workspace/didChangeConfiguration" => {
12379                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12380                }
12381                "workspace/didChangeWorkspaceFolders" => {
12382                    server.update_capabilities(|capabilities| {
12383                        capabilities
12384                            .workspace
12385                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12386                                workspace_folders: None,
12387                                file_operations: None,
12388                            })
12389                            .workspace_folders = None;
12390                    });
12391                    notify_server_capabilities_updated(&server, cx);
12392                }
12393                "workspace/symbol" => {
12394                    server.update_capabilities(|capabilities| {
12395                        capabilities.workspace_symbol_provider = None
12396                    });
12397                    notify_server_capabilities_updated(&server, cx);
12398                }
12399                "workspace/fileOperations" => {
12400                    server.update_capabilities(|capabilities| {
12401                        capabilities
12402                            .workspace
12403                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12404                                workspace_folders: None,
12405                                file_operations: None,
12406                            })
12407                            .file_operations = None;
12408                    });
12409                    notify_server_capabilities_updated(&server, cx);
12410                }
12411                "workspace/executeCommand" => {
12412                    server.update_capabilities(|capabilities| {
12413                        capabilities.execute_command_provider = None;
12414                    });
12415                    notify_server_capabilities_updated(&server, cx);
12416                }
12417                "textDocument/rangeFormatting" => {
12418                    server.update_capabilities(|capabilities| {
12419                        capabilities.document_range_formatting_provider = None
12420                    });
12421                    notify_server_capabilities_updated(&server, cx);
12422                }
12423                "textDocument/onTypeFormatting" => {
12424                    server.update_capabilities(|capabilities| {
12425                        capabilities.document_on_type_formatting_provider = None;
12426                    });
12427                    notify_server_capabilities_updated(&server, cx);
12428                }
12429                "textDocument/formatting" => {
12430                    server.update_capabilities(|capabilities| {
12431                        capabilities.document_formatting_provider = None;
12432                    });
12433                    notify_server_capabilities_updated(&server, cx);
12434                }
12435                "textDocument/rename" => {
12436                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12437                    notify_server_capabilities_updated(&server, cx);
12438                }
12439                "textDocument/codeAction" => {
12440                    server.update_capabilities(|capabilities| {
12441                        capabilities.code_action_provider = None;
12442                    });
12443                    notify_server_capabilities_updated(&server, cx);
12444                }
12445                "textDocument/definition" => {
12446                    server.update_capabilities(|capabilities| {
12447                        capabilities.definition_provider = None;
12448                    });
12449                    notify_server_capabilities_updated(&server, cx);
12450                }
12451                "textDocument/completion" => {
12452                    server.update_capabilities(|capabilities| {
12453                        capabilities.completion_provider = None;
12454                    });
12455                    notify_server_capabilities_updated(&server, cx);
12456                }
12457                "textDocument/hover" => {
12458                    server.update_capabilities(|capabilities| {
12459                        capabilities.hover_provider = None;
12460                    });
12461                    notify_server_capabilities_updated(&server, cx);
12462                }
12463                "textDocument/signatureHelp" => {
12464                    server.update_capabilities(|capabilities| {
12465                        capabilities.signature_help_provider = None;
12466                    });
12467                    notify_server_capabilities_updated(&server, cx);
12468                }
12469                "textDocument/didChange" => {
12470                    server.update_capabilities(|capabilities| {
12471                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12472                        sync_options.change = None;
12473                        capabilities.text_document_sync =
12474                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12475                    });
12476                    notify_server_capabilities_updated(&server, cx);
12477                }
12478                "textDocument/didSave" => {
12479                    server.update_capabilities(|capabilities| {
12480                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12481                        sync_options.save = None;
12482                        capabilities.text_document_sync =
12483                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12484                    });
12485                    notify_server_capabilities_updated(&server, cx);
12486                }
12487                "textDocument/codeLens" => {
12488                    server.update_capabilities(|capabilities| {
12489                        capabilities.code_lens_provider = None;
12490                    });
12491                    notify_server_capabilities_updated(&server, cx);
12492                }
12493                "textDocument/diagnostic" => {
12494                    let local = self
12495                        .as_local_mut()
12496                        .context("Expected LSP Store to be local")?;
12497
12498                    let state = local
12499                        .language_servers
12500                        .get_mut(&server_id)
12501                        .context("Could not obtain Language Servers state")?;
12502                    let options = local
12503                        .language_server_dynamic_registrations
12504                        .get_mut(&server_id)
12505                        .with_context(|| {
12506                            format!("Expected dynamic registration to exist for server {server_id}")
12507                        })?.diagnostics
12508                        .remove(&Some(unreg.id.clone()))
12509                        .with_context(|| format!(
12510                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12511                            unreg.id)
12512                        )?;
12513
12514                    let mut has_any_diagnostic_providers_still = true;
12515                    if let Some(identifier) = diagnostic_identifier(&options)
12516                        && let LanguageServerState::Running {
12517                            workspace_diagnostics_refresh_tasks,
12518                            ..
12519                        } = state
12520                    {
12521                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12522                        has_any_diagnostic_providers_still =
12523                            !workspace_diagnostics_refresh_tasks.is_empty();
12524                    }
12525
12526                    if !has_any_diagnostic_providers_still {
12527                        server.update_capabilities(|capabilities| {
12528                            debug_assert!(capabilities.diagnostic_provider.is_some());
12529                            capabilities.diagnostic_provider = None;
12530                        });
12531                    }
12532
12533                    notify_server_capabilities_updated(&server, cx);
12534                }
12535                "textDocument/documentColor" => {
12536                    server.update_capabilities(|capabilities| {
12537                        capabilities.color_provider = None;
12538                    });
12539                    notify_server_capabilities_updated(&server, cx);
12540                }
12541                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12542            }
12543        }
12544
12545        Ok(())
12546    }
12547
12548    async fn deduplicate_range_based_lsp_requests<T>(
12549        lsp_store: &Entity<Self>,
12550        server_id: Option<LanguageServerId>,
12551        lsp_request_id: LspRequestId,
12552        proto_request: &T::ProtoRequest,
12553        range: Range<Anchor>,
12554        cx: &mut AsyncApp,
12555    ) -> Result<()>
12556    where
12557        T: LspCommand,
12558        T::ProtoRequest: proto::LspRequestMessage,
12559    {
12560        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12561        let version = deserialize_version(proto_request.buffer_version());
12562        let buffer = lsp_store.update(cx, |this, cx| {
12563            this.buffer_store.read(cx).get_existing(buffer_id)
12564        })??;
12565        buffer
12566            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12567            .await?;
12568        lsp_store.update(cx, |lsp_store, cx| {
12569            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12570            let chunks_queried_for = lsp_data
12571                .inlay_hints
12572                .applicable_chunks(&[range])
12573                .collect::<Vec<_>>();
12574            match chunks_queried_for.as_slice() {
12575                &[chunk] => {
12576                    let key = LspKey {
12577                        request_type: TypeId::of::<T>(),
12578                        server_queried: server_id,
12579                    };
12580                    let previous_request = lsp_data
12581                        .chunk_lsp_requests
12582                        .entry(key)
12583                        .or_default()
12584                        .insert(chunk, lsp_request_id);
12585                    if let Some((previous_request, running_requests)) =
12586                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12587                    {
12588                        running_requests.remove(&previous_request);
12589                    }
12590                }
12591                _ambiguous_chunks => {
12592                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12593                    // there, a buffer version-based check will be performed and outdated requests discarded.
12594                }
12595            }
12596            anyhow::Ok(())
12597        })??;
12598
12599        Ok(())
12600    }
12601
12602    async fn query_lsp_locally<T>(
12603        lsp_store: Entity<Self>,
12604        for_server_id: Option<LanguageServerId>,
12605        sender_id: proto::PeerId,
12606        lsp_request_id: LspRequestId,
12607        proto_request: T::ProtoRequest,
12608        position: Option<Anchor>,
12609        cx: &mut AsyncApp,
12610    ) -> Result<()>
12611    where
12612        T: LspCommand + Clone,
12613        T::ProtoRequest: proto::LspRequestMessage,
12614        <T::ProtoRequest as proto::RequestMessage>::Response:
12615            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12616    {
12617        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12618        let version = deserialize_version(proto_request.buffer_version());
12619        let buffer = lsp_store.update(cx, |this, cx| {
12620            this.buffer_store.read(cx).get_existing(buffer_id)
12621        })??;
12622        buffer
12623            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12624            .await?;
12625        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12626        let request =
12627            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12628        let key = LspKey {
12629            request_type: TypeId::of::<T>(),
12630            server_queried: for_server_id,
12631        };
12632        lsp_store.update(cx, |lsp_store, cx| {
12633            let request_task = match for_server_id {
12634                Some(server_id) => {
12635                    let server_task = lsp_store.request_lsp(
12636                        buffer.clone(),
12637                        LanguageServerToQuery::Other(server_id),
12638                        request.clone(),
12639                        cx,
12640                    );
12641                    cx.background_spawn(async move {
12642                        let mut responses = Vec::new();
12643                        match server_task.await {
12644                            Ok(response) => responses.push((server_id, response)),
12645                            // rust-analyzer likes to error with this when its still loading up
12646                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12647                            Err(e) => log::error!(
12648                                "Error handling response for request {request:?}: {e:#}"
12649                            ),
12650                        }
12651                        responses
12652                    })
12653                }
12654                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12655            };
12656            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12657            if T::ProtoRequest::stop_previous_requests() {
12658                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12659                    lsp_requests.clear();
12660                }
12661            }
12662            lsp_data.lsp_requests.entry(key).or_default().insert(
12663                lsp_request_id,
12664                cx.spawn(async move |lsp_store, cx| {
12665                    let response = request_task.await;
12666                    lsp_store
12667                        .update(cx, |lsp_store, cx| {
12668                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12669                            {
12670                                let response = response
12671                                    .into_iter()
12672                                    .map(|(server_id, response)| {
12673                                        (
12674                                            server_id.to_proto(),
12675                                            T::response_to_proto(
12676                                                response,
12677                                                lsp_store,
12678                                                sender_id,
12679                                                &buffer_version,
12680                                                cx,
12681                                            )
12682                                            .into(),
12683                                        )
12684                                    })
12685                                    .collect::<HashMap<_, _>>();
12686                                match client.send_lsp_response::<T::ProtoRequest>(
12687                                    project_id,
12688                                    lsp_request_id,
12689                                    response,
12690                                ) {
12691                                    Ok(()) => {}
12692                                    Err(e) => {
12693                                        log::error!("Failed to send LSP response: {e:#}",)
12694                                    }
12695                                }
12696                            }
12697                        })
12698                        .ok();
12699                }),
12700            );
12701        })?;
12702        Ok(())
12703    }
12704
12705    fn take_text_document_sync_options(
12706        capabilities: &mut lsp::ServerCapabilities,
12707    ) -> lsp::TextDocumentSyncOptions {
12708        match capabilities.text_document_sync.take() {
12709            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12710            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12711                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12712                sync_options.change = Some(sync_kind);
12713                sync_options
12714            }
12715            None => lsp::TextDocumentSyncOptions::default(),
12716        }
12717    }
12718
12719    #[cfg(any(test, feature = "test-support"))]
12720    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12721        Some(
12722            self.lsp_data
12723                .get_mut(&buffer_id)?
12724                .code_lens
12725                .take()?
12726                .update
12727                .take()?
12728                .1,
12729        )
12730    }
12731
12732    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12733        self.downstream_client.clone()
12734    }
12735
12736    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12737        self.worktree_store.clone()
12738    }
12739
12740    /// Gets what's stored in the LSP data for the given buffer.
12741    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12742        self.lsp_data.get_mut(&buffer_id)
12743    }
12744
12745    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12746    /// new [`BufferLspData`] will be created to replace the previous state.
12747    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12748        let (buffer_id, buffer_version) =
12749            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12750        let lsp_data = self
12751            .lsp_data
12752            .entry(buffer_id)
12753            .or_insert_with(|| BufferLspData::new(buffer, cx));
12754        if buffer_version.changed_since(&lsp_data.buffer_version) {
12755            *lsp_data = BufferLspData::new(buffer, cx);
12756        }
12757        lsp_data
12758    }
12759}
12760
12761// Registration with registerOptions as null, should fallback to true.
12762// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12763fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12764    reg: lsp::Registration,
12765) -> Result<OneOf<bool, T>> {
12766    Ok(match reg.register_options {
12767        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12768        None => OneOf::Left(true),
12769    })
12770}
12771
12772fn subscribe_to_binary_statuses(
12773    languages: &Arc<LanguageRegistry>,
12774    cx: &mut Context<'_, LspStore>,
12775) -> Task<()> {
12776    let mut server_statuses = languages.language_server_binary_statuses();
12777    cx.spawn(async move |lsp_store, cx| {
12778        while let Some((server_name, binary_status)) = server_statuses.next().await {
12779            if lsp_store
12780                .update(cx, |_, cx| {
12781                    let mut message = None;
12782                    let binary_status = match binary_status {
12783                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12784                        BinaryStatus::CheckingForUpdate => {
12785                            proto::ServerBinaryStatus::CheckingForUpdate
12786                        }
12787                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12788                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12789                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12790                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12791                        BinaryStatus::Failed { error } => {
12792                            message = Some(error);
12793                            proto::ServerBinaryStatus::Failed
12794                        }
12795                    };
12796                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12797                        // Binary updates are about the binary that might not have any language server id at that point.
12798                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12799                        language_server_id: LanguageServerId(0),
12800                        name: Some(server_name),
12801                        message: proto::update_language_server::Variant::StatusUpdate(
12802                            proto::StatusUpdate {
12803                                message,
12804                                status: Some(proto::status_update::Status::Binary(
12805                                    binary_status as i32,
12806                                )),
12807                            },
12808                        ),
12809                    });
12810                })
12811                .is_err()
12812            {
12813                break;
12814            }
12815        }
12816    })
12817}
12818
12819fn lsp_workspace_diagnostics_refresh(
12820    registration_id: Option<String>,
12821    options: DiagnosticServerCapabilities,
12822    server: Arc<LanguageServer>,
12823    cx: &mut Context<'_, LspStore>,
12824) -> Option<WorkspaceRefreshTask> {
12825    let identifier = diagnostic_identifier(&options)?;
12826
12827    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12828    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12829    refresh_tx.try_send(()).ok();
12830
12831    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12832        let mut attempts = 0;
12833        let max_attempts = 50;
12834        let mut requests = 0;
12835
12836        loop {
12837            let Some(()) = refresh_rx.recv().await else {
12838                return;
12839            };
12840
12841            'request: loop {
12842                requests += 1;
12843                if attempts > max_attempts {
12844                    log::error!(
12845                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12846                    );
12847                    return;
12848                }
12849                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12850                cx.background_executor()
12851                    .timer(Duration::from_millis(backoff_millis))
12852                    .await;
12853                attempts += 1;
12854
12855                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12856                    lsp_store
12857                        .all_result_ids(server.server_id())
12858                        .into_iter()
12859                        .filter_map(|(abs_path, result_id)| {
12860                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12861                            Some(lsp::PreviousResultId {
12862                                uri,
12863                                value: result_id,
12864                            })
12865                        })
12866                        .collect()
12867                }) else {
12868                    return;
12869                };
12870
12871                let token = if let Some(identifier) = &registration_id {
12872                    format!(
12873                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{identifier}",
12874                        server.server_id(),
12875                    )
12876                } else {
12877                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12878                };
12879
12880                progress_rx.try_recv().ok();
12881                let timer =
12882                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12883                let progress = pin!(progress_rx.recv().fuse());
12884                let response_result = server
12885                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12886                        lsp::WorkspaceDiagnosticParams {
12887                            previous_result_ids,
12888                            identifier: identifier.clone(),
12889                            work_done_progress_params: Default::default(),
12890                            partial_result_params: lsp::PartialResultParams {
12891                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12892                            },
12893                        },
12894                        select(timer, progress).then(|either| match either {
12895                            Either::Left((message, ..)) => ready(message).left_future(),
12896                            Either::Right(..) => pending::<String>().right_future(),
12897                        }),
12898                    )
12899                    .await;
12900
12901                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12902                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12903                match response_result {
12904                    ConnectionResult::Timeout => {
12905                        log::error!("Timeout during workspace diagnostics pull");
12906                        continue 'request;
12907                    }
12908                    ConnectionResult::ConnectionReset => {
12909                        log::error!("Server closed a workspace diagnostics pull request");
12910                        continue 'request;
12911                    }
12912                    ConnectionResult::Result(Err(e)) => {
12913                        log::error!("Error during workspace diagnostics pull: {e:#}");
12914                        break 'request;
12915                    }
12916                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12917                        attempts = 0;
12918                        if lsp_store
12919                            .update(cx, |lsp_store, cx| {
12920                                lsp_store.apply_workspace_diagnostic_report(
12921                                    server.server_id(),
12922                                    pulled_diagnostics,
12923                                    cx,
12924                                )
12925                            })
12926                            .is_err()
12927                        {
12928                            return;
12929                        }
12930                        break 'request;
12931                    }
12932                }
12933            }
12934        }
12935    });
12936
12937    Some(WorkspaceRefreshTask {
12938        refresh_tx,
12939        progress_tx,
12940        task: workspace_query_language_server,
12941    })
12942}
12943
12944fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12945    match &options {
12946        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12947            if !diagnostic_options.workspace_diagnostics {
12948                return None;
12949            }
12950            Some(diagnostic_options.identifier.clone())
12951        }
12952        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12953            let diagnostic_options = &registration_options.diagnostic_options;
12954            if !diagnostic_options.workspace_diagnostics {
12955                return None;
12956            }
12957            Some(diagnostic_options.identifier.clone())
12958        }
12959    }
12960}
12961
12962fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12963    let CompletionSource::BufferWord {
12964        word_range,
12965        resolved,
12966    } = &mut completion.source
12967    else {
12968        return;
12969    };
12970    if *resolved {
12971        return;
12972    }
12973
12974    if completion.new_text
12975        != snapshot
12976            .text_for_range(word_range.clone())
12977            .collect::<String>()
12978    {
12979        return;
12980    }
12981
12982    let mut offset = 0;
12983    for chunk in snapshot.chunks(word_range.clone(), true) {
12984        let end_offset = offset + chunk.text.len();
12985        if let Some(highlight_id) = chunk.syntax_highlight_id {
12986            completion
12987                .label
12988                .runs
12989                .push((offset..end_offset, highlight_id));
12990        }
12991        offset = end_offset;
12992    }
12993    *resolved = true;
12994}
12995
12996impl EventEmitter<LspStoreEvent> for LspStore {}
12997
12998fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12999    hover
13000        .contents
13001        .retain(|hover_block| !hover_block.text.trim().is_empty());
13002    if hover.contents.is_empty() {
13003        None
13004    } else {
13005        Some(hover)
13006    }
13007}
13008
13009async fn populate_labels_for_completions(
13010    new_completions: Vec<CoreCompletion>,
13011    language: Option<Arc<Language>>,
13012    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13013) -> Vec<Completion> {
13014    let lsp_completions = new_completions
13015        .iter()
13016        .filter_map(|new_completion| {
13017            new_completion
13018                .source
13019                .lsp_completion(true)
13020                .map(|lsp_completion| lsp_completion.into_owned())
13021        })
13022        .collect::<Vec<_>>();
13023
13024    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13025        lsp_adapter
13026            .labels_for_completions(&lsp_completions, language)
13027            .await
13028            .log_err()
13029            .unwrap_or_default()
13030    } else {
13031        Vec::new()
13032    }
13033    .into_iter()
13034    .fuse();
13035
13036    let mut completions = Vec::new();
13037    for completion in new_completions {
13038        match completion.source.lsp_completion(true) {
13039            Some(lsp_completion) => {
13040                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13041
13042                let mut label = labels.next().flatten().unwrap_or_else(|| {
13043                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13044                });
13045                ensure_uniform_list_compatible_label(&mut label);
13046                completions.push(Completion {
13047                    label,
13048                    documentation,
13049                    replace_range: completion.replace_range,
13050                    new_text: completion.new_text,
13051                    insert_text_mode: lsp_completion.insert_text_mode,
13052                    source: completion.source,
13053                    icon_path: None,
13054                    confirm: None,
13055                    match_start: None,
13056                    snippet_deduplication_key: None,
13057                });
13058            }
13059            None => {
13060                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13061                ensure_uniform_list_compatible_label(&mut label);
13062                completions.push(Completion {
13063                    label,
13064                    documentation: None,
13065                    replace_range: completion.replace_range,
13066                    new_text: completion.new_text,
13067                    source: completion.source,
13068                    insert_text_mode: None,
13069                    icon_path: None,
13070                    confirm: None,
13071                    match_start: None,
13072                    snippet_deduplication_key: None,
13073                });
13074            }
13075        }
13076    }
13077    completions
13078}
13079
13080#[derive(Debug)]
13081pub enum LanguageServerToQuery {
13082    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13083    FirstCapable,
13084    /// Query a specific language server.
13085    Other(LanguageServerId),
13086}
13087
13088#[derive(Default)]
13089struct RenamePathsWatchedForServer {
13090    did_rename: Vec<RenameActionPredicate>,
13091    will_rename: Vec<RenameActionPredicate>,
13092}
13093
13094impl RenamePathsWatchedForServer {
13095    fn with_did_rename_patterns(
13096        mut self,
13097        did_rename: Option<&FileOperationRegistrationOptions>,
13098    ) -> Self {
13099        if let Some(did_rename) = did_rename {
13100            self.did_rename = did_rename
13101                .filters
13102                .iter()
13103                .filter_map(|filter| filter.try_into().log_err())
13104                .collect();
13105        }
13106        self
13107    }
13108    fn with_will_rename_patterns(
13109        mut self,
13110        will_rename: Option<&FileOperationRegistrationOptions>,
13111    ) -> Self {
13112        if let Some(will_rename) = will_rename {
13113            self.will_rename = will_rename
13114                .filters
13115                .iter()
13116                .filter_map(|filter| filter.try_into().log_err())
13117                .collect();
13118        }
13119        self
13120    }
13121
13122    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13123        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13124    }
13125    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13126        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13127    }
13128}
13129
13130impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13131    type Error = globset::Error;
13132    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13133        Ok(Self {
13134            kind: ops.pattern.matches.clone(),
13135            glob: GlobBuilder::new(&ops.pattern.glob)
13136                .case_insensitive(
13137                    ops.pattern
13138                        .options
13139                        .as_ref()
13140                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13141                )
13142                .build()?
13143                .compile_matcher(),
13144        })
13145    }
13146}
13147struct RenameActionPredicate {
13148    glob: GlobMatcher,
13149    kind: Option<FileOperationPatternKind>,
13150}
13151
13152impl RenameActionPredicate {
13153    // Returns true if language server should be notified
13154    fn eval(&self, path: &str, is_dir: bool) -> bool {
13155        self.kind.as_ref().is_none_or(|kind| {
13156            let expected_kind = if is_dir {
13157                FileOperationPatternKind::Folder
13158            } else {
13159                FileOperationPatternKind::File
13160            };
13161            kind == &expected_kind
13162        }) && self.glob.is_match(path)
13163    }
13164}
13165
13166#[derive(Default)]
13167struct LanguageServerWatchedPaths {
13168    worktree_paths: HashMap<WorktreeId, GlobSet>,
13169    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13170}
13171
13172#[derive(Default)]
13173struct LanguageServerWatchedPathsBuilder {
13174    worktree_paths: HashMap<WorktreeId, GlobSet>,
13175    abs_paths: HashMap<Arc<Path>, GlobSet>,
13176}
13177
13178impl LanguageServerWatchedPathsBuilder {
13179    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13180        self.worktree_paths.insert(worktree_id, glob_set);
13181    }
13182    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13183        self.abs_paths.insert(path, glob_set);
13184    }
13185    fn build(
13186        self,
13187        fs: Arc<dyn Fs>,
13188        language_server_id: LanguageServerId,
13189        cx: &mut Context<LspStore>,
13190    ) -> LanguageServerWatchedPaths {
13191        let lsp_store = cx.weak_entity();
13192
13193        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13194        let abs_paths = self
13195            .abs_paths
13196            .into_iter()
13197            .map(|(abs_path, globset)| {
13198                let task = cx.spawn({
13199                    let abs_path = abs_path.clone();
13200                    let fs = fs.clone();
13201
13202                    let lsp_store = lsp_store.clone();
13203                    async move |_, cx| {
13204                        maybe!(async move {
13205                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13206                            while let Some(update) = push_updates.0.next().await {
13207                                let action = lsp_store
13208                                    .update(cx, |this, _| {
13209                                        let Some(local) = this.as_local() else {
13210                                            return ControlFlow::Break(());
13211                                        };
13212                                        let Some(watcher) = local
13213                                            .language_server_watched_paths
13214                                            .get(&language_server_id)
13215                                        else {
13216                                            return ControlFlow::Break(());
13217                                        };
13218                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13219                                            "Watched abs path is not registered with a watcher",
13220                                        );
13221                                        let matching_entries = update
13222                                            .into_iter()
13223                                            .filter(|event| globs.is_match(&event.path))
13224                                            .collect::<Vec<_>>();
13225                                        this.lsp_notify_abs_paths_changed(
13226                                            language_server_id,
13227                                            matching_entries,
13228                                        );
13229                                        ControlFlow::Continue(())
13230                                    })
13231                                    .ok()?;
13232
13233                                if action.is_break() {
13234                                    break;
13235                                }
13236                            }
13237                            Some(())
13238                        })
13239                        .await;
13240                    }
13241                });
13242                (abs_path, (globset, task))
13243            })
13244            .collect();
13245        LanguageServerWatchedPaths {
13246            worktree_paths: self.worktree_paths,
13247            abs_paths,
13248        }
13249    }
13250}
13251
13252struct LspBufferSnapshot {
13253    version: i32,
13254    snapshot: TextBufferSnapshot,
13255}
13256
13257/// A prompt requested by LSP server.
13258#[derive(Clone, Debug)]
13259pub struct LanguageServerPromptRequest {
13260    pub level: PromptLevel,
13261    pub message: String,
13262    pub actions: Vec<MessageActionItem>,
13263    pub lsp_name: String,
13264    pub(crate) response_channel: Sender<MessageActionItem>,
13265}
13266
13267impl LanguageServerPromptRequest {
13268    pub async fn respond(self, index: usize) -> Option<()> {
13269        if let Some(response) = self.actions.into_iter().nth(index) {
13270            self.response_channel.send(response).await.ok()
13271        } else {
13272            None
13273        }
13274    }
13275}
13276impl PartialEq for LanguageServerPromptRequest {
13277    fn eq(&self, other: &Self) -> bool {
13278        self.message == other.message && self.actions == other.actions
13279    }
13280}
13281
13282#[derive(Clone, Debug, PartialEq)]
13283pub enum LanguageServerLogType {
13284    Log(MessageType),
13285    Trace { verbose_info: Option<String> },
13286    Rpc { received: bool },
13287}
13288
13289impl LanguageServerLogType {
13290    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13291        match self {
13292            Self::Log(log_type) => {
13293                use proto::log_message::LogLevel;
13294                let level = match *log_type {
13295                    MessageType::ERROR => LogLevel::Error,
13296                    MessageType::WARNING => LogLevel::Warning,
13297                    MessageType::INFO => LogLevel::Info,
13298                    MessageType::LOG => LogLevel::Log,
13299                    other => {
13300                        log::warn!("Unknown lsp log message type: {other:?}");
13301                        LogLevel::Log
13302                    }
13303                };
13304                proto::language_server_log::LogType::Log(proto::LogMessage {
13305                    level: level as i32,
13306                })
13307            }
13308            Self::Trace { verbose_info } => {
13309                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13310                    verbose_info: verbose_info.to_owned(),
13311                })
13312            }
13313            Self::Rpc { received } => {
13314                let kind = if *received {
13315                    proto::rpc_message::Kind::Received
13316                } else {
13317                    proto::rpc_message::Kind::Sent
13318                };
13319                let kind = kind as i32;
13320                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13321            }
13322        }
13323    }
13324
13325    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13326        use proto::log_message::LogLevel;
13327        use proto::rpc_message;
13328        match log_type {
13329            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13330                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13331                    LogLevel::Error => MessageType::ERROR,
13332                    LogLevel::Warning => MessageType::WARNING,
13333                    LogLevel::Info => MessageType::INFO,
13334                    LogLevel::Log => MessageType::LOG,
13335                },
13336            ),
13337            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13338                verbose_info: trace_message.verbose_info,
13339            },
13340            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13341                received: match rpc_message::Kind::from_i32(message.kind)
13342                    .unwrap_or(rpc_message::Kind::Received)
13343                {
13344                    rpc_message::Kind::Received => true,
13345                    rpc_message::Kind::Sent => false,
13346                },
13347            },
13348        }
13349    }
13350}
13351
13352pub struct WorkspaceRefreshTask {
13353    refresh_tx: mpsc::Sender<()>,
13354    progress_tx: mpsc::Sender<()>,
13355    #[allow(dead_code)]
13356    task: Task<()>,
13357}
13358
13359pub enum LanguageServerState {
13360    Starting {
13361        startup: Task<Option<Arc<LanguageServer>>>,
13362        /// List of language servers that will be added to the workspace once it's initialization completes.
13363        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13364    },
13365
13366    Running {
13367        adapter: Arc<CachedLspAdapter>,
13368        server: Arc<LanguageServer>,
13369        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13370        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13371    },
13372}
13373
13374impl LanguageServerState {
13375    fn add_workspace_folder(&self, uri: Uri) {
13376        match self {
13377            LanguageServerState::Starting {
13378                pending_workspace_folders,
13379                ..
13380            } => {
13381                pending_workspace_folders.lock().insert(uri);
13382            }
13383            LanguageServerState::Running { server, .. } => {
13384                server.add_workspace_folder(uri);
13385            }
13386        }
13387    }
13388    fn _remove_workspace_folder(&self, uri: Uri) {
13389        match self {
13390            LanguageServerState::Starting {
13391                pending_workspace_folders,
13392                ..
13393            } => {
13394                pending_workspace_folders.lock().remove(&uri);
13395            }
13396            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13397        }
13398    }
13399}
13400
13401impl std::fmt::Debug for LanguageServerState {
13402    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13403        match self {
13404            LanguageServerState::Starting { .. } => {
13405                f.debug_struct("LanguageServerState::Starting").finish()
13406            }
13407            LanguageServerState::Running { .. } => {
13408                f.debug_struct("LanguageServerState::Running").finish()
13409            }
13410        }
13411    }
13412}
13413
13414#[derive(Clone, Debug, Serialize)]
13415pub struct LanguageServerProgress {
13416    pub is_disk_based_diagnostics_progress: bool,
13417    pub is_cancellable: bool,
13418    pub title: Option<String>,
13419    pub message: Option<String>,
13420    pub percentage: Option<usize>,
13421    #[serde(skip_serializing)]
13422    pub last_update_at: Instant,
13423}
13424
13425#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13426pub struct DiagnosticSummary {
13427    pub error_count: usize,
13428    pub warning_count: usize,
13429}
13430
13431impl DiagnosticSummary {
13432    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13433        let mut this = Self {
13434            error_count: 0,
13435            warning_count: 0,
13436        };
13437
13438        for entry in diagnostics {
13439            if entry.diagnostic.is_primary {
13440                match entry.diagnostic.severity {
13441                    DiagnosticSeverity::ERROR => this.error_count += 1,
13442                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13443                    _ => {}
13444                }
13445            }
13446        }
13447
13448        this
13449    }
13450
13451    pub fn is_empty(&self) -> bool {
13452        self.error_count == 0 && self.warning_count == 0
13453    }
13454
13455    pub fn to_proto(
13456        self,
13457        language_server_id: LanguageServerId,
13458        path: &RelPath,
13459    ) -> proto::DiagnosticSummary {
13460        proto::DiagnosticSummary {
13461            path: path.to_proto(),
13462            language_server_id: language_server_id.0 as u64,
13463            error_count: self.error_count as u32,
13464            warning_count: self.warning_count as u32,
13465        }
13466    }
13467}
13468
13469#[derive(Clone, Debug)]
13470pub enum CompletionDocumentation {
13471    /// There is no documentation for this completion.
13472    Undocumented,
13473    /// A single line of documentation.
13474    SingleLine(SharedString),
13475    /// Multiple lines of plain text documentation.
13476    MultiLinePlainText(SharedString),
13477    /// Markdown documentation.
13478    MultiLineMarkdown(SharedString),
13479    /// Both single line and multiple lines of plain text documentation.
13480    SingleLineAndMultiLinePlainText {
13481        single_line: SharedString,
13482        plain_text: Option<SharedString>,
13483    },
13484}
13485
13486impl CompletionDocumentation {
13487    #[cfg(any(test, feature = "test-support"))]
13488    pub fn text(&self) -> SharedString {
13489        match self {
13490            CompletionDocumentation::Undocumented => "".into(),
13491            CompletionDocumentation::SingleLine(s) => s.clone(),
13492            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13493            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13494            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13495                single_line.clone()
13496            }
13497        }
13498    }
13499}
13500
13501impl From<lsp::Documentation> for CompletionDocumentation {
13502    fn from(docs: lsp::Documentation) -> Self {
13503        match docs {
13504            lsp::Documentation::String(text) => {
13505                if text.lines().count() <= 1 {
13506                    CompletionDocumentation::SingleLine(text.into())
13507                } else {
13508                    CompletionDocumentation::MultiLinePlainText(text.into())
13509                }
13510            }
13511
13512            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13513                lsp::MarkupKind::PlainText => {
13514                    if value.lines().count() <= 1 {
13515                        CompletionDocumentation::SingleLine(value.into())
13516                    } else {
13517                        CompletionDocumentation::MultiLinePlainText(value.into())
13518                    }
13519                }
13520
13521                lsp::MarkupKind::Markdown => {
13522                    CompletionDocumentation::MultiLineMarkdown(value.into())
13523                }
13524            },
13525        }
13526    }
13527}
13528
13529pub enum ResolvedHint {
13530    Resolved(InlayHint),
13531    Resolving(Shared<Task<()>>),
13532}
13533
13534fn glob_literal_prefix(glob: &Path) -> PathBuf {
13535    glob.components()
13536        .take_while(|component| match component {
13537            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13538            _ => true,
13539        })
13540        .collect()
13541}
13542
13543pub struct SshLspAdapter {
13544    name: LanguageServerName,
13545    binary: LanguageServerBinary,
13546    initialization_options: Option<String>,
13547    code_action_kinds: Option<Vec<CodeActionKind>>,
13548}
13549
13550impl SshLspAdapter {
13551    pub fn new(
13552        name: LanguageServerName,
13553        binary: LanguageServerBinary,
13554        initialization_options: Option<String>,
13555        code_action_kinds: Option<String>,
13556    ) -> Self {
13557        Self {
13558            name,
13559            binary,
13560            initialization_options,
13561            code_action_kinds: code_action_kinds
13562                .as_ref()
13563                .and_then(|c| serde_json::from_str(c).ok()),
13564        }
13565    }
13566}
13567
13568impl LspInstaller for SshLspAdapter {
13569    type BinaryVersion = ();
13570    async fn check_if_user_installed(
13571        &self,
13572        _: &dyn LspAdapterDelegate,
13573        _: Option<Toolchain>,
13574        _: &AsyncApp,
13575    ) -> Option<LanguageServerBinary> {
13576        Some(self.binary.clone())
13577    }
13578
13579    async fn cached_server_binary(
13580        &self,
13581        _: PathBuf,
13582        _: &dyn LspAdapterDelegate,
13583    ) -> Option<LanguageServerBinary> {
13584        None
13585    }
13586
13587    async fn fetch_latest_server_version(
13588        &self,
13589        _: &dyn LspAdapterDelegate,
13590        _: bool,
13591        _: &mut AsyncApp,
13592    ) -> Result<()> {
13593        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13594    }
13595
13596    async fn fetch_server_binary(
13597        &self,
13598        _: (),
13599        _: PathBuf,
13600        _: &dyn LspAdapterDelegate,
13601    ) -> Result<LanguageServerBinary> {
13602        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13603    }
13604}
13605
13606#[async_trait(?Send)]
13607impl LspAdapter for SshLspAdapter {
13608    fn name(&self) -> LanguageServerName {
13609        self.name.clone()
13610    }
13611
13612    async fn initialization_options(
13613        self: Arc<Self>,
13614        _: &Arc<dyn LspAdapterDelegate>,
13615    ) -> Result<Option<serde_json::Value>> {
13616        let Some(options) = &self.initialization_options else {
13617            return Ok(None);
13618        };
13619        let result = serde_json::from_str(options)?;
13620        Ok(result)
13621    }
13622
13623    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13624        self.code_action_kinds.clone()
13625    }
13626}
13627
13628pub fn language_server_settings<'a>(
13629    delegate: &'a dyn LspAdapterDelegate,
13630    language: &LanguageServerName,
13631    cx: &'a App,
13632) -> Option<&'a LspSettings> {
13633    language_server_settings_for(
13634        SettingsLocation {
13635            worktree_id: delegate.worktree_id(),
13636            path: RelPath::empty(),
13637        },
13638        language,
13639        cx,
13640    )
13641}
13642
13643pub fn language_server_settings_for<'a>(
13644    location: SettingsLocation<'a>,
13645    language: &LanguageServerName,
13646    cx: &'a App,
13647) -> Option<&'a LspSettings> {
13648    ProjectSettings::get(Some(location), cx).lsp.get(language)
13649}
13650
13651pub struct LocalLspAdapterDelegate {
13652    lsp_store: WeakEntity<LspStore>,
13653    worktree: worktree::Snapshot,
13654    fs: Arc<dyn Fs>,
13655    http_client: Arc<dyn HttpClient>,
13656    language_registry: Arc<LanguageRegistry>,
13657    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13658}
13659
13660impl LocalLspAdapterDelegate {
13661    pub fn new(
13662        language_registry: Arc<LanguageRegistry>,
13663        environment: &Entity<ProjectEnvironment>,
13664        lsp_store: WeakEntity<LspStore>,
13665        worktree: &Entity<Worktree>,
13666        http_client: Arc<dyn HttpClient>,
13667        fs: Arc<dyn Fs>,
13668        cx: &mut App,
13669    ) -> Arc<Self> {
13670        let load_shell_env_task =
13671            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13672
13673        Arc::new(Self {
13674            lsp_store,
13675            worktree: worktree.read(cx).snapshot(),
13676            fs,
13677            http_client,
13678            language_registry,
13679            load_shell_env_task,
13680        })
13681    }
13682
13683    fn from_local_lsp(
13684        local: &LocalLspStore,
13685        worktree: &Entity<Worktree>,
13686        cx: &mut App,
13687    ) -> Arc<Self> {
13688        Self::new(
13689            local.languages.clone(),
13690            &local.environment,
13691            local.weak.clone(),
13692            worktree,
13693            local.http_client.clone(),
13694            local.fs.clone(),
13695            cx,
13696        )
13697    }
13698}
13699
13700#[async_trait]
13701impl LspAdapterDelegate for LocalLspAdapterDelegate {
13702    fn show_notification(&self, message: &str, cx: &mut App) {
13703        self.lsp_store
13704            .update(cx, |_, cx| {
13705                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13706            })
13707            .ok();
13708    }
13709
13710    fn http_client(&self) -> Arc<dyn HttpClient> {
13711        self.http_client.clone()
13712    }
13713
13714    fn worktree_id(&self) -> WorktreeId {
13715        self.worktree.id()
13716    }
13717
13718    fn worktree_root_path(&self) -> &Path {
13719        self.worktree.abs_path().as_ref()
13720    }
13721
13722    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13723        self.worktree.resolve_executable_path(path)
13724    }
13725
13726    async fn shell_env(&self) -> HashMap<String, String> {
13727        let task = self.load_shell_env_task.clone();
13728        task.await.unwrap_or_default()
13729    }
13730
13731    async fn npm_package_installed_version(
13732        &self,
13733        package_name: &str,
13734    ) -> Result<Option<(PathBuf, String)>> {
13735        let local_package_directory = self.worktree_root_path();
13736        let node_modules_directory = local_package_directory.join("node_modules");
13737
13738        if let Some(version) =
13739            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13740        {
13741            return Ok(Some((node_modules_directory, version)));
13742        }
13743        let Some(npm) = self.which("npm".as_ref()).await else {
13744            log::warn!(
13745                "Failed to find npm executable for {:?}",
13746                local_package_directory
13747            );
13748            return Ok(None);
13749        };
13750
13751        let env = self.shell_env().await;
13752        let output = util::command::new_smol_command(&npm)
13753            .args(["root", "-g"])
13754            .envs(env)
13755            .current_dir(local_package_directory)
13756            .output()
13757            .await?;
13758        let global_node_modules =
13759            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13760
13761        if let Some(version) =
13762            read_package_installed_version(global_node_modules.clone(), package_name).await?
13763        {
13764            return Ok(Some((global_node_modules, version)));
13765        }
13766        return Ok(None);
13767    }
13768
13769    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13770        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13771        if self.fs.is_file(&worktree_abs_path).await {
13772            worktree_abs_path.pop();
13773        }
13774
13775        let env = self.shell_env().await;
13776
13777        let shell_path = env.get("PATH").cloned();
13778
13779        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13780    }
13781
13782    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13783        let mut working_dir = self.worktree_root_path().to_path_buf();
13784        if self.fs.is_file(&working_dir).await {
13785            working_dir.pop();
13786        }
13787        let output = util::command::new_smol_command(&command.path)
13788            .args(command.arguments)
13789            .envs(command.env.clone().unwrap_or_default())
13790            .current_dir(working_dir)
13791            .output()
13792            .await?;
13793
13794        anyhow::ensure!(
13795            output.status.success(),
13796            "{}, stdout: {:?}, stderr: {:?}",
13797            output.status,
13798            String::from_utf8_lossy(&output.stdout),
13799            String::from_utf8_lossy(&output.stderr)
13800        );
13801        Ok(())
13802    }
13803
13804    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13805        self.language_registry
13806            .update_lsp_binary_status(server_name, status);
13807    }
13808
13809    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13810        self.language_registry
13811            .all_lsp_adapters()
13812            .into_iter()
13813            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13814            .collect()
13815    }
13816
13817    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13818        let dir = self.language_registry.language_server_download_dir(name)?;
13819
13820        if !dir.exists() {
13821            smol::fs::create_dir_all(&dir)
13822                .await
13823                .context("failed to create container directory")
13824                .log_err()?;
13825        }
13826
13827        Some(dir)
13828    }
13829
13830    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13831        let entry = self
13832            .worktree
13833            .entry_for_path(path)
13834            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13835        let abs_path = self.worktree.absolutize(&entry.path);
13836        self.fs.load(&abs_path).await
13837    }
13838}
13839
13840async fn populate_labels_for_symbols(
13841    symbols: Vec<CoreSymbol>,
13842    language_registry: &Arc<LanguageRegistry>,
13843    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13844    output: &mut Vec<Symbol>,
13845) {
13846    #[allow(clippy::mutable_key_type)]
13847    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13848
13849    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13850    for symbol in symbols {
13851        let Some(file_name) = symbol.path.file_name() else {
13852            continue;
13853        };
13854        let language = language_registry
13855            .load_language_for_file_path(Path::new(file_name))
13856            .await
13857            .ok()
13858            .or_else(|| {
13859                unknown_paths.insert(file_name.into());
13860                None
13861            });
13862        symbols_by_language
13863            .entry(language)
13864            .or_default()
13865            .push(symbol);
13866    }
13867
13868    for unknown_path in unknown_paths {
13869        log::info!("no language found for symbol in file {unknown_path:?}");
13870    }
13871
13872    let mut label_params = Vec::new();
13873    for (language, mut symbols) in symbols_by_language {
13874        label_params.clear();
13875        label_params.extend(
13876            symbols
13877                .iter_mut()
13878                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13879        );
13880
13881        let mut labels = Vec::new();
13882        if let Some(language) = language {
13883            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13884                language_registry
13885                    .lsp_adapters(&language.name())
13886                    .first()
13887                    .cloned()
13888            });
13889            if let Some(lsp_adapter) = lsp_adapter {
13890                labels = lsp_adapter
13891                    .labels_for_symbols(&label_params, &language)
13892                    .await
13893                    .log_err()
13894                    .unwrap_or_default();
13895            }
13896        }
13897
13898        for ((symbol, (name, _)), label) in symbols
13899            .into_iter()
13900            .zip(label_params.drain(..))
13901            .zip(labels.into_iter().chain(iter::repeat(None)))
13902        {
13903            output.push(Symbol {
13904                language_server_name: symbol.language_server_name,
13905                source_worktree_id: symbol.source_worktree_id,
13906                source_language_server_id: symbol.source_language_server_id,
13907                path: symbol.path,
13908                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13909                name,
13910                kind: symbol.kind,
13911                range: symbol.range,
13912            });
13913        }
13914    }
13915}
13916
13917fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13918    match server.capabilities().text_document_sync.as_ref()? {
13919        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13920            // Server wants didSave but didn't specify includeText.
13921            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13922            // Server doesn't want didSave at all.
13923            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13924            // Server provided SaveOptions.
13925            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13926                Some(save_options.include_text.unwrap_or(false))
13927            }
13928        },
13929        // We do not have any save info. Kind affects didChange only.
13930        lsp::TextDocumentSyncCapability::Kind(_) => None,
13931    }
13932}
13933
13934/// Completion items are displayed in a `UniformList`.
13935/// Usually, those items are single-line strings, but in LSP responses,
13936/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13937/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13938/// 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,
13939/// breaking the completions menu presentation.
13940///
13941/// 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.
13942fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13943    let mut new_text = String::with_capacity(label.text.len());
13944    let mut offset_map = vec![0; label.text.len() + 1];
13945    let mut last_char_was_space = false;
13946    let mut new_idx = 0;
13947    let chars = label.text.char_indices().fuse();
13948    let mut newlines_removed = false;
13949
13950    for (idx, c) in chars {
13951        offset_map[idx] = new_idx;
13952
13953        match c {
13954            '\n' if last_char_was_space => {
13955                newlines_removed = true;
13956            }
13957            '\t' | ' ' if last_char_was_space => {}
13958            '\n' if !last_char_was_space => {
13959                new_text.push(' ');
13960                new_idx += 1;
13961                last_char_was_space = true;
13962                newlines_removed = true;
13963            }
13964            ' ' | '\t' => {
13965                new_text.push(' ');
13966                new_idx += 1;
13967                last_char_was_space = true;
13968            }
13969            _ => {
13970                new_text.push(c);
13971                new_idx += c.len_utf8();
13972                last_char_was_space = false;
13973            }
13974        }
13975    }
13976    offset_map[label.text.len()] = new_idx;
13977
13978    // Only modify the label if newlines were removed.
13979    if !newlines_removed {
13980        return;
13981    }
13982
13983    let last_index = new_idx;
13984    let mut run_ranges_errors = Vec::new();
13985    label.runs.retain_mut(|(range, _)| {
13986        match offset_map.get(range.start) {
13987            Some(&start) => range.start = start,
13988            None => {
13989                run_ranges_errors.push(range.clone());
13990                return false;
13991            }
13992        }
13993
13994        match offset_map.get(range.end) {
13995            Some(&end) => range.end = end,
13996            None => {
13997                run_ranges_errors.push(range.clone());
13998                range.end = last_index;
13999            }
14000        }
14001        true
14002    });
14003    if !run_ranges_errors.is_empty() {
14004        log::error!(
14005            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14006            label.text
14007        );
14008    }
14009
14010    let mut wrong_filter_range = None;
14011    if label.filter_range == (0..label.text.len()) {
14012        label.filter_range = 0..new_text.len();
14013    } else {
14014        let mut original_filter_range = Some(label.filter_range.clone());
14015        match offset_map.get(label.filter_range.start) {
14016            Some(&start) => label.filter_range.start = start,
14017            None => {
14018                wrong_filter_range = original_filter_range.take();
14019                label.filter_range.start = last_index;
14020            }
14021        }
14022
14023        match offset_map.get(label.filter_range.end) {
14024            Some(&end) => label.filter_range.end = end,
14025            None => {
14026                wrong_filter_range = original_filter_range.take();
14027                label.filter_range.end = last_index;
14028            }
14029        }
14030    }
14031    if let Some(wrong_filter_range) = wrong_filter_range {
14032        log::error!(
14033            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14034            label.text
14035        );
14036    }
14037
14038    label.text = new_text;
14039}
14040
14041#[cfg(test)]
14042mod tests {
14043    use language::HighlightId;
14044
14045    use super::*;
14046
14047    #[test]
14048    fn test_glob_literal_prefix() {
14049        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14050        assert_eq!(
14051            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14052            Path::new("node_modules")
14053        );
14054        assert_eq!(
14055            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14056            Path::new("foo")
14057        );
14058        assert_eq!(
14059            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14060            Path::new("foo/bar/baz.js")
14061        );
14062
14063        #[cfg(target_os = "windows")]
14064        {
14065            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14066            assert_eq!(
14067                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14068                Path::new("node_modules")
14069            );
14070            assert_eq!(
14071                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14072                Path::new("foo")
14073            );
14074            assert_eq!(
14075                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14076                Path::new("foo/bar/baz.js")
14077            );
14078        }
14079    }
14080
14081    #[test]
14082    fn test_multi_len_chars_normalization() {
14083        let mut label = CodeLabel::new(
14084            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14085            0..6,
14086            vec![(0..6, HighlightId(1))],
14087        );
14088        ensure_uniform_list_compatible_label(&mut label);
14089        assert_eq!(
14090            label,
14091            CodeLabel::new(
14092                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14093                0..6,
14094                vec![(0..6, HighlightId(1))],
14095            )
14096        );
14097    }
14098}