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
 4293                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4294                                        if let Some(local) = this.as_local_mut() {
 4295                                            local.reset_buffer(&buffer, &f, cx);
 4296
 4297                                            if local
 4298                                                .registered_buffers
 4299                                                .contains_key(&buffer.read(cx).remote_id())
 4300                                                && let Some(file_url) =
 4301                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4302                                            {
 4303                                                local.unregister_buffer_from_language_servers(
 4304                                                    &buffer, &file_url, cx,
 4305                                                );
 4306                                            }
 4307                                        }
 4308                                    }
 4309                                }
 4310                            });
 4311                        })
 4312                        .ok();
 4313                    }
 4314
 4315                    this.update(cx, |this, cx| {
 4316                        let mut plain_text_buffers = Vec::new();
 4317                        let mut buffers_with_unknown_injections = Vec::new();
 4318                        for handle in this.buffer_store.read(cx).buffers() {
 4319                            let buffer = handle.read(cx);
 4320                            if buffer.language().is_none()
 4321                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4322                            {
 4323                                plain_text_buffers.push(handle);
 4324                            } else if buffer.contains_unknown_injections() {
 4325                                buffers_with_unknown_injections.push(handle);
 4326                            }
 4327                        }
 4328
 4329                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4330                        // and reused later in the invisible worktrees.
 4331                        plain_text_buffers.sort_by_key(|buffer| {
 4332                            Reverse(
 4333                                File::from_dyn(buffer.read(cx).file())
 4334                                    .map(|file| file.worktree.read(cx).is_visible()),
 4335                            )
 4336                        });
 4337
 4338                        for buffer in plain_text_buffers {
 4339                            this.detect_language_for_buffer(&buffer, cx);
 4340                            if let Some(local) = this.as_local_mut() {
 4341                                local.initialize_buffer(&buffer, cx);
 4342                                if local
 4343                                    .registered_buffers
 4344                                    .contains_key(&buffer.read(cx).remote_id())
 4345                                {
 4346                                    local.register_buffer_with_language_servers(
 4347                                        &buffer,
 4348                                        HashSet::default(),
 4349                                        cx,
 4350                                    );
 4351                                }
 4352                            }
 4353                        }
 4354
 4355                        for buffer in buffers_with_unknown_injections {
 4356                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4357                        }
 4358                    })
 4359                    .ok();
 4360                }
 4361            }
 4362        })
 4363    }
 4364
 4365    fn detect_language_for_buffer(
 4366        &mut self,
 4367        buffer_handle: &Entity<Buffer>,
 4368        cx: &mut Context<Self>,
 4369    ) -> Option<language::AvailableLanguage> {
 4370        // If the buffer has a language, set it and start the language server if we haven't already.
 4371        let buffer = buffer_handle.read(cx);
 4372        let file = buffer.file()?;
 4373
 4374        let content = buffer.as_rope();
 4375        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4376        if let Some(available_language) = &available_language {
 4377            if let Some(Ok(Ok(new_language))) = self
 4378                .languages
 4379                .load_language(available_language)
 4380                .now_or_never()
 4381            {
 4382                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4383            }
 4384        } else {
 4385            cx.emit(LspStoreEvent::LanguageDetected {
 4386                buffer: buffer_handle.clone(),
 4387                new_language: None,
 4388            });
 4389        }
 4390
 4391        available_language
 4392    }
 4393
 4394    pub(crate) fn set_language_for_buffer(
 4395        &mut self,
 4396        buffer_entity: &Entity<Buffer>,
 4397        new_language: Arc<Language>,
 4398        cx: &mut Context<Self>,
 4399    ) {
 4400        let buffer = buffer_entity.read(cx);
 4401        let buffer_file = buffer.file().cloned();
 4402        let buffer_id = buffer.remote_id();
 4403        if let Some(local_store) = self.as_local_mut()
 4404            && local_store.registered_buffers.contains_key(&buffer_id)
 4405            && let Some(abs_path) =
 4406                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4407            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4408        {
 4409            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4410        }
 4411        buffer_entity.update(cx, |buffer, cx| {
 4412            if buffer
 4413                .language()
 4414                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4415            {
 4416                buffer.set_language(Some(new_language.clone()), cx);
 4417            }
 4418        });
 4419
 4420        let settings =
 4421            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4422        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4423
 4424        let worktree_id = if let Some(file) = buffer_file {
 4425            let worktree = file.worktree.clone();
 4426
 4427            if let Some(local) = self.as_local_mut()
 4428                && local.registered_buffers.contains_key(&buffer_id)
 4429            {
 4430                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4431            }
 4432            Some(worktree.read(cx).id())
 4433        } else {
 4434            None
 4435        };
 4436
 4437        if settings.prettier.allowed
 4438            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4439        {
 4440            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4441            if let Some(prettier_store) = prettier_store {
 4442                prettier_store.update(cx, |prettier_store, cx| {
 4443                    prettier_store.install_default_prettier(
 4444                        worktree_id,
 4445                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4446                        cx,
 4447                    )
 4448                })
 4449            }
 4450        }
 4451
 4452        cx.emit(LspStoreEvent::LanguageDetected {
 4453            buffer: buffer_entity.clone(),
 4454            new_language: Some(new_language),
 4455        })
 4456    }
 4457
 4458    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4459        self.buffer_store.clone()
 4460    }
 4461
 4462    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4463        self.active_entry = active_entry;
 4464    }
 4465
 4466    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4467        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4468            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4469        {
 4470            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4471                summaries
 4472                    .iter()
 4473                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4474            });
 4475            if let Some(summary) = summaries.next() {
 4476                client
 4477                    .send(proto::UpdateDiagnosticSummary {
 4478                        project_id: downstream_project_id,
 4479                        worktree_id: worktree.id().to_proto(),
 4480                        summary: Some(summary),
 4481                        more_summaries: summaries.collect(),
 4482                    })
 4483                    .log_err();
 4484            }
 4485        }
 4486    }
 4487
 4488    fn is_capable_for_proto_request<R>(
 4489        &self,
 4490        buffer: &Entity<Buffer>,
 4491        request: &R,
 4492        cx: &App,
 4493    ) -> bool
 4494    where
 4495        R: LspCommand,
 4496    {
 4497        self.check_if_capable_for_proto_request(
 4498            buffer,
 4499            |capabilities| {
 4500                request.check_capabilities(AdapterServerCapabilities {
 4501                    server_capabilities: capabilities.clone(),
 4502                    code_action_kinds: None,
 4503                })
 4504            },
 4505            cx,
 4506        )
 4507    }
 4508
 4509    fn check_if_capable_for_proto_request<F>(
 4510        &self,
 4511        buffer: &Entity<Buffer>,
 4512        check: F,
 4513        cx: &App,
 4514    ) -> bool
 4515    where
 4516        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4517    {
 4518        let Some(language) = buffer.read(cx).language().cloned() else {
 4519            return false;
 4520        };
 4521        let relevant_language_servers = self
 4522            .languages
 4523            .lsp_adapters(&language.name())
 4524            .into_iter()
 4525            .map(|lsp_adapter| lsp_adapter.name())
 4526            .collect::<HashSet<_>>();
 4527        self.language_server_statuses
 4528            .iter()
 4529            .filter_map(|(server_id, server_status)| {
 4530                relevant_language_servers
 4531                    .contains(&server_status.name)
 4532                    .then_some(server_id)
 4533            })
 4534            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4535            .any(check)
 4536    }
 4537
 4538    fn all_capable_for_proto_request<F>(
 4539        &self,
 4540        buffer: &Entity<Buffer>,
 4541        mut check: F,
 4542        cx: &App,
 4543    ) -> Vec<lsp::LanguageServerId>
 4544    where
 4545        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4546    {
 4547        let Some(language) = buffer.read(cx).language().cloned() else {
 4548            return Vec::default();
 4549        };
 4550        let relevant_language_servers = self
 4551            .languages
 4552            .lsp_adapters(&language.name())
 4553            .into_iter()
 4554            .map(|lsp_adapter| lsp_adapter.name())
 4555            .collect::<HashSet<_>>();
 4556        self.language_server_statuses
 4557            .iter()
 4558            .filter_map(|(server_id, server_status)| {
 4559                relevant_language_servers
 4560                    .contains(&server_status.name)
 4561                    .then_some((server_id, &server_status.name))
 4562            })
 4563            .filter_map(|(server_id, server_name)| {
 4564                self.lsp_server_capabilities
 4565                    .get(server_id)
 4566                    .map(|c| (server_id, server_name, c))
 4567            })
 4568            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4569            .map(|(server_id, _, _)| *server_id)
 4570            .collect()
 4571    }
 4572
 4573    pub fn request_lsp<R>(
 4574        &mut self,
 4575        buffer: Entity<Buffer>,
 4576        server: LanguageServerToQuery,
 4577        request: R,
 4578        cx: &mut Context<Self>,
 4579    ) -> Task<Result<R::Response>>
 4580    where
 4581        R: LspCommand,
 4582        <R::LspRequest as lsp::request::Request>::Result: Send,
 4583        <R::LspRequest as lsp::request::Request>::Params: Send,
 4584    {
 4585        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4586            return self.send_lsp_proto_request(
 4587                buffer,
 4588                upstream_client,
 4589                upstream_project_id,
 4590                request,
 4591                cx,
 4592            );
 4593        }
 4594
 4595        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4596            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4597                local
 4598                    .language_servers_for_buffer(buffer, cx)
 4599                    .find(|(_, server)| {
 4600                        request.check_capabilities(server.adapter_server_capabilities())
 4601                    })
 4602                    .map(|(_, server)| server.clone())
 4603            }),
 4604            LanguageServerToQuery::Other(id) => self
 4605                .language_server_for_local_buffer(buffer, id, cx)
 4606                .and_then(|(_, server)| {
 4607                    request
 4608                        .check_capabilities(server.adapter_server_capabilities())
 4609                        .then(|| Arc::clone(server))
 4610                }),
 4611        }) else {
 4612            return Task::ready(Ok(Default::default()));
 4613        };
 4614
 4615        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4616
 4617        let Some(file) = file else {
 4618            return Task::ready(Ok(Default::default()));
 4619        };
 4620
 4621        let lsp_params = match request.to_lsp_params_or_response(
 4622            &file.abs_path(cx),
 4623            buffer.read(cx),
 4624            &language_server,
 4625            cx,
 4626        ) {
 4627            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4628            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4629            Err(err) => {
 4630                let message = format!(
 4631                    "{} via {} failed: {}",
 4632                    request.display_name(),
 4633                    language_server.name(),
 4634                    err
 4635                );
 4636                // rust-analyzer likes to error with this when its still loading up
 4637                if !message.ends_with("content modified") {
 4638                    log::warn!("{message}");
 4639                }
 4640                return Task::ready(Err(anyhow!(message)));
 4641            }
 4642        };
 4643
 4644        let status = request.status();
 4645        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4646            return Task::ready(Ok(Default::default()));
 4647        }
 4648        cx.spawn(async move |this, cx| {
 4649            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4650
 4651            let id = lsp_request.id();
 4652            let _cleanup = if status.is_some() {
 4653                cx.update(|cx| {
 4654                    this.update(cx, |this, cx| {
 4655                        this.on_lsp_work_start(
 4656                            language_server.server_id(),
 4657                            ProgressToken::Number(id),
 4658                            LanguageServerProgress {
 4659                                is_disk_based_diagnostics_progress: false,
 4660                                is_cancellable: false,
 4661                                title: None,
 4662                                message: status.clone(),
 4663                                percentage: None,
 4664                                last_update_at: cx.background_executor().now(),
 4665                            },
 4666                            cx,
 4667                        );
 4668                    })
 4669                })
 4670                .log_err();
 4671
 4672                Some(defer(|| {
 4673                    cx.update(|cx| {
 4674                        this.update(cx, |this, cx| {
 4675                            this.on_lsp_work_end(
 4676                                language_server.server_id(),
 4677                                ProgressToken::Number(id),
 4678                                cx,
 4679                            );
 4680                        })
 4681                    })
 4682                    .log_err();
 4683                }))
 4684            } else {
 4685                None
 4686            };
 4687
 4688            let result = lsp_request.await.into_response();
 4689
 4690            let response = result.map_err(|err| {
 4691                let message = format!(
 4692                    "{} via {} failed: {}",
 4693                    request.display_name(),
 4694                    language_server.name(),
 4695                    err
 4696                );
 4697                // rust-analyzer likes to error with this when its still loading up
 4698                if !message.ends_with("content modified") {
 4699                    log::warn!("{message}");
 4700                }
 4701                anyhow::anyhow!(message)
 4702            })?;
 4703
 4704            request
 4705                .response_from_lsp(
 4706                    response,
 4707                    this.upgrade().context("no app context")?,
 4708                    buffer,
 4709                    language_server.server_id(),
 4710                    cx.clone(),
 4711                )
 4712                .await
 4713        })
 4714    }
 4715
 4716    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4717        let mut language_formatters_to_check = Vec::new();
 4718        for buffer in self.buffer_store.read(cx).buffers() {
 4719            let buffer = buffer.read(cx);
 4720            let buffer_file = File::from_dyn(buffer.file());
 4721            let buffer_language = buffer.language();
 4722            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4723            if buffer_language.is_some() {
 4724                language_formatters_to_check.push((
 4725                    buffer_file.map(|f| f.worktree_id(cx)),
 4726                    settings.into_owned(),
 4727                ));
 4728            }
 4729        }
 4730
 4731        self.request_workspace_config_refresh();
 4732
 4733        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4734            prettier_store.update(cx, |prettier_store, cx| {
 4735                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4736            })
 4737        }
 4738
 4739        cx.notify();
 4740    }
 4741
 4742    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4743        let buffer_store = self.buffer_store.clone();
 4744        let Some(local) = self.as_local_mut() else {
 4745            return;
 4746        };
 4747        let mut adapters = BTreeMap::default();
 4748        let get_adapter = {
 4749            let languages = local.languages.clone();
 4750            let environment = local.environment.clone();
 4751            let weak = local.weak.clone();
 4752            let worktree_store = local.worktree_store.clone();
 4753            let http_client = local.http_client.clone();
 4754            let fs = local.fs.clone();
 4755            move |worktree_id, cx: &mut App| {
 4756                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4757                Some(LocalLspAdapterDelegate::new(
 4758                    languages.clone(),
 4759                    &environment,
 4760                    weak.clone(),
 4761                    &worktree,
 4762                    http_client.clone(),
 4763                    fs.clone(),
 4764                    cx,
 4765                ))
 4766            }
 4767        };
 4768
 4769        let mut messages_to_report = Vec::new();
 4770        let (new_tree, to_stop) = {
 4771            let mut rebase = local.lsp_tree.rebase();
 4772            let buffers = buffer_store
 4773                .read(cx)
 4774                .buffers()
 4775                .filter_map(|buffer| {
 4776                    let raw_buffer = buffer.read(cx);
 4777                    if !local
 4778                        .registered_buffers
 4779                        .contains_key(&raw_buffer.remote_id())
 4780                    {
 4781                        return None;
 4782                    }
 4783                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4784                    let language = raw_buffer.language().cloned()?;
 4785                    Some((file, language, raw_buffer.remote_id()))
 4786                })
 4787                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4788            for (file, language, buffer_id) in buffers {
 4789                let worktree_id = file.worktree_id(cx);
 4790                let Some(worktree) = local
 4791                    .worktree_store
 4792                    .read(cx)
 4793                    .worktree_for_id(worktree_id, cx)
 4794                else {
 4795                    continue;
 4796                };
 4797
 4798                if let Some((_, apply)) = local.reuse_existing_language_server(
 4799                    rebase.server_tree(),
 4800                    &worktree,
 4801                    &language.name(),
 4802                    cx,
 4803                ) {
 4804                    (apply)(rebase.server_tree());
 4805                } else if let Some(lsp_delegate) = adapters
 4806                    .entry(worktree_id)
 4807                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4808                    .clone()
 4809                {
 4810                    let delegate =
 4811                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4812                    let path = file
 4813                        .path()
 4814                        .parent()
 4815                        .map(Arc::from)
 4816                        .unwrap_or_else(|| file.path().clone());
 4817                    let worktree_path = ProjectPath { worktree_id, path };
 4818                    let abs_path = file.abs_path(cx);
 4819                    let nodes = rebase
 4820                        .walk(
 4821                            worktree_path,
 4822                            language.name(),
 4823                            language.manifest(),
 4824                            delegate.clone(),
 4825                            cx,
 4826                        )
 4827                        .collect::<Vec<_>>();
 4828                    for node in nodes {
 4829                        let server_id = node.server_id_or_init(|disposition| {
 4830                            let path = &disposition.path;
 4831                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4832                            let key = LanguageServerSeed {
 4833                                worktree_id,
 4834                                name: disposition.server_name.clone(),
 4835                                settings: disposition.settings.clone(),
 4836                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4837                                    path.worktree_id,
 4838                                    &path.path,
 4839                                    language.name(),
 4840                                ),
 4841                            };
 4842                            local.language_server_ids.remove(&key);
 4843
 4844                            let server_id = local.get_or_insert_language_server(
 4845                                &worktree,
 4846                                lsp_delegate.clone(),
 4847                                disposition,
 4848                                &language.name(),
 4849                                cx,
 4850                            );
 4851                            if let Some(state) = local.language_servers.get(&server_id)
 4852                                && let Ok(uri) = uri
 4853                            {
 4854                                state.add_workspace_folder(uri);
 4855                            };
 4856                            server_id
 4857                        });
 4858
 4859                        if let Some(language_server_id) = server_id {
 4860                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4861                                language_server_id,
 4862                                name: node.name(),
 4863                                message:
 4864                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4865                                        proto::RegisteredForBuffer {
 4866                                            buffer_abs_path: abs_path
 4867                                                .to_string_lossy()
 4868                                                .into_owned(),
 4869                                            buffer_id: buffer_id.to_proto(),
 4870                                        },
 4871                                    ),
 4872                            });
 4873                        }
 4874                    }
 4875                } else {
 4876                    continue;
 4877                }
 4878            }
 4879            rebase.finish()
 4880        };
 4881        for message in messages_to_report {
 4882            cx.emit(message);
 4883        }
 4884        local.lsp_tree = new_tree;
 4885        for (id, _) in to_stop {
 4886            self.stop_local_language_server(id, cx).detach();
 4887        }
 4888    }
 4889
 4890    pub fn apply_code_action(
 4891        &self,
 4892        buffer_handle: Entity<Buffer>,
 4893        mut action: CodeAction,
 4894        push_to_history: bool,
 4895        cx: &mut Context<Self>,
 4896    ) -> Task<Result<ProjectTransaction>> {
 4897        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4898            let request = proto::ApplyCodeAction {
 4899                project_id,
 4900                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4901                action: Some(Self::serialize_code_action(&action)),
 4902            };
 4903            let buffer_store = self.buffer_store();
 4904            cx.spawn(async move |_, cx| {
 4905                let response = upstream_client
 4906                    .request(request)
 4907                    .await?
 4908                    .transaction
 4909                    .context("missing transaction")?;
 4910
 4911                buffer_store
 4912                    .update(cx, |buffer_store, cx| {
 4913                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4914                    })?
 4915                    .await
 4916            })
 4917        } else if self.mode.is_local() {
 4918            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4919                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4920                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4921            }) else {
 4922                return Task::ready(Ok(ProjectTransaction::default()));
 4923            };
 4924            cx.spawn(async move |this,  cx| {
 4925                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4926                    .await
 4927                    .context("resolving a code action")?;
 4928                if let Some(edit) = action.lsp_action.edit()
 4929                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4930                        return LocalLspStore::deserialize_workspace_edit(
 4931                            this.upgrade().context("no app present")?,
 4932                            edit.clone(),
 4933                            push_to_history,
 4934
 4935                            lang_server.clone(),
 4936                            cx,
 4937                        )
 4938                        .await;
 4939                    }
 4940
 4941                if let Some(command) = action.lsp_action.command() {
 4942                    let server_capabilities = lang_server.capabilities();
 4943                    let available_commands = server_capabilities
 4944                        .execute_command_provider
 4945                        .as_ref()
 4946                        .map(|options| options.commands.as_slice())
 4947                        .unwrap_or_default();
 4948                    if available_commands.contains(&command.command) {
 4949                        this.update(cx, |this, _| {
 4950                            this.as_local_mut()
 4951                                .unwrap()
 4952                                .last_workspace_edits_by_language_server
 4953                                .remove(&lang_server.server_id());
 4954                        })?;
 4955
 4956                        let _result = lang_server
 4957                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4958                                command: command.command.clone(),
 4959                                arguments: command.arguments.clone().unwrap_or_default(),
 4960                                ..lsp::ExecuteCommandParams::default()
 4961                            })
 4962                            .await.into_response()
 4963                            .context("execute command")?;
 4964
 4965                        return this.update(cx, |this, _| {
 4966                            this.as_local_mut()
 4967                                .unwrap()
 4968                                .last_workspace_edits_by_language_server
 4969                                .remove(&lang_server.server_id())
 4970                                .unwrap_or_default()
 4971                        });
 4972                    } else {
 4973                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4974                    }
 4975                }
 4976
 4977                Ok(ProjectTransaction::default())
 4978            })
 4979        } else {
 4980            Task::ready(Err(anyhow!("no upstream client and not local")))
 4981        }
 4982    }
 4983
 4984    pub fn apply_code_action_kind(
 4985        &mut self,
 4986        buffers: HashSet<Entity<Buffer>>,
 4987        kind: CodeActionKind,
 4988        push_to_history: bool,
 4989        cx: &mut Context<Self>,
 4990    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4991        if self.as_local().is_some() {
 4992            cx.spawn(async move |lsp_store, cx| {
 4993                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4994                let result = LocalLspStore::execute_code_action_kind_locally(
 4995                    lsp_store.clone(),
 4996                    buffers,
 4997                    kind,
 4998                    push_to_history,
 4999                    cx,
 5000                )
 5001                .await;
 5002                lsp_store.update(cx, |lsp_store, _| {
 5003                    lsp_store.update_last_formatting_failure(&result);
 5004                })?;
 5005                result
 5006            })
 5007        } else if let Some((client, project_id)) = self.upstream_client() {
 5008            let buffer_store = self.buffer_store();
 5009            cx.spawn(async move |lsp_store, cx| {
 5010                let result = client
 5011                    .request(proto::ApplyCodeActionKind {
 5012                        project_id,
 5013                        kind: kind.as_str().to_owned(),
 5014                        buffer_ids: buffers
 5015                            .iter()
 5016                            .map(|buffer| {
 5017                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5018                            })
 5019                            .collect::<Result<_>>()?,
 5020                    })
 5021                    .await
 5022                    .and_then(|result| result.transaction.context("missing transaction"));
 5023                lsp_store.update(cx, |lsp_store, _| {
 5024                    lsp_store.update_last_formatting_failure(&result);
 5025                })?;
 5026
 5027                let transaction_response = result?;
 5028                buffer_store
 5029                    .update(cx, |buffer_store, cx| {
 5030                        buffer_store.deserialize_project_transaction(
 5031                            transaction_response,
 5032                            push_to_history,
 5033                            cx,
 5034                        )
 5035                    })?
 5036                    .await
 5037            })
 5038        } else {
 5039            Task::ready(Ok(ProjectTransaction::default()))
 5040        }
 5041    }
 5042
 5043    pub fn resolved_hint(
 5044        &mut self,
 5045        buffer_id: BufferId,
 5046        id: InlayId,
 5047        cx: &mut Context<Self>,
 5048    ) -> Option<ResolvedHint> {
 5049        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5050
 5051        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5052        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5053        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5054        let (server_id, resolve_data) = match &hint.resolve_state {
 5055            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5056            ResolveState::Resolving => {
 5057                return Some(ResolvedHint::Resolving(
 5058                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5059                ));
 5060            }
 5061            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5062        };
 5063
 5064        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5065        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5066        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5067            id,
 5068            cx.spawn(async move |lsp_store, cx| {
 5069                let resolved_hint = resolve_task.await;
 5070                lsp_store
 5071                    .update(cx, |lsp_store, _| {
 5072                        if let Some(old_inlay_hint) = lsp_store
 5073                            .lsp_data
 5074                            .get_mut(&buffer_id)
 5075                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5076                        {
 5077                            match resolved_hint {
 5078                                Ok(resolved_hint) => {
 5079                                    *old_inlay_hint = resolved_hint;
 5080                                }
 5081                                Err(e) => {
 5082                                    old_inlay_hint.resolve_state =
 5083                                        ResolveState::CanResolve(server_id, resolve_data);
 5084                                    log::error!("Inlay hint resolve failed: {e:#}");
 5085                                }
 5086                            }
 5087                        }
 5088                    })
 5089                    .ok();
 5090            })
 5091            .shared(),
 5092        );
 5093        debug_assert!(
 5094            previous_task.is_none(),
 5095            "Did not change hint's resolve state after spawning its resolve"
 5096        );
 5097        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5098        None
 5099    }
 5100
 5101    fn resolve_inlay_hint(
 5102        &self,
 5103        mut hint: InlayHint,
 5104        buffer: Entity<Buffer>,
 5105        server_id: LanguageServerId,
 5106        cx: &mut Context<Self>,
 5107    ) -> Task<anyhow::Result<InlayHint>> {
 5108        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5109            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5110            {
 5111                hint.resolve_state = ResolveState::Resolved;
 5112                return Task::ready(Ok(hint));
 5113            }
 5114            let request = proto::ResolveInlayHint {
 5115                project_id,
 5116                buffer_id: buffer.read(cx).remote_id().into(),
 5117                language_server_id: server_id.0 as u64,
 5118                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5119            };
 5120            cx.background_spawn(async move {
 5121                let response = upstream_client
 5122                    .request(request)
 5123                    .await
 5124                    .context("inlay hints proto request")?;
 5125                match response.hint {
 5126                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5127                        .context("inlay hints proto resolve response conversion"),
 5128                    None => Ok(hint),
 5129                }
 5130            })
 5131        } else {
 5132            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5133                self.language_server_for_local_buffer(buffer, server_id, cx)
 5134                    .map(|(_, server)| server.clone())
 5135            }) else {
 5136                return Task::ready(Ok(hint));
 5137            };
 5138            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5139                return Task::ready(Ok(hint));
 5140            }
 5141            let buffer_snapshot = buffer.read(cx).snapshot();
 5142            cx.spawn(async move |_, cx| {
 5143                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5144                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5145                );
 5146                let resolved_hint = resolve_task
 5147                    .await
 5148                    .into_response()
 5149                    .context("inlay hint resolve LSP request")?;
 5150                let resolved_hint = InlayHints::lsp_to_project_hint(
 5151                    resolved_hint,
 5152                    &buffer,
 5153                    server_id,
 5154                    ResolveState::Resolved,
 5155                    false,
 5156                    cx,
 5157                )
 5158                .await?;
 5159                Ok(resolved_hint)
 5160            })
 5161        }
 5162    }
 5163
 5164    pub fn resolve_color_presentation(
 5165        &mut self,
 5166        mut color: DocumentColor,
 5167        buffer: Entity<Buffer>,
 5168        server_id: LanguageServerId,
 5169        cx: &mut Context<Self>,
 5170    ) -> Task<Result<DocumentColor>> {
 5171        if color.resolved {
 5172            return Task::ready(Ok(color));
 5173        }
 5174
 5175        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5176            let start = color.lsp_range.start;
 5177            let end = color.lsp_range.end;
 5178            let request = proto::GetColorPresentation {
 5179                project_id,
 5180                server_id: server_id.to_proto(),
 5181                buffer_id: buffer.read(cx).remote_id().into(),
 5182                color: Some(proto::ColorInformation {
 5183                    red: color.color.red,
 5184                    green: color.color.green,
 5185                    blue: color.color.blue,
 5186                    alpha: color.color.alpha,
 5187                    lsp_range_start: Some(proto::PointUtf16 {
 5188                        row: start.line,
 5189                        column: start.character,
 5190                    }),
 5191                    lsp_range_end: Some(proto::PointUtf16 {
 5192                        row: end.line,
 5193                        column: end.character,
 5194                    }),
 5195                }),
 5196            };
 5197            cx.background_spawn(async move {
 5198                let response = upstream_client
 5199                    .request(request)
 5200                    .await
 5201                    .context("color presentation proto request")?;
 5202                color.resolved = true;
 5203                color.color_presentations = response
 5204                    .presentations
 5205                    .into_iter()
 5206                    .map(|presentation| ColorPresentation {
 5207                        label: SharedString::from(presentation.label),
 5208                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5209                        additional_text_edits: presentation
 5210                            .additional_text_edits
 5211                            .into_iter()
 5212                            .filter_map(deserialize_lsp_edit)
 5213                            .collect(),
 5214                    })
 5215                    .collect();
 5216                Ok(color)
 5217            })
 5218        } else {
 5219            let path = match buffer
 5220                .update(cx, |buffer, cx| {
 5221                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5222                })
 5223                .context("buffer with the missing path")
 5224            {
 5225                Ok(path) => path,
 5226                Err(e) => return Task::ready(Err(e)),
 5227            };
 5228            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5229                self.language_server_for_local_buffer(buffer, server_id, cx)
 5230                    .map(|(_, server)| server.clone())
 5231            }) else {
 5232                return Task::ready(Ok(color));
 5233            };
 5234            cx.background_spawn(async move {
 5235                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5236                    lsp::ColorPresentationParams {
 5237                        text_document: make_text_document_identifier(&path)?,
 5238                        color: color.color,
 5239                        range: color.lsp_range,
 5240                        work_done_progress_params: Default::default(),
 5241                        partial_result_params: Default::default(),
 5242                    },
 5243                );
 5244                color.color_presentations = resolve_task
 5245                    .await
 5246                    .into_response()
 5247                    .context("color presentation resolve LSP request")?
 5248                    .into_iter()
 5249                    .map(|presentation| ColorPresentation {
 5250                        label: SharedString::from(presentation.label),
 5251                        text_edit: presentation.text_edit,
 5252                        additional_text_edits: presentation
 5253                            .additional_text_edits
 5254                            .unwrap_or_default(),
 5255                    })
 5256                    .collect();
 5257                color.resolved = true;
 5258                Ok(color)
 5259            })
 5260        }
 5261    }
 5262
 5263    pub(crate) fn linked_edits(
 5264        &mut self,
 5265        buffer: &Entity<Buffer>,
 5266        position: Anchor,
 5267        cx: &mut Context<Self>,
 5268    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5269        let snapshot = buffer.read(cx).snapshot();
 5270        let scope = snapshot.language_scope_at(position);
 5271        let Some(server_id) = self
 5272            .as_local()
 5273            .and_then(|local| {
 5274                buffer.update(cx, |buffer, cx| {
 5275                    local
 5276                        .language_servers_for_buffer(buffer, cx)
 5277                        .filter(|(_, server)| {
 5278                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5279                        })
 5280                        .filter(|(adapter, _)| {
 5281                            scope
 5282                                .as_ref()
 5283                                .map(|scope| scope.language_allowed(&adapter.name))
 5284                                .unwrap_or(true)
 5285                        })
 5286                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5287                        .next()
 5288                })
 5289            })
 5290            .or_else(|| {
 5291                self.upstream_client()
 5292                    .is_some()
 5293                    .then_some(LanguageServerToQuery::FirstCapable)
 5294            })
 5295            .filter(|_| {
 5296                maybe!({
 5297                    let language = buffer.read(cx).language_at(position)?;
 5298                    Some(
 5299                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5300                            .linked_edits,
 5301                    )
 5302                }) == Some(true)
 5303            })
 5304        else {
 5305            return Task::ready(Ok(Vec::new()));
 5306        };
 5307
 5308        self.request_lsp(
 5309            buffer.clone(),
 5310            server_id,
 5311            LinkedEditingRange { position },
 5312            cx,
 5313        )
 5314    }
 5315
 5316    fn apply_on_type_formatting(
 5317        &mut self,
 5318        buffer: Entity<Buffer>,
 5319        position: Anchor,
 5320        trigger: String,
 5321        cx: &mut Context<Self>,
 5322    ) -> Task<Result<Option<Transaction>>> {
 5323        if let Some((client, project_id)) = self.upstream_client() {
 5324            if !self.check_if_capable_for_proto_request(
 5325                &buffer,
 5326                |capabilities| {
 5327                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5328                },
 5329                cx,
 5330            ) {
 5331                return Task::ready(Ok(None));
 5332            }
 5333            let request = proto::OnTypeFormatting {
 5334                project_id,
 5335                buffer_id: buffer.read(cx).remote_id().into(),
 5336                position: Some(serialize_anchor(&position)),
 5337                trigger,
 5338                version: serialize_version(&buffer.read(cx).version()),
 5339            };
 5340            cx.background_spawn(async move {
 5341                client
 5342                    .request(request)
 5343                    .await?
 5344                    .transaction
 5345                    .map(language::proto::deserialize_transaction)
 5346                    .transpose()
 5347            })
 5348        } else if let Some(local) = self.as_local_mut() {
 5349            let buffer_id = buffer.read(cx).remote_id();
 5350            local.buffers_being_formatted.insert(buffer_id);
 5351            cx.spawn(async move |this, cx| {
 5352                let _cleanup = defer({
 5353                    let this = this.clone();
 5354                    let mut cx = cx.clone();
 5355                    move || {
 5356                        this.update(&mut cx, |this, _| {
 5357                            if let Some(local) = this.as_local_mut() {
 5358                                local.buffers_being_formatted.remove(&buffer_id);
 5359                            }
 5360                        })
 5361                        .ok();
 5362                    }
 5363                });
 5364
 5365                buffer
 5366                    .update(cx, |buffer, _| {
 5367                        buffer.wait_for_edits(Some(position.timestamp))
 5368                    })?
 5369                    .await?;
 5370                this.update(cx, |this, cx| {
 5371                    let position = position.to_point_utf16(buffer.read(cx));
 5372                    this.on_type_format(buffer, position, trigger, false, cx)
 5373                })?
 5374                .await
 5375            })
 5376        } else {
 5377            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5378        }
 5379    }
 5380
 5381    pub fn on_type_format<T: ToPointUtf16>(
 5382        &mut self,
 5383        buffer: Entity<Buffer>,
 5384        position: T,
 5385        trigger: String,
 5386        push_to_history: bool,
 5387        cx: &mut Context<Self>,
 5388    ) -> Task<Result<Option<Transaction>>> {
 5389        let position = position.to_point_utf16(buffer.read(cx));
 5390        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5391    }
 5392
 5393    fn on_type_format_impl(
 5394        &mut self,
 5395        buffer: Entity<Buffer>,
 5396        position: PointUtf16,
 5397        trigger: String,
 5398        push_to_history: bool,
 5399        cx: &mut Context<Self>,
 5400    ) -> Task<Result<Option<Transaction>>> {
 5401        let options = buffer.update(cx, |buffer, cx| {
 5402            lsp_command::lsp_formatting_options(
 5403                language_settings(
 5404                    buffer.language_at(position).map(|l| l.name()),
 5405                    buffer.file(),
 5406                    cx,
 5407                )
 5408                .as_ref(),
 5409            )
 5410        });
 5411
 5412        cx.spawn(async move |this, cx| {
 5413            if let Some(waiter) =
 5414                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5415            {
 5416                waiter.await?;
 5417            }
 5418            cx.update(|cx| {
 5419                this.update(cx, |this, cx| {
 5420                    this.request_lsp(
 5421                        buffer.clone(),
 5422                        LanguageServerToQuery::FirstCapable,
 5423                        OnTypeFormatting {
 5424                            position,
 5425                            trigger,
 5426                            options,
 5427                            push_to_history,
 5428                        },
 5429                        cx,
 5430                    )
 5431                })
 5432            })??
 5433            .await
 5434        })
 5435    }
 5436
 5437    pub fn definitions(
 5438        &mut self,
 5439        buffer: &Entity<Buffer>,
 5440        position: PointUtf16,
 5441        cx: &mut Context<Self>,
 5442    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5443        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5444            let request = GetDefinitions { position };
 5445            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5446                return Task::ready(Ok(None));
 5447            }
 5448            let request_task = upstream_client.request_lsp(
 5449                project_id,
 5450                None,
 5451                LSP_REQUEST_TIMEOUT,
 5452                cx.background_executor().clone(),
 5453                request.to_proto(project_id, buffer.read(cx)),
 5454            );
 5455            let buffer = buffer.clone();
 5456            cx.spawn(async move |weak_lsp_store, cx| {
 5457                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5458                    return Ok(None);
 5459                };
 5460                let Some(responses) = request_task.await? else {
 5461                    return Ok(None);
 5462                };
 5463                let actions = join_all(responses.payload.into_iter().map(|response| {
 5464                    GetDefinitions { position }.response_from_proto(
 5465                        response.response,
 5466                        lsp_store.clone(),
 5467                        buffer.clone(),
 5468                        cx.clone(),
 5469                    )
 5470                }))
 5471                .await;
 5472
 5473                Ok(Some(
 5474                    actions
 5475                        .into_iter()
 5476                        .collect::<Result<Vec<Vec<_>>>>()?
 5477                        .into_iter()
 5478                        .flatten()
 5479                        .dedup()
 5480                        .collect(),
 5481                ))
 5482            })
 5483        } else {
 5484            let definitions_task = self.request_multiple_lsp_locally(
 5485                buffer,
 5486                Some(position),
 5487                GetDefinitions { position },
 5488                cx,
 5489            );
 5490            cx.background_spawn(async move {
 5491                Ok(Some(
 5492                    definitions_task
 5493                        .await
 5494                        .into_iter()
 5495                        .flat_map(|(_, definitions)| definitions)
 5496                        .dedup()
 5497                        .collect(),
 5498                ))
 5499            })
 5500        }
 5501    }
 5502
 5503    pub fn declarations(
 5504        &mut self,
 5505        buffer: &Entity<Buffer>,
 5506        position: PointUtf16,
 5507        cx: &mut Context<Self>,
 5508    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5509        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5510            let request = GetDeclarations { position };
 5511            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5512                return Task::ready(Ok(None));
 5513            }
 5514            let request_task = upstream_client.request_lsp(
 5515                project_id,
 5516                None,
 5517                LSP_REQUEST_TIMEOUT,
 5518                cx.background_executor().clone(),
 5519                request.to_proto(project_id, buffer.read(cx)),
 5520            );
 5521            let buffer = buffer.clone();
 5522            cx.spawn(async move |weak_lsp_store, cx| {
 5523                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5524                    return Ok(None);
 5525                };
 5526                let Some(responses) = request_task.await? else {
 5527                    return Ok(None);
 5528                };
 5529                let actions = join_all(responses.payload.into_iter().map(|response| {
 5530                    GetDeclarations { position }.response_from_proto(
 5531                        response.response,
 5532                        lsp_store.clone(),
 5533                        buffer.clone(),
 5534                        cx.clone(),
 5535                    )
 5536                }))
 5537                .await;
 5538
 5539                Ok(Some(
 5540                    actions
 5541                        .into_iter()
 5542                        .collect::<Result<Vec<Vec<_>>>>()?
 5543                        .into_iter()
 5544                        .flatten()
 5545                        .dedup()
 5546                        .collect(),
 5547                ))
 5548            })
 5549        } else {
 5550            let declarations_task = self.request_multiple_lsp_locally(
 5551                buffer,
 5552                Some(position),
 5553                GetDeclarations { position },
 5554                cx,
 5555            );
 5556            cx.background_spawn(async move {
 5557                Ok(Some(
 5558                    declarations_task
 5559                        .await
 5560                        .into_iter()
 5561                        .flat_map(|(_, declarations)| declarations)
 5562                        .dedup()
 5563                        .collect(),
 5564                ))
 5565            })
 5566        }
 5567    }
 5568
 5569    pub fn type_definitions(
 5570        &mut self,
 5571        buffer: &Entity<Buffer>,
 5572        position: PointUtf16,
 5573        cx: &mut Context<Self>,
 5574    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5575        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5576            let request = GetTypeDefinitions { position };
 5577            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5578                return Task::ready(Ok(None));
 5579            }
 5580            let request_task = upstream_client.request_lsp(
 5581                project_id,
 5582                None,
 5583                LSP_REQUEST_TIMEOUT,
 5584                cx.background_executor().clone(),
 5585                request.to_proto(project_id, buffer.read(cx)),
 5586            );
 5587            let buffer = buffer.clone();
 5588            cx.spawn(async move |weak_lsp_store, cx| {
 5589                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5590                    return Ok(None);
 5591                };
 5592                let Some(responses) = request_task.await? else {
 5593                    return Ok(None);
 5594                };
 5595                let actions = join_all(responses.payload.into_iter().map(|response| {
 5596                    GetTypeDefinitions { position }.response_from_proto(
 5597                        response.response,
 5598                        lsp_store.clone(),
 5599                        buffer.clone(),
 5600                        cx.clone(),
 5601                    )
 5602                }))
 5603                .await;
 5604
 5605                Ok(Some(
 5606                    actions
 5607                        .into_iter()
 5608                        .collect::<Result<Vec<Vec<_>>>>()?
 5609                        .into_iter()
 5610                        .flatten()
 5611                        .dedup()
 5612                        .collect(),
 5613                ))
 5614            })
 5615        } else {
 5616            let type_definitions_task = self.request_multiple_lsp_locally(
 5617                buffer,
 5618                Some(position),
 5619                GetTypeDefinitions { position },
 5620                cx,
 5621            );
 5622            cx.background_spawn(async move {
 5623                Ok(Some(
 5624                    type_definitions_task
 5625                        .await
 5626                        .into_iter()
 5627                        .flat_map(|(_, type_definitions)| type_definitions)
 5628                        .dedup()
 5629                        .collect(),
 5630                ))
 5631            })
 5632        }
 5633    }
 5634
 5635    pub fn implementations(
 5636        &mut self,
 5637        buffer: &Entity<Buffer>,
 5638        position: PointUtf16,
 5639        cx: &mut Context<Self>,
 5640    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5641        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5642            let request = GetImplementations { position };
 5643            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5644                return Task::ready(Ok(None));
 5645            }
 5646            let request_task = upstream_client.request_lsp(
 5647                project_id,
 5648                None,
 5649                LSP_REQUEST_TIMEOUT,
 5650                cx.background_executor().clone(),
 5651                request.to_proto(project_id, buffer.read(cx)),
 5652            );
 5653            let buffer = buffer.clone();
 5654            cx.spawn(async move |weak_lsp_store, cx| {
 5655                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5656                    return Ok(None);
 5657                };
 5658                let Some(responses) = request_task.await? else {
 5659                    return Ok(None);
 5660                };
 5661                let actions = join_all(responses.payload.into_iter().map(|response| {
 5662                    GetImplementations { position }.response_from_proto(
 5663                        response.response,
 5664                        lsp_store.clone(),
 5665                        buffer.clone(),
 5666                        cx.clone(),
 5667                    )
 5668                }))
 5669                .await;
 5670
 5671                Ok(Some(
 5672                    actions
 5673                        .into_iter()
 5674                        .collect::<Result<Vec<Vec<_>>>>()?
 5675                        .into_iter()
 5676                        .flatten()
 5677                        .dedup()
 5678                        .collect(),
 5679                ))
 5680            })
 5681        } else {
 5682            let implementations_task = self.request_multiple_lsp_locally(
 5683                buffer,
 5684                Some(position),
 5685                GetImplementations { position },
 5686                cx,
 5687            );
 5688            cx.background_spawn(async move {
 5689                Ok(Some(
 5690                    implementations_task
 5691                        .await
 5692                        .into_iter()
 5693                        .flat_map(|(_, implementations)| implementations)
 5694                        .dedup()
 5695                        .collect(),
 5696                ))
 5697            })
 5698        }
 5699    }
 5700
 5701    pub fn references(
 5702        &mut self,
 5703        buffer: &Entity<Buffer>,
 5704        position: PointUtf16,
 5705        cx: &mut Context<Self>,
 5706    ) -> Task<Result<Option<Vec<Location>>>> {
 5707        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5708            let request = GetReferences { position };
 5709            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5710                return Task::ready(Ok(None));
 5711            }
 5712
 5713            let request_task = upstream_client.request_lsp(
 5714                project_id,
 5715                None,
 5716                LSP_REQUEST_TIMEOUT,
 5717                cx.background_executor().clone(),
 5718                request.to_proto(project_id, buffer.read(cx)),
 5719            );
 5720            let buffer = buffer.clone();
 5721            cx.spawn(async move |weak_lsp_store, cx| {
 5722                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5723                    return Ok(None);
 5724                };
 5725                let Some(responses) = request_task.await? else {
 5726                    return Ok(None);
 5727                };
 5728
 5729                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5730                    GetReferences { position }.response_from_proto(
 5731                        lsp_response.response,
 5732                        lsp_store.clone(),
 5733                        buffer.clone(),
 5734                        cx.clone(),
 5735                    )
 5736                }))
 5737                .await
 5738                .into_iter()
 5739                .collect::<Result<Vec<Vec<_>>>>()?
 5740                .into_iter()
 5741                .flatten()
 5742                .dedup()
 5743                .collect();
 5744                Ok(Some(locations))
 5745            })
 5746        } else {
 5747            let references_task = self.request_multiple_lsp_locally(
 5748                buffer,
 5749                Some(position),
 5750                GetReferences { position },
 5751                cx,
 5752            );
 5753            cx.background_spawn(async move {
 5754                Ok(Some(
 5755                    references_task
 5756                        .await
 5757                        .into_iter()
 5758                        .flat_map(|(_, references)| references)
 5759                        .dedup()
 5760                        .collect(),
 5761                ))
 5762            })
 5763        }
 5764    }
 5765
 5766    pub fn code_actions(
 5767        &mut self,
 5768        buffer: &Entity<Buffer>,
 5769        range: Range<Anchor>,
 5770        kinds: Option<Vec<CodeActionKind>>,
 5771        cx: &mut Context<Self>,
 5772    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5773        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5774            let request = GetCodeActions {
 5775                range: range.clone(),
 5776                kinds: kinds.clone(),
 5777            };
 5778            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5779                return Task::ready(Ok(None));
 5780            }
 5781            let request_task = upstream_client.request_lsp(
 5782                project_id,
 5783                None,
 5784                LSP_REQUEST_TIMEOUT,
 5785                cx.background_executor().clone(),
 5786                request.to_proto(project_id, buffer.read(cx)),
 5787            );
 5788            let buffer = buffer.clone();
 5789            cx.spawn(async move |weak_lsp_store, cx| {
 5790                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5791                    return Ok(None);
 5792                };
 5793                let Some(responses) = request_task.await? else {
 5794                    return Ok(None);
 5795                };
 5796                let actions = join_all(responses.payload.into_iter().map(|response| {
 5797                    GetCodeActions {
 5798                        range: range.clone(),
 5799                        kinds: kinds.clone(),
 5800                    }
 5801                    .response_from_proto(
 5802                        response.response,
 5803                        lsp_store.clone(),
 5804                        buffer.clone(),
 5805                        cx.clone(),
 5806                    )
 5807                }))
 5808                .await;
 5809
 5810                Ok(Some(
 5811                    actions
 5812                        .into_iter()
 5813                        .collect::<Result<Vec<Vec<_>>>>()?
 5814                        .into_iter()
 5815                        .flatten()
 5816                        .collect(),
 5817                ))
 5818            })
 5819        } else {
 5820            let all_actions_task = self.request_multiple_lsp_locally(
 5821                buffer,
 5822                Some(range.start),
 5823                GetCodeActions { range, kinds },
 5824                cx,
 5825            );
 5826            cx.background_spawn(async move {
 5827                Ok(Some(
 5828                    all_actions_task
 5829                        .await
 5830                        .into_iter()
 5831                        .flat_map(|(_, actions)| actions)
 5832                        .collect(),
 5833                ))
 5834            })
 5835        }
 5836    }
 5837
 5838    pub fn code_lens_actions(
 5839        &mut self,
 5840        buffer: &Entity<Buffer>,
 5841        cx: &mut Context<Self>,
 5842    ) -> CodeLensTask {
 5843        let version_queried_for = buffer.read(cx).version();
 5844        let buffer_id = buffer.read(cx).remote_id();
 5845        let existing_servers = self.as_local().map(|local| {
 5846            local
 5847                .buffers_opened_in_servers
 5848                .get(&buffer_id)
 5849                .cloned()
 5850                .unwrap_or_default()
 5851        });
 5852
 5853        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5854            if let Some(cached_lens) = &lsp_data.code_lens {
 5855                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5856                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5857                        existing_servers != cached_lens.lens.keys().copied().collect()
 5858                    });
 5859                    if !has_different_servers {
 5860                        return Task::ready(Ok(Some(
 5861                            cached_lens.lens.values().flatten().cloned().collect(),
 5862                        )))
 5863                        .shared();
 5864                    }
 5865                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5866                    if !version_queried_for.changed_since(updating_for) {
 5867                        return running_update.clone();
 5868                    }
 5869                }
 5870            }
 5871        }
 5872
 5873        let lens_lsp_data = self
 5874            .latest_lsp_data(buffer, cx)
 5875            .code_lens
 5876            .get_or_insert_default();
 5877        let buffer = buffer.clone();
 5878        let query_version_queried_for = version_queried_for.clone();
 5879        let new_task = cx
 5880            .spawn(async move |lsp_store, cx| {
 5881                cx.background_executor()
 5882                    .timer(Duration::from_millis(30))
 5883                    .await;
 5884                let fetched_lens = lsp_store
 5885                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5886                    .map_err(Arc::new)?
 5887                    .await
 5888                    .context("fetching code lens")
 5889                    .map_err(Arc::new);
 5890                let fetched_lens = match fetched_lens {
 5891                    Ok(fetched_lens) => fetched_lens,
 5892                    Err(e) => {
 5893                        lsp_store
 5894                            .update(cx, |lsp_store, _| {
 5895                                if let Some(lens_lsp_data) = lsp_store
 5896                                    .lsp_data
 5897                                    .get_mut(&buffer_id)
 5898                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5899                                {
 5900                                    lens_lsp_data.update = None;
 5901                                }
 5902                            })
 5903                            .ok();
 5904                        return Err(e);
 5905                    }
 5906                };
 5907
 5908                lsp_store
 5909                    .update(cx, |lsp_store, _| {
 5910                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5911                        let code_lens = lsp_data.code_lens.as_mut()?;
 5912                        if let Some(fetched_lens) = fetched_lens {
 5913                            if lsp_data.buffer_version == query_version_queried_for {
 5914                                code_lens.lens.extend(fetched_lens);
 5915                            } else if !lsp_data
 5916                                .buffer_version
 5917                                .changed_since(&query_version_queried_for)
 5918                            {
 5919                                lsp_data.buffer_version = query_version_queried_for;
 5920                                code_lens.lens = fetched_lens;
 5921                            }
 5922                        }
 5923                        code_lens.update = None;
 5924                        Some(code_lens.lens.values().flatten().cloned().collect())
 5925                    })
 5926                    .map_err(Arc::new)
 5927            })
 5928            .shared();
 5929        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5930        new_task
 5931    }
 5932
 5933    fn fetch_code_lens(
 5934        &mut self,
 5935        buffer: &Entity<Buffer>,
 5936        cx: &mut Context<Self>,
 5937    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5938        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5939            let request = GetCodeLens;
 5940            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5941                return Task::ready(Ok(None));
 5942            }
 5943            let request_task = upstream_client.request_lsp(
 5944                project_id,
 5945                None,
 5946                LSP_REQUEST_TIMEOUT,
 5947                cx.background_executor().clone(),
 5948                request.to_proto(project_id, buffer.read(cx)),
 5949            );
 5950            let buffer = buffer.clone();
 5951            cx.spawn(async move |weak_lsp_store, cx| {
 5952                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5953                    return Ok(None);
 5954                };
 5955                let Some(responses) = request_task.await? else {
 5956                    return Ok(None);
 5957                };
 5958
 5959                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5960                    let lsp_store = lsp_store.clone();
 5961                    let buffer = buffer.clone();
 5962                    let cx = cx.clone();
 5963                    async move {
 5964                        (
 5965                            LanguageServerId::from_proto(response.server_id),
 5966                            GetCodeLens
 5967                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5968                                .await,
 5969                        )
 5970                    }
 5971                }))
 5972                .await;
 5973
 5974                let mut has_errors = false;
 5975                let code_lens_actions = code_lens_actions
 5976                    .into_iter()
 5977                    .filter_map(|(server_id, code_lens)| match code_lens {
 5978                        Ok(code_lens) => Some((server_id, code_lens)),
 5979                        Err(e) => {
 5980                            has_errors = true;
 5981                            log::error!("{e:#}");
 5982                            None
 5983                        }
 5984                    })
 5985                    .collect::<HashMap<_, _>>();
 5986                anyhow::ensure!(
 5987                    !has_errors || !code_lens_actions.is_empty(),
 5988                    "Failed to fetch code lens"
 5989                );
 5990                Ok(Some(code_lens_actions))
 5991            })
 5992        } else {
 5993            let code_lens_actions_task =
 5994                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5995            cx.background_spawn(async move {
 5996                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5997            })
 5998        }
 5999    }
 6000
 6001    #[inline(never)]
 6002    pub fn completions(
 6003        &self,
 6004        buffer: &Entity<Buffer>,
 6005        position: PointUtf16,
 6006        context: CompletionContext,
 6007        cx: &mut Context<Self>,
 6008    ) -> Task<Result<Vec<CompletionResponse>>> {
 6009        let language_registry = self.languages.clone();
 6010
 6011        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6012            let snapshot = buffer.read(cx).snapshot();
 6013            let offset = position.to_offset(&snapshot);
 6014            let scope = snapshot.language_scope_at(offset);
 6015            let capable_lsps = self.all_capable_for_proto_request(
 6016                buffer,
 6017                |server_name, capabilities| {
 6018                    capabilities.completion_provider.is_some()
 6019                        && scope
 6020                            .as_ref()
 6021                            .map(|scope| scope.language_allowed(server_name))
 6022                            .unwrap_or(true)
 6023                },
 6024                cx,
 6025            );
 6026            if capable_lsps.is_empty() {
 6027                return Task::ready(Ok(Vec::new()));
 6028            }
 6029
 6030            let language = buffer.read(cx).language().cloned();
 6031
 6032            // In the future, we should provide project guests with the names of LSP adapters,
 6033            // so that they can use the correct LSP adapter when computing labels. For now,
 6034            // guests just use the first LSP adapter associated with the buffer's language.
 6035            let lsp_adapter = language.as_ref().and_then(|language| {
 6036                language_registry
 6037                    .lsp_adapters(&language.name())
 6038                    .first()
 6039                    .cloned()
 6040            });
 6041
 6042            let buffer = buffer.clone();
 6043
 6044            cx.spawn(async move |this, cx| {
 6045                let requests = join_all(
 6046                    capable_lsps
 6047                        .into_iter()
 6048                        .map(|id| {
 6049                            let request = GetCompletions {
 6050                                position,
 6051                                context: context.clone(),
 6052                                server_id: Some(id),
 6053                            };
 6054                            let buffer = buffer.clone();
 6055                            let language = language.clone();
 6056                            let lsp_adapter = lsp_adapter.clone();
 6057                            let upstream_client = upstream_client.clone();
 6058                            let response = this
 6059                                .update(cx, |this, cx| {
 6060                                    this.send_lsp_proto_request(
 6061                                        buffer,
 6062                                        upstream_client,
 6063                                        project_id,
 6064                                        request,
 6065                                        cx,
 6066                                    )
 6067                                })
 6068                                .log_err();
 6069                            async move {
 6070                                let response = response?.await.log_err()?;
 6071
 6072                                let completions = populate_labels_for_completions(
 6073                                    response.completions,
 6074                                    language,
 6075                                    lsp_adapter,
 6076                                )
 6077                                .await;
 6078
 6079                                Some(CompletionResponse {
 6080                                    completions,
 6081                                    display_options: CompletionDisplayOptions::default(),
 6082                                    is_incomplete: response.is_incomplete,
 6083                                })
 6084                            }
 6085                        })
 6086                        .collect::<Vec<_>>(),
 6087                );
 6088                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6089            })
 6090        } else if let Some(local) = self.as_local() {
 6091            let snapshot = buffer.read(cx).snapshot();
 6092            let offset = position.to_offset(&snapshot);
 6093            let scope = snapshot.language_scope_at(offset);
 6094            let language = snapshot.language().cloned();
 6095            let completion_settings = language_settings(
 6096                language.as_ref().map(|language| language.name()),
 6097                buffer.read(cx).file(),
 6098                cx,
 6099            )
 6100            .completions
 6101            .clone();
 6102            if !completion_settings.lsp {
 6103                return Task::ready(Ok(Vec::new()));
 6104            }
 6105
 6106            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6107                local
 6108                    .language_servers_for_buffer(buffer, cx)
 6109                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6110                    .filter(|(adapter, _)| {
 6111                        scope
 6112                            .as_ref()
 6113                            .map(|scope| scope.language_allowed(&adapter.name))
 6114                            .unwrap_or(true)
 6115                    })
 6116                    .map(|(_, server)| server.server_id())
 6117                    .collect()
 6118            });
 6119
 6120            let buffer = buffer.clone();
 6121            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6122            let lsp_timeout = if lsp_timeout > 0 {
 6123                Some(Duration::from_millis(lsp_timeout))
 6124            } else {
 6125                None
 6126            };
 6127            cx.spawn(async move |this,  cx| {
 6128                let mut tasks = Vec::with_capacity(server_ids.len());
 6129                this.update(cx, |lsp_store, cx| {
 6130                    for server_id in server_ids {
 6131                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6132                        let lsp_timeout = lsp_timeout
 6133                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6134                        let mut timeout = cx.background_spawn(async move {
 6135                            match lsp_timeout {
 6136                                Some(lsp_timeout) => {
 6137                                    lsp_timeout.await;
 6138                                    true
 6139                                },
 6140                                None => false,
 6141                            }
 6142                        }).fuse();
 6143                        let mut lsp_request = lsp_store.request_lsp(
 6144                            buffer.clone(),
 6145                            LanguageServerToQuery::Other(server_id),
 6146                            GetCompletions {
 6147                                position,
 6148                                context: context.clone(),
 6149                                server_id: Some(server_id),
 6150                            },
 6151                            cx,
 6152                        ).fuse();
 6153                        let new_task = cx.background_spawn(async move {
 6154                            select_biased! {
 6155                                response = lsp_request => anyhow::Ok(Some(response?)),
 6156                                timeout_happened = timeout => {
 6157                                    if timeout_happened {
 6158                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6159                                        Ok(None)
 6160                                    } else {
 6161                                        let completions = lsp_request.await?;
 6162                                        Ok(Some(completions))
 6163                                    }
 6164                                },
 6165                            }
 6166                        });
 6167                        tasks.push((lsp_adapter, new_task));
 6168                    }
 6169                })?;
 6170
 6171                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6172                    let completion_response = task.await.ok()??;
 6173                    let completions = populate_labels_for_completions(
 6174                            completion_response.completions,
 6175                            language.clone(),
 6176                            lsp_adapter,
 6177                        )
 6178                        .await;
 6179                    Some(CompletionResponse {
 6180                        completions,
 6181                        display_options: CompletionDisplayOptions::default(),
 6182                        is_incomplete: completion_response.is_incomplete,
 6183                    })
 6184                });
 6185
 6186                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6187
 6188                Ok(responses.into_iter().flatten().collect())
 6189            })
 6190        } else {
 6191            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6192        }
 6193    }
 6194
 6195    pub fn resolve_completions(
 6196        &self,
 6197        buffer: Entity<Buffer>,
 6198        completion_indices: Vec<usize>,
 6199        completions: Rc<RefCell<Box<[Completion]>>>,
 6200        cx: &mut Context<Self>,
 6201    ) -> Task<Result<bool>> {
 6202        let client = self.upstream_client();
 6203        let buffer_id = buffer.read(cx).remote_id();
 6204        let buffer_snapshot = buffer.read(cx).snapshot();
 6205
 6206        if !self.check_if_capable_for_proto_request(
 6207            &buffer,
 6208            GetCompletions::can_resolve_completions,
 6209            cx,
 6210        ) {
 6211            return Task::ready(Ok(false));
 6212        }
 6213        cx.spawn(async move |lsp_store, cx| {
 6214            let mut did_resolve = false;
 6215            if let Some((client, project_id)) = client {
 6216                for completion_index in completion_indices {
 6217                    let server_id = {
 6218                        let completion = &completions.borrow()[completion_index];
 6219                        completion.source.server_id()
 6220                    };
 6221                    if let Some(server_id) = server_id {
 6222                        if Self::resolve_completion_remote(
 6223                            project_id,
 6224                            server_id,
 6225                            buffer_id,
 6226                            completions.clone(),
 6227                            completion_index,
 6228                            client.clone(),
 6229                        )
 6230                        .await
 6231                        .log_err()
 6232                        .is_some()
 6233                        {
 6234                            did_resolve = true;
 6235                        }
 6236                    } else {
 6237                        resolve_word_completion(
 6238                            &buffer_snapshot,
 6239                            &mut completions.borrow_mut()[completion_index],
 6240                        );
 6241                    }
 6242                }
 6243            } else {
 6244                for completion_index in completion_indices {
 6245                    let server_id = {
 6246                        let completion = &completions.borrow()[completion_index];
 6247                        completion.source.server_id()
 6248                    };
 6249                    if let Some(server_id) = server_id {
 6250                        let server_and_adapter = lsp_store
 6251                            .read_with(cx, |lsp_store, _| {
 6252                                let server = lsp_store.language_server_for_id(server_id)?;
 6253                                let adapter =
 6254                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6255                                Some((server, adapter))
 6256                            })
 6257                            .ok()
 6258                            .flatten();
 6259                        let Some((server, adapter)) = server_and_adapter else {
 6260                            continue;
 6261                        };
 6262
 6263                        let resolved = Self::resolve_completion_local(
 6264                            server,
 6265                            completions.clone(),
 6266                            completion_index,
 6267                        )
 6268                        .await
 6269                        .log_err()
 6270                        .is_some();
 6271                        if resolved {
 6272                            Self::regenerate_completion_labels(
 6273                                adapter,
 6274                                &buffer_snapshot,
 6275                                completions.clone(),
 6276                                completion_index,
 6277                            )
 6278                            .await
 6279                            .log_err();
 6280                            did_resolve = true;
 6281                        }
 6282                    } else {
 6283                        resolve_word_completion(
 6284                            &buffer_snapshot,
 6285                            &mut completions.borrow_mut()[completion_index],
 6286                        );
 6287                    }
 6288                }
 6289            }
 6290
 6291            Ok(did_resolve)
 6292        })
 6293    }
 6294
 6295    async fn resolve_completion_local(
 6296        server: Arc<lsp::LanguageServer>,
 6297        completions: Rc<RefCell<Box<[Completion]>>>,
 6298        completion_index: usize,
 6299    ) -> Result<()> {
 6300        let server_id = server.server_id();
 6301        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6302            return Ok(());
 6303        }
 6304
 6305        let request = {
 6306            let completion = &completions.borrow()[completion_index];
 6307            match &completion.source {
 6308                CompletionSource::Lsp {
 6309                    lsp_completion,
 6310                    resolved,
 6311                    server_id: completion_server_id,
 6312                    ..
 6313                } => {
 6314                    if *resolved {
 6315                        return Ok(());
 6316                    }
 6317                    anyhow::ensure!(
 6318                        server_id == *completion_server_id,
 6319                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6320                    );
 6321                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6322                }
 6323                CompletionSource::BufferWord { .. }
 6324                | CompletionSource::Dap { .. }
 6325                | CompletionSource::Custom => {
 6326                    return Ok(());
 6327                }
 6328            }
 6329        };
 6330        let resolved_completion = request
 6331            .await
 6332            .into_response()
 6333            .context("resolve completion")?;
 6334
 6335        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6336        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6337
 6338        let mut completions = completions.borrow_mut();
 6339        let completion = &mut completions[completion_index];
 6340        if let CompletionSource::Lsp {
 6341            lsp_completion,
 6342            resolved,
 6343            server_id: completion_server_id,
 6344            ..
 6345        } = &mut completion.source
 6346        {
 6347            if *resolved {
 6348                return Ok(());
 6349            }
 6350            anyhow::ensure!(
 6351                server_id == *completion_server_id,
 6352                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6353            );
 6354            *lsp_completion = Box::new(resolved_completion);
 6355            *resolved = true;
 6356        }
 6357        Ok(())
 6358    }
 6359
 6360    async fn regenerate_completion_labels(
 6361        adapter: Arc<CachedLspAdapter>,
 6362        snapshot: &BufferSnapshot,
 6363        completions: Rc<RefCell<Box<[Completion]>>>,
 6364        completion_index: usize,
 6365    ) -> Result<()> {
 6366        let completion_item = completions.borrow()[completion_index]
 6367            .source
 6368            .lsp_completion(true)
 6369            .map(Cow::into_owned);
 6370        if let Some(lsp_documentation) = completion_item
 6371            .as_ref()
 6372            .and_then(|completion_item| completion_item.documentation.clone())
 6373        {
 6374            let mut completions = completions.borrow_mut();
 6375            let completion = &mut completions[completion_index];
 6376            completion.documentation = Some(lsp_documentation.into());
 6377        } else {
 6378            let mut completions = completions.borrow_mut();
 6379            let completion = &mut completions[completion_index];
 6380            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6381        }
 6382
 6383        let mut new_label = match completion_item {
 6384            Some(completion_item) => {
 6385                // 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
 6386                // So we have to update the label here anyway...
 6387                let language = snapshot.language();
 6388                match language {
 6389                    Some(language) => {
 6390                        adapter
 6391                            .labels_for_completions(
 6392                                std::slice::from_ref(&completion_item),
 6393                                language,
 6394                            )
 6395                            .await?
 6396                    }
 6397                    None => Vec::new(),
 6398                }
 6399                .pop()
 6400                .flatten()
 6401                .unwrap_or_else(|| {
 6402                    CodeLabel::fallback_for_completion(
 6403                        &completion_item,
 6404                        language.map(|language| language.as_ref()),
 6405                    )
 6406                })
 6407            }
 6408            None => CodeLabel::plain(
 6409                completions.borrow()[completion_index].new_text.clone(),
 6410                None,
 6411            ),
 6412        };
 6413        ensure_uniform_list_compatible_label(&mut new_label);
 6414
 6415        let mut completions = completions.borrow_mut();
 6416        let completion = &mut completions[completion_index];
 6417        if completion.label.filter_text() == new_label.filter_text() {
 6418            completion.label = new_label;
 6419        } else {
 6420            log::error!(
 6421                "Resolved completion changed display label from {} to {}. \
 6422                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6423                completion.label.text(),
 6424                new_label.text(),
 6425                completion.label.filter_text(),
 6426                new_label.filter_text()
 6427            );
 6428        }
 6429
 6430        Ok(())
 6431    }
 6432
 6433    async fn resolve_completion_remote(
 6434        project_id: u64,
 6435        server_id: LanguageServerId,
 6436        buffer_id: BufferId,
 6437        completions: Rc<RefCell<Box<[Completion]>>>,
 6438        completion_index: usize,
 6439        client: AnyProtoClient,
 6440    ) -> Result<()> {
 6441        let lsp_completion = {
 6442            let completion = &completions.borrow()[completion_index];
 6443            match &completion.source {
 6444                CompletionSource::Lsp {
 6445                    lsp_completion,
 6446                    resolved,
 6447                    server_id: completion_server_id,
 6448                    ..
 6449                } => {
 6450                    anyhow::ensure!(
 6451                        server_id == *completion_server_id,
 6452                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6453                    );
 6454                    if *resolved {
 6455                        return Ok(());
 6456                    }
 6457                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6458                }
 6459                CompletionSource::Custom
 6460                | CompletionSource::Dap { .. }
 6461                | CompletionSource::BufferWord { .. } => {
 6462                    return Ok(());
 6463                }
 6464            }
 6465        };
 6466        let request = proto::ResolveCompletionDocumentation {
 6467            project_id,
 6468            language_server_id: server_id.0 as u64,
 6469            lsp_completion,
 6470            buffer_id: buffer_id.into(),
 6471        };
 6472
 6473        let response = client
 6474            .request(request)
 6475            .await
 6476            .context("completion documentation resolve proto request")?;
 6477        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6478
 6479        let documentation = if response.documentation.is_empty() {
 6480            CompletionDocumentation::Undocumented
 6481        } else if response.documentation_is_markdown {
 6482            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6483        } else if response.documentation.lines().count() <= 1 {
 6484            CompletionDocumentation::SingleLine(response.documentation.into())
 6485        } else {
 6486            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6487        };
 6488
 6489        let mut completions = completions.borrow_mut();
 6490        let completion = &mut completions[completion_index];
 6491        completion.documentation = Some(documentation);
 6492        if let CompletionSource::Lsp {
 6493            insert_range,
 6494            lsp_completion,
 6495            resolved,
 6496            server_id: completion_server_id,
 6497            lsp_defaults: _,
 6498        } = &mut completion.source
 6499        {
 6500            let completion_insert_range = response
 6501                .old_insert_start
 6502                .and_then(deserialize_anchor)
 6503                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6504            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6505
 6506            if *resolved {
 6507                return Ok(());
 6508            }
 6509            anyhow::ensure!(
 6510                server_id == *completion_server_id,
 6511                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6512            );
 6513            *lsp_completion = Box::new(resolved_lsp_completion);
 6514            *resolved = true;
 6515        }
 6516
 6517        let replace_range = response
 6518            .old_replace_start
 6519            .and_then(deserialize_anchor)
 6520            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6521        if let Some((old_replace_start, old_replace_end)) = replace_range
 6522            && !response.new_text.is_empty()
 6523        {
 6524            completion.new_text = response.new_text;
 6525            completion.replace_range = old_replace_start..old_replace_end;
 6526        }
 6527
 6528        Ok(())
 6529    }
 6530
 6531    pub fn apply_additional_edits_for_completion(
 6532        &self,
 6533        buffer_handle: Entity<Buffer>,
 6534        completions: Rc<RefCell<Box<[Completion]>>>,
 6535        completion_index: usize,
 6536        push_to_history: bool,
 6537        cx: &mut Context<Self>,
 6538    ) -> Task<Result<Option<Transaction>>> {
 6539        if let Some((client, project_id)) = self.upstream_client() {
 6540            let buffer = buffer_handle.read(cx);
 6541            let buffer_id = buffer.remote_id();
 6542            cx.spawn(async move |_, cx| {
 6543                let request = {
 6544                    let completion = completions.borrow()[completion_index].clone();
 6545                    proto::ApplyCompletionAdditionalEdits {
 6546                        project_id,
 6547                        buffer_id: buffer_id.into(),
 6548                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6549                            replace_range: completion.replace_range,
 6550                            new_text: completion.new_text,
 6551                            source: completion.source,
 6552                        })),
 6553                    }
 6554                };
 6555
 6556                if let Some(transaction) = client.request(request).await?.transaction {
 6557                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6558                    buffer_handle
 6559                        .update(cx, |buffer, _| {
 6560                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6561                        })?
 6562                        .await?;
 6563                    if push_to_history {
 6564                        buffer_handle.update(cx, |buffer, _| {
 6565                            buffer.push_transaction(transaction.clone(), Instant::now());
 6566                            buffer.finalize_last_transaction();
 6567                        })?;
 6568                    }
 6569                    Ok(Some(transaction))
 6570                } else {
 6571                    Ok(None)
 6572                }
 6573            })
 6574        } else {
 6575            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6576                let completion = &completions.borrow()[completion_index];
 6577                let server_id = completion.source.server_id()?;
 6578                Some(
 6579                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6580                        .1
 6581                        .clone(),
 6582                )
 6583            }) else {
 6584                return Task::ready(Ok(None));
 6585            };
 6586
 6587            cx.spawn(async move |this, cx| {
 6588                Self::resolve_completion_local(
 6589                    server.clone(),
 6590                    completions.clone(),
 6591                    completion_index,
 6592                )
 6593                .await
 6594                .context("resolving completion")?;
 6595                let completion = completions.borrow()[completion_index].clone();
 6596                let additional_text_edits = completion
 6597                    .source
 6598                    .lsp_completion(true)
 6599                    .as_ref()
 6600                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6601                if let Some(edits) = additional_text_edits {
 6602                    let edits = this
 6603                        .update(cx, |this, cx| {
 6604                            this.as_local_mut().unwrap().edits_from_lsp(
 6605                                &buffer_handle,
 6606                                edits,
 6607                                server.server_id(),
 6608                                None,
 6609                                cx,
 6610                            )
 6611                        })?
 6612                        .await?;
 6613
 6614                    buffer_handle.update(cx, |buffer, cx| {
 6615                        buffer.finalize_last_transaction();
 6616                        buffer.start_transaction();
 6617
 6618                        for (range, text) in edits {
 6619                            let primary = &completion.replace_range;
 6620
 6621                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6622                            // and the primary completion is just an insertion (empty range), then this is likely
 6623                            // an auto-import scenario and should not be considered overlapping
 6624                            // https://github.com/zed-industries/zed/issues/26136
 6625                            let is_file_start_auto_import = {
 6626                                let snapshot = buffer.snapshot();
 6627                                let primary_start_point = primary.start.to_point(&snapshot);
 6628                                let range_start_point = range.start.to_point(&snapshot);
 6629
 6630                                let result = primary_start_point.row == 0
 6631                                    && primary_start_point.column == 0
 6632                                    && range_start_point.row == 0
 6633                                    && range_start_point.column == 0;
 6634
 6635                                result
 6636                            };
 6637
 6638                            let has_overlap = if is_file_start_auto_import {
 6639                                false
 6640                            } else {
 6641                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6642                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6643                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6644                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6645                                let result = start_within || end_within;
 6646                                result
 6647                            };
 6648
 6649                            //Skip additional edits which overlap with the primary completion edit
 6650                            //https://github.com/zed-industries/zed/pull/1871
 6651                            if !has_overlap {
 6652                                buffer.edit([(range, text)], None, cx);
 6653                            }
 6654                        }
 6655
 6656                        let transaction = if buffer.end_transaction(cx).is_some() {
 6657                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6658                            if !push_to_history {
 6659                                buffer.forget_transaction(transaction.id);
 6660                            }
 6661                            Some(transaction)
 6662                        } else {
 6663                            None
 6664                        };
 6665                        Ok(transaction)
 6666                    })?
 6667                } else {
 6668                    Ok(None)
 6669                }
 6670            })
 6671        }
 6672    }
 6673
 6674    pub fn pull_diagnostics(
 6675        &mut self,
 6676        buffer: Entity<Buffer>,
 6677        cx: &mut Context<Self>,
 6678    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6679        let buffer_id = buffer.read(cx).remote_id();
 6680
 6681        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6682            let mut suitable_capabilities = None;
 6683            // Are we capable for proto request?
 6684            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6685                &buffer,
 6686                |capabilities| {
 6687                    if let Some(caps) = &capabilities.diagnostic_provider {
 6688                        suitable_capabilities = Some(caps.clone());
 6689                        true
 6690                    } else {
 6691                        false
 6692                    }
 6693                },
 6694                cx,
 6695            );
 6696            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6697            let Some(dynamic_caps) = suitable_capabilities else {
 6698                return Task::ready(Ok(None));
 6699            };
 6700            assert!(any_server_has_diagnostics_provider);
 6701
 6702            let request = GetDocumentDiagnostics {
 6703                previous_result_id: None,
 6704                dynamic_caps,
 6705            };
 6706            let request_task = client.request_lsp(
 6707                upstream_project_id,
 6708                None,
 6709                LSP_REQUEST_TIMEOUT,
 6710                cx.background_executor().clone(),
 6711                request.to_proto(upstream_project_id, buffer.read(cx)),
 6712            );
 6713            cx.background_spawn(async move {
 6714                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6715                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6716                // Do not attempt to further process the dummy responses here.
 6717                let _response = request_task.await?;
 6718                Ok(None)
 6719            })
 6720        } else {
 6721            let servers = buffer.update(cx, |buffer, cx| {
 6722                self.language_servers_for_local_buffer(buffer, cx)
 6723                    .map(|(_, server)| server.clone())
 6724                    .collect::<Vec<_>>()
 6725            });
 6726
 6727            let pull_diagnostics = servers
 6728                .into_iter()
 6729                .flat_map(|server| {
 6730                    let result = maybe!({
 6731                        let local = self.as_local()?;
 6732                        let server_id = server.server_id();
 6733                        let providers_with_identifiers = local
 6734                            .language_server_dynamic_registrations
 6735                            .get(&server_id)
 6736                            .into_iter()
 6737                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6738                            .collect::<Vec<_>>();
 6739                        Some(
 6740                            providers_with_identifiers
 6741                                .into_iter()
 6742                                .map(|dynamic_caps| {
 6743                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6744                                    self.request_lsp(
 6745                                        buffer.clone(),
 6746                                        LanguageServerToQuery::Other(server_id),
 6747                                        GetDocumentDiagnostics {
 6748                                            previous_result_id: result_id,
 6749                                            dynamic_caps,
 6750                                        },
 6751                                        cx,
 6752                                    )
 6753                                })
 6754                                .collect::<Vec<_>>(),
 6755                        )
 6756                    });
 6757
 6758                    result.unwrap_or_default()
 6759                })
 6760                .collect::<Vec<_>>();
 6761
 6762            cx.background_spawn(async move {
 6763                let mut responses = Vec::new();
 6764                for diagnostics in join_all(pull_diagnostics).await {
 6765                    responses.extend(diagnostics?);
 6766                }
 6767                Ok(Some(responses))
 6768            })
 6769        }
 6770    }
 6771
 6772    pub fn applicable_inlay_chunks(
 6773        &mut self,
 6774        buffer: &Entity<Buffer>,
 6775        ranges: &[Range<text::Anchor>],
 6776        cx: &mut Context<Self>,
 6777    ) -> Vec<Range<BufferRow>> {
 6778        self.latest_lsp_data(buffer, cx)
 6779            .inlay_hints
 6780            .applicable_chunks(ranges)
 6781            .map(|chunk| chunk.row_range())
 6782            .collect()
 6783    }
 6784
 6785    pub fn invalidate_inlay_hints<'a>(
 6786        &'a mut self,
 6787        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6788    ) {
 6789        for buffer_id in for_buffers {
 6790            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6791                lsp_data.inlay_hints.clear();
 6792            }
 6793        }
 6794    }
 6795
 6796    pub fn inlay_hints(
 6797        &mut self,
 6798        invalidate: InvalidationStrategy,
 6799        buffer: Entity<Buffer>,
 6800        ranges: Vec<Range<text::Anchor>>,
 6801        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6802        cx: &mut Context<Self>,
 6803    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6804        let next_hint_id = self.next_hint_id.clone();
 6805        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6806        let query_version = lsp_data.buffer_version.clone();
 6807        let mut lsp_refresh_requested = false;
 6808        let for_server = if let InvalidationStrategy::RefreshRequested {
 6809            server_id,
 6810            request_id,
 6811        } = invalidate
 6812        {
 6813            let invalidated = lsp_data
 6814                .inlay_hints
 6815                .invalidate_for_server_refresh(server_id, request_id);
 6816            lsp_refresh_requested = invalidated;
 6817            Some(server_id)
 6818        } else {
 6819            None
 6820        };
 6821        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6822        let known_chunks = known_chunks
 6823            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6824            .map(|(_, known_chunks)| known_chunks)
 6825            .unwrap_or_default();
 6826
 6827        let mut hint_fetch_tasks = Vec::new();
 6828        let mut cached_inlay_hints = None;
 6829        let mut ranges_to_query = None;
 6830        let applicable_chunks = existing_inlay_hints
 6831            .applicable_chunks(ranges.as_slice())
 6832            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6833            .collect::<Vec<_>>();
 6834        if applicable_chunks.is_empty() {
 6835            return HashMap::default();
 6836        }
 6837
 6838        for row_chunk in applicable_chunks {
 6839            match (
 6840                existing_inlay_hints
 6841                    .cached_hints(&row_chunk)
 6842                    .filter(|_| !lsp_refresh_requested)
 6843                    .cloned(),
 6844                existing_inlay_hints
 6845                    .fetched_hints(&row_chunk)
 6846                    .as_ref()
 6847                    .filter(|_| !lsp_refresh_requested)
 6848                    .cloned(),
 6849            ) {
 6850                (None, None) => {
 6851                    let Some(chunk_range) = existing_inlay_hints.chunk_range(row_chunk) else {
 6852                        continue;
 6853                    };
 6854                    ranges_to_query
 6855                        .get_or_insert_with(Vec::new)
 6856                        .push((row_chunk, chunk_range));
 6857                }
 6858                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6859                (Some(cached_hints), None) => {
 6860                    for (server_id, cached_hints) in cached_hints {
 6861                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6862                            cached_inlay_hints
 6863                                .get_or_insert_with(HashMap::default)
 6864                                .entry(row_chunk.row_range())
 6865                                .or_insert_with(HashMap::default)
 6866                                .entry(server_id)
 6867                                .or_insert_with(Vec::new)
 6868                                .extend(cached_hints);
 6869                        }
 6870                    }
 6871                }
 6872                (Some(cached_hints), Some(fetched_hints)) => {
 6873                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6874                    for (server_id, cached_hints) in cached_hints {
 6875                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6876                            cached_inlay_hints
 6877                                .get_or_insert_with(HashMap::default)
 6878                                .entry(row_chunk.row_range())
 6879                                .or_insert_with(HashMap::default)
 6880                                .entry(server_id)
 6881                                .or_insert_with(Vec::new)
 6882                                .extend(cached_hints);
 6883                        }
 6884                    }
 6885                }
 6886            }
 6887        }
 6888
 6889        if hint_fetch_tasks.is_empty()
 6890            && ranges_to_query
 6891                .as_ref()
 6892                .is_none_or(|ranges| ranges.is_empty())
 6893            && let Some(cached_inlay_hints) = cached_inlay_hints
 6894        {
 6895            cached_inlay_hints
 6896                .into_iter()
 6897                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6898                .collect()
 6899        } else {
 6900            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6901                let next_hint_id = next_hint_id.clone();
 6902                let buffer = buffer.clone();
 6903                let query_version = query_version.clone();
 6904                let new_inlay_hints = cx
 6905                    .spawn(async move |lsp_store, cx| {
 6906                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6907                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6908                        })?;
 6909                        new_fetch_task
 6910                            .await
 6911                            .and_then(|new_hints_by_server| {
 6912                                lsp_store.update(cx, |lsp_store, cx| {
 6913                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6914                                    let update_cache = lsp_data.buffer_version == query_version;
 6915                                    if new_hints_by_server.is_empty() {
 6916                                        if update_cache {
 6917                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6918                                        }
 6919                                        HashMap::default()
 6920                                    } else {
 6921                                        new_hints_by_server
 6922                                            .into_iter()
 6923                                            .map(|(server_id, new_hints)| {
 6924                                                let new_hints = new_hints
 6925                                                    .into_iter()
 6926                                                    .map(|new_hint| {
 6927                                                        (
 6928                                                            InlayId::Hint(next_hint_id.fetch_add(
 6929                                                                1,
 6930                                                                atomic::Ordering::AcqRel,
 6931                                                            )),
 6932                                                            new_hint,
 6933                                                        )
 6934                                                    })
 6935                                                    .collect::<Vec<_>>();
 6936                                                if update_cache {
 6937                                                    lsp_data.inlay_hints.insert_new_hints(
 6938                                                        chunk,
 6939                                                        server_id,
 6940                                                        new_hints.clone(),
 6941                                                    );
 6942                                                }
 6943                                                (server_id, new_hints)
 6944                                            })
 6945                                            .collect()
 6946                                    }
 6947                                })
 6948                            })
 6949                            .map_err(Arc::new)
 6950                    })
 6951                    .shared();
 6952
 6953                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6954                *fetch_task = Some(new_inlay_hints.clone());
 6955                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6956            }
 6957
 6958            cached_inlay_hints
 6959                .unwrap_or_default()
 6960                .into_iter()
 6961                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6962                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6963                    (
 6964                        chunk.row_range(),
 6965                        cx.spawn(async move |_, _| {
 6966                            hints_fetch.await.map_err(|e| {
 6967                                if e.error_code() != ErrorCode::Internal {
 6968                                    anyhow!(e.error_code())
 6969                                } else {
 6970                                    anyhow!("{e:#}")
 6971                                }
 6972                            })
 6973                        }),
 6974                    )
 6975                }))
 6976                .collect()
 6977        }
 6978    }
 6979
 6980    fn fetch_inlay_hints(
 6981        &mut self,
 6982        for_server: Option<LanguageServerId>,
 6983        buffer: &Entity<Buffer>,
 6984        range: Range<Anchor>,
 6985        cx: &mut Context<Self>,
 6986    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6987        let request = InlayHints {
 6988            range: range.clone(),
 6989        };
 6990        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6991            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6992                return Task::ready(Ok(HashMap::default()));
 6993            }
 6994            let request_task = upstream_client.request_lsp(
 6995                project_id,
 6996                for_server.map(|id| id.to_proto()),
 6997                LSP_REQUEST_TIMEOUT,
 6998                cx.background_executor().clone(),
 6999                request.to_proto(project_id, buffer.read(cx)),
 7000            );
 7001            let buffer = buffer.clone();
 7002            cx.spawn(async move |weak_lsp_store, cx| {
 7003                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7004                    return Ok(HashMap::default());
 7005                };
 7006                let Some(responses) = request_task.await? else {
 7007                    return Ok(HashMap::default());
 7008                };
 7009
 7010                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7011                    let lsp_store = lsp_store.clone();
 7012                    let buffer = buffer.clone();
 7013                    let cx = cx.clone();
 7014                    let request = request.clone();
 7015                    async move {
 7016                        (
 7017                            LanguageServerId::from_proto(response.server_id),
 7018                            request
 7019                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7020                                .await,
 7021                        )
 7022                    }
 7023                }))
 7024                .await;
 7025
 7026                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7027                let mut has_errors = false;
 7028                let inlay_hints = inlay_hints
 7029                    .into_iter()
 7030                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7031                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7032                        Err(e) => {
 7033                            has_errors = true;
 7034                            log::error!("{e:#}");
 7035                            None
 7036                        }
 7037                    })
 7038                    .map(|(server_id, mut new_hints)| {
 7039                        new_hints.retain(|hint| {
 7040                            hint.position.is_valid(&buffer_snapshot)
 7041                                && range.start.is_valid(&buffer_snapshot)
 7042                                && range.end.is_valid(&buffer_snapshot)
 7043                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7044                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7045                        });
 7046                        (server_id, new_hints)
 7047                    })
 7048                    .collect::<HashMap<_, _>>();
 7049                anyhow::ensure!(
 7050                    !has_errors || !inlay_hints.is_empty(),
 7051                    "Failed to fetch inlay hints"
 7052                );
 7053                Ok(inlay_hints)
 7054            })
 7055        } else {
 7056            let inlay_hints_task = match for_server {
 7057                Some(server_id) => {
 7058                    let server_task = self.request_lsp(
 7059                        buffer.clone(),
 7060                        LanguageServerToQuery::Other(server_id),
 7061                        request,
 7062                        cx,
 7063                    );
 7064                    cx.background_spawn(async move {
 7065                        let mut responses = Vec::new();
 7066                        match server_task.await {
 7067                            Ok(response) => responses.push((server_id, response)),
 7068                            // rust-analyzer likes to error with this when its still loading up
 7069                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7070                            Err(e) => log::error!(
 7071                                "Error handling response for inlay hints request: {e:#}"
 7072                            ),
 7073                        }
 7074                        responses
 7075                    })
 7076                }
 7077                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7078            };
 7079            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7080            cx.background_spawn(async move {
 7081                Ok(inlay_hints_task
 7082                    .await
 7083                    .into_iter()
 7084                    .map(|(server_id, mut new_hints)| {
 7085                        new_hints.retain(|hint| {
 7086                            hint.position.is_valid(&buffer_snapshot)
 7087                                && range.start.is_valid(&buffer_snapshot)
 7088                                && range.end.is_valid(&buffer_snapshot)
 7089                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7090                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7091                        });
 7092                        (server_id, new_hints)
 7093                    })
 7094                    .collect())
 7095            })
 7096        }
 7097    }
 7098
 7099    pub fn pull_diagnostics_for_buffer(
 7100        &mut self,
 7101        buffer: Entity<Buffer>,
 7102        cx: &mut Context<Self>,
 7103    ) -> Task<anyhow::Result<()>> {
 7104        let diagnostics = self.pull_diagnostics(buffer, cx);
 7105        cx.spawn(async move |lsp_store, cx| {
 7106            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7107                return Ok(());
 7108            };
 7109            lsp_store.update(cx, |lsp_store, cx| {
 7110                if lsp_store.as_local().is_none() {
 7111                    return;
 7112                }
 7113
 7114                let mut unchanged_buffers = HashSet::default();
 7115                let mut changed_buffers = HashSet::default();
 7116                let server_diagnostics_updates = diagnostics
 7117                    .into_iter()
 7118                    .filter_map(|diagnostics_set| match diagnostics_set {
 7119                        LspPullDiagnostics::Response {
 7120                            server_id,
 7121                            uri,
 7122                            diagnostics,
 7123                        } => Some((server_id, uri, diagnostics)),
 7124                        LspPullDiagnostics::Default => None,
 7125                    })
 7126                    .fold(
 7127                        HashMap::default(),
 7128                        |mut acc, (server_id, uri, diagnostics)| {
 7129                            let (result_id, diagnostics) = match diagnostics {
 7130                                PulledDiagnostics::Unchanged { result_id } => {
 7131                                    unchanged_buffers.insert(uri.clone());
 7132                                    (Some(result_id), Vec::new())
 7133                                }
 7134                                PulledDiagnostics::Changed {
 7135                                    result_id,
 7136                                    diagnostics,
 7137                                } => {
 7138                                    changed_buffers.insert(uri.clone());
 7139                                    (result_id, diagnostics)
 7140                                }
 7141                            };
 7142                            let disk_based_sources = Cow::Owned(
 7143                                lsp_store
 7144                                    .language_server_adapter_for_id(server_id)
 7145                                    .as_ref()
 7146                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7147                                    .unwrap_or(&[])
 7148                                    .to_vec(),
 7149                            );
 7150                            acc.entry(server_id).or_insert_with(Vec::new).push(
 7151                                DocumentDiagnosticsUpdate {
 7152                                    server_id,
 7153                                    diagnostics: lsp::PublishDiagnosticsParams {
 7154                                        uri,
 7155                                        diagnostics,
 7156                                        version: None,
 7157                                    },
 7158                                    result_id,
 7159                                    disk_based_sources,
 7160                                },
 7161                            );
 7162                            acc
 7163                        },
 7164                    );
 7165
 7166                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7167                    lsp_store
 7168                        .merge_lsp_diagnostics(
 7169                            DiagnosticSourceKind::Pulled,
 7170                            diagnostic_updates,
 7171                            |buffer, old_diagnostic, cx| {
 7172                                File::from_dyn(buffer.file())
 7173                                    .and_then(|file| {
 7174                                        let abs_path = file.as_local()?.abs_path(cx);
 7175                                        lsp::Uri::from_file_path(abs_path).ok()
 7176                                    })
 7177                                    .is_none_or(|buffer_uri| {
 7178                                        unchanged_buffers.contains(&buffer_uri)
 7179                                            || match old_diagnostic.source_kind {
 7180                                                DiagnosticSourceKind::Pulled => {
 7181                                                    !changed_buffers.contains(&buffer_uri)
 7182                                                }
 7183                                                DiagnosticSourceKind::Other
 7184                                                | DiagnosticSourceKind::Pushed => true,
 7185                                            }
 7186                                    })
 7187                            },
 7188                            cx,
 7189                        )
 7190                        .log_err();
 7191                }
 7192            })
 7193        })
 7194    }
 7195
 7196    pub fn document_colors(
 7197        &mut self,
 7198        known_cache_version: Option<usize>,
 7199        buffer: Entity<Buffer>,
 7200        cx: &mut Context<Self>,
 7201    ) -> Option<DocumentColorTask> {
 7202        let version_queried_for = buffer.read(cx).version();
 7203        let buffer_id = buffer.read(cx).remote_id();
 7204
 7205        let current_language_servers = self.as_local().map(|local| {
 7206            local
 7207                .buffers_opened_in_servers
 7208                .get(&buffer_id)
 7209                .cloned()
 7210                .unwrap_or_default()
 7211        });
 7212
 7213        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7214            if let Some(cached_colors) = &lsp_data.document_colors {
 7215                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7216                    let has_different_servers =
 7217                        current_language_servers.is_some_and(|current_language_servers| {
 7218                            current_language_servers
 7219                                != cached_colors.colors.keys().copied().collect()
 7220                        });
 7221                    if !has_different_servers {
 7222                        let cache_version = cached_colors.cache_version;
 7223                        if Some(cache_version) == known_cache_version {
 7224                            return None;
 7225                        } else {
 7226                            return Some(
 7227                                Task::ready(Ok(DocumentColors {
 7228                                    colors: cached_colors
 7229                                        .colors
 7230                                        .values()
 7231                                        .flatten()
 7232                                        .cloned()
 7233                                        .collect(),
 7234                                    cache_version: Some(cache_version),
 7235                                }))
 7236                                .shared(),
 7237                            );
 7238                        }
 7239                    }
 7240                }
 7241            }
 7242        }
 7243
 7244        let color_lsp_data = self
 7245            .latest_lsp_data(&buffer, cx)
 7246            .document_colors
 7247            .get_or_insert_default();
 7248        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7249            && !version_queried_for.changed_since(updating_for)
 7250        {
 7251            return Some(running_update.clone());
 7252        }
 7253        let buffer_version_queried_for = version_queried_for.clone();
 7254        let new_task = cx
 7255            .spawn(async move |lsp_store, cx| {
 7256                cx.background_executor()
 7257                    .timer(Duration::from_millis(30))
 7258                    .await;
 7259                let fetched_colors = lsp_store
 7260                    .update(cx, |lsp_store, cx| {
 7261                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7262                    })?
 7263                    .await
 7264                    .context("fetching document colors")
 7265                    .map_err(Arc::new);
 7266                let fetched_colors = match fetched_colors {
 7267                    Ok(fetched_colors) => {
 7268                        if Some(true)
 7269                            == buffer
 7270                                .update(cx, |buffer, _| {
 7271                                    buffer.version() != buffer_version_queried_for
 7272                                })
 7273                                .ok()
 7274                        {
 7275                            return Ok(DocumentColors::default());
 7276                        }
 7277                        fetched_colors
 7278                    }
 7279                    Err(e) => {
 7280                        lsp_store
 7281                            .update(cx, |lsp_store, _| {
 7282                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7283                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7284                                        document_colors.colors_update = None;
 7285                                    }
 7286                                }
 7287                            })
 7288                            .ok();
 7289                        return Err(e);
 7290                    }
 7291                };
 7292
 7293                lsp_store
 7294                    .update(cx, |lsp_store, cx| {
 7295                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7296                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7297
 7298                        if let Some(fetched_colors) = fetched_colors {
 7299                            if lsp_data.buffer_version == buffer_version_queried_for {
 7300                                lsp_colors.colors.extend(fetched_colors);
 7301                                lsp_colors.cache_version += 1;
 7302                            } else if !lsp_data
 7303                                .buffer_version
 7304                                .changed_since(&buffer_version_queried_for)
 7305                            {
 7306                                lsp_data.buffer_version = buffer_version_queried_for;
 7307                                lsp_colors.colors = fetched_colors;
 7308                                lsp_colors.cache_version += 1;
 7309                            }
 7310                        }
 7311                        lsp_colors.colors_update = None;
 7312                        let colors = lsp_colors
 7313                            .colors
 7314                            .values()
 7315                            .flatten()
 7316                            .cloned()
 7317                            .collect::<HashSet<_>>();
 7318                        DocumentColors {
 7319                            colors,
 7320                            cache_version: Some(lsp_colors.cache_version),
 7321                        }
 7322                    })
 7323                    .map_err(Arc::new)
 7324            })
 7325            .shared();
 7326        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7327        Some(new_task)
 7328    }
 7329
 7330    fn fetch_document_colors_for_buffer(
 7331        &mut self,
 7332        buffer: &Entity<Buffer>,
 7333        cx: &mut Context<Self>,
 7334    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7335        if let Some((client, project_id)) = self.upstream_client() {
 7336            let request = GetDocumentColor {};
 7337            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7338                return Task::ready(Ok(None));
 7339            }
 7340
 7341            let request_task = client.request_lsp(
 7342                project_id,
 7343                None,
 7344                LSP_REQUEST_TIMEOUT,
 7345                cx.background_executor().clone(),
 7346                request.to_proto(project_id, buffer.read(cx)),
 7347            );
 7348            let buffer = buffer.clone();
 7349            cx.spawn(async move |lsp_store, cx| {
 7350                let Some(lsp_store) = lsp_store.upgrade() else {
 7351                    return Ok(None);
 7352                };
 7353                let colors = join_all(
 7354                    request_task
 7355                        .await
 7356                        .log_err()
 7357                        .flatten()
 7358                        .map(|response| response.payload)
 7359                        .unwrap_or_default()
 7360                        .into_iter()
 7361                        .map(|color_response| {
 7362                            let response = request.response_from_proto(
 7363                                color_response.response,
 7364                                lsp_store.clone(),
 7365                                buffer.clone(),
 7366                                cx.clone(),
 7367                            );
 7368                            async move {
 7369                                (
 7370                                    LanguageServerId::from_proto(color_response.server_id),
 7371                                    response.await.log_err().unwrap_or_default(),
 7372                                )
 7373                            }
 7374                        }),
 7375                )
 7376                .await
 7377                .into_iter()
 7378                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7379                    acc.entry(server_id)
 7380                        .or_insert_with(HashSet::default)
 7381                        .extend(colors);
 7382                    acc
 7383                });
 7384                Ok(Some(colors))
 7385            })
 7386        } else {
 7387            let document_colors_task =
 7388                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7389            cx.background_spawn(async move {
 7390                Ok(Some(
 7391                    document_colors_task
 7392                        .await
 7393                        .into_iter()
 7394                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7395                            acc.entry(server_id)
 7396                                .or_insert_with(HashSet::default)
 7397                                .extend(colors);
 7398                            acc
 7399                        })
 7400                        .into_iter()
 7401                        .collect(),
 7402                ))
 7403            })
 7404        }
 7405    }
 7406
 7407    pub fn signature_help<T: ToPointUtf16>(
 7408        &mut self,
 7409        buffer: &Entity<Buffer>,
 7410        position: T,
 7411        cx: &mut Context<Self>,
 7412    ) -> Task<Option<Vec<SignatureHelp>>> {
 7413        let position = position.to_point_utf16(buffer.read(cx));
 7414
 7415        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7416            let request = GetSignatureHelp { position };
 7417            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7418                return Task::ready(None);
 7419            }
 7420            let request_task = client.request_lsp(
 7421                upstream_project_id,
 7422                None,
 7423                LSP_REQUEST_TIMEOUT,
 7424                cx.background_executor().clone(),
 7425                request.to_proto(upstream_project_id, buffer.read(cx)),
 7426            );
 7427            let buffer = buffer.clone();
 7428            cx.spawn(async move |weak_lsp_store, cx| {
 7429                let lsp_store = weak_lsp_store.upgrade()?;
 7430                let signatures = join_all(
 7431                    request_task
 7432                        .await
 7433                        .log_err()
 7434                        .flatten()
 7435                        .map(|response| response.payload)
 7436                        .unwrap_or_default()
 7437                        .into_iter()
 7438                        .map(|response| {
 7439                            let response = GetSignatureHelp { position }.response_from_proto(
 7440                                response.response,
 7441                                lsp_store.clone(),
 7442                                buffer.clone(),
 7443                                cx.clone(),
 7444                            );
 7445                            async move { response.await.log_err().flatten() }
 7446                        }),
 7447                )
 7448                .await
 7449                .into_iter()
 7450                .flatten()
 7451                .collect();
 7452                Some(signatures)
 7453            })
 7454        } else {
 7455            let all_actions_task = self.request_multiple_lsp_locally(
 7456                buffer,
 7457                Some(position),
 7458                GetSignatureHelp { position },
 7459                cx,
 7460            );
 7461            cx.background_spawn(async move {
 7462                Some(
 7463                    all_actions_task
 7464                        .await
 7465                        .into_iter()
 7466                        .flat_map(|(_, actions)| actions)
 7467                        .collect::<Vec<_>>(),
 7468                )
 7469            })
 7470        }
 7471    }
 7472
 7473    pub fn hover(
 7474        &mut self,
 7475        buffer: &Entity<Buffer>,
 7476        position: PointUtf16,
 7477        cx: &mut Context<Self>,
 7478    ) -> Task<Option<Vec<Hover>>> {
 7479        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7480            let request = GetHover { position };
 7481            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7482                return Task::ready(None);
 7483            }
 7484            let request_task = client.request_lsp(
 7485                upstream_project_id,
 7486                None,
 7487                LSP_REQUEST_TIMEOUT,
 7488                cx.background_executor().clone(),
 7489                request.to_proto(upstream_project_id, buffer.read(cx)),
 7490            );
 7491            let buffer = buffer.clone();
 7492            cx.spawn(async move |weak_lsp_store, cx| {
 7493                let lsp_store = weak_lsp_store.upgrade()?;
 7494                let hovers = join_all(
 7495                    request_task
 7496                        .await
 7497                        .log_err()
 7498                        .flatten()
 7499                        .map(|response| response.payload)
 7500                        .unwrap_or_default()
 7501                        .into_iter()
 7502                        .map(|response| {
 7503                            let response = GetHover { position }.response_from_proto(
 7504                                response.response,
 7505                                lsp_store.clone(),
 7506                                buffer.clone(),
 7507                                cx.clone(),
 7508                            );
 7509                            async move {
 7510                                response
 7511                                    .await
 7512                                    .log_err()
 7513                                    .flatten()
 7514                                    .and_then(remove_empty_hover_blocks)
 7515                            }
 7516                        }),
 7517                )
 7518                .await
 7519                .into_iter()
 7520                .flatten()
 7521                .collect();
 7522                Some(hovers)
 7523            })
 7524        } else {
 7525            let all_actions_task = self.request_multiple_lsp_locally(
 7526                buffer,
 7527                Some(position),
 7528                GetHover { position },
 7529                cx,
 7530            );
 7531            cx.background_spawn(async move {
 7532                Some(
 7533                    all_actions_task
 7534                        .await
 7535                        .into_iter()
 7536                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7537                        .collect::<Vec<Hover>>(),
 7538                )
 7539            })
 7540        }
 7541    }
 7542
 7543    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7544        let language_registry = self.languages.clone();
 7545
 7546        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7547            let request = upstream_client.request(proto::GetProjectSymbols {
 7548                project_id: *project_id,
 7549                query: query.to_string(),
 7550            });
 7551            cx.foreground_executor().spawn(async move {
 7552                let response = request.await?;
 7553                let mut symbols = Vec::new();
 7554                let core_symbols = response
 7555                    .symbols
 7556                    .into_iter()
 7557                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7558                    .collect::<Vec<_>>();
 7559                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7560                    .await;
 7561                Ok(symbols)
 7562            })
 7563        } else if let Some(local) = self.as_local() {
 7564            struct WorkspaceSymbolsResult {
 7565                server_id: LanguageServerId,
 7566                lsp_adapter: Arc<CachedLspAdapter>,
 7567                worktree: WeakEntity<Worktree>,
 7568                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7569            }
 7570
 7571            let mut requests = Vec::new();
 7572            let mut requested_servers = BTreeSet::new();
 7573            for (seed, state) in local.language_server_ids.iter() {
 7574                let Some(worktree_handle) = self
 7575                    .worktree_store
 7576                    .read(cx)
 7577                    .worktree_for_id(seed.worktree_id, cx)
 7578                else {
 7579                    continue;
 7580                };
 7581                let worktree = worktree_handle.read(cx);
 7582                if !worktree.is_visible() {
 7583                    continue;
 7584                }
 7585
 7586                if !requested_servers.insert(state.id) {
 7587                    continue;
 7588                }
 7589
 7590                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7591                    Some(LanguageServerState::Running {
 7592                        adapter, server, ..
 7593                    }) => (adapter.clone(), server),
 7594
 7595                    _ => continue,
 7596                };
 7597                let supports_workspace_symbol_request =
 7598                    match server.capabilities().workspace_symbol_provider {
 7599                        Some(OneOf::Left(supported)) => supported,
 7600                        Some(OneOf::Right(_)) => true,
 7601                        None => false,
 7602                    };
 7603                if !supports_workspace_symbol_request {
 7604                    continue;
 7605                }
 7606                let worktree_handle = worktree_handle.clone();
 7607                let server_id = server.server_id();
 7608                requests.push(
 7609                        server
 7610                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7611                                lsp::WorkspaceSymbolParams {
 7612                                    query: query.to_string(),
 7613                                    ..Default::default()
 7614                                },
 7615                            )
 7616                            .map(move |response| {
 7617                                let lsp_symbols = response.into_response()
 7618                                    .context("workspace symbols request")
 7619                                    .log_err()
 7620                                    .flatten()
 7621                                    .map(|symbol_response| match symbol_response {
 7622                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7623                                            flat_responses.into_iter().map(|lsp_symbol| {
 7624                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7625                                            }).collect::<Vec<_>>()
 7626                                        }
 7627                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7628                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7629                                                let location = match lsp_symbol.location {
 7630                                                    OneOf::Left(location) => location,
 7631                                                    OneOf::Right(_) => {
 7632                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7633                                                        return None
 7634                                                    }
 7635                                                };
 7636                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7637                                            }).collect::<Vec<_>>()
 7638                                        }
 7639                                    }).unwrap_or_default();
 7640
 7641                                WorkspaceSymbolsResult {
 7642                                    server_id,
 7643                                    lsp_adapter,
 7644                                    worktree: worktree_handle.downgrade(),
 7645                                    lsp_symbols,
 7646                                }
 7647                            }),
 7648                    );
 7649            }
 7650
 7651            cx.spawn(async move |this, cx| {
 7652                let responses = futures::future::join_all(requests).await;
 7653                let this = match this.upgrade() {
 7654                    Some(this) => this,
 7655                    None => return Ok(Vec::new()),
 7656                };
 7657
 7658                let mut symbols = Vec::new();
 7659                for result in responses {
 7660                    let core_symbols = this.update(cx, |this, cx| {
 7661                        result
 7662                            .lsp_symbols
 7663                            .into_iter()
 7664                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7665                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7666                                let source_worktree = result.worktree.upgrade()?;
 7667                                let source_worktree_id = source_worktree.read(cx).id();
 7668
 7669                                let path = if let Some((tree, rel_path)) =
 7670                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7671                                {
 7672                                    let worktree_id = tree.read(cx).id();
 7673                                    SymbolLocation::InProject(ProjectPath {
 7674                                        worktree_id,
 7675                                        path: rel_path,
 7676                                    })
 7677                                } else {
 7678                                    SymbolLocation::OutsideProject {
 7679                                        signature: this.symbol_signature(&abs_path),
 7680                                        abs_path: abs_path.into(),
 7681                                    }
 7682                                };
 7683
 7684                                Some(CoreSymbol {
 7685                                    source_language_server_id: result.server_id,
 7686                                    language_server_name: result.lsp_adapter.name.clone(),
 7687                                    source_worktree_id,
 7688                                    path,
 7689                                    kind: symbol_kind,
 7690                                    name: symbol_name,
 7691                                    range: range_from_lsp(symbol_location.range),
 7692                                })
 7693                            })
 7694                            .collect()
 7695                    })?;
 7696
 7697                    populate_labels_for_symbols(
 7698                        core_symbols,
 7699                        &language_registry,
 7700                        Some(result.lsp_adapter),
 7701                        &mut symbols,
 7702                    )
 7703                    .await;
 7704                }
 7705
 7706                Ok(symbols)
 7707            })
 7708        } else {
 7709            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7710        }
 7711    }
 7712
 7713    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7714        let mut summary = DiagnosticSummary::default();
 7715        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7716            summary.error_count += path_summary.error_count;
 7717            summary.warning_count += path_summary.warning_count;
 7718        }
 7719        summary
 7720    }
 7721
 7722    /// Returns the diagnostic summary for a specific project path.
 7723    pub fn diagnostic_summary_for_path(
 7724        &self,
 7725        project_path: &ProjectPath,
 7726        _: &App,
 7727    ) -> DiagnosticSummary {
 7728        if let Some(summaries) = self
 7729            .diagnostic_summaries
 7730            .get(&project_path.worktree_id)
 7731            .and_then(|map| map.get(&project_path.path))
 7732        {
 7733            let (error_count, warning_count) = summaries.iter().fold(
 7734                (0, 0),
 7735                |(error_count, warning_count), (_language_server_id, summary)| {
 7736                    (
 7737                        error_count + summary.error_count,
 7738                        warning_count + summary.warning_count,
 7739                    )
 7740                },
 7741            );
 7742
 7743            DiagnosticSummary {
 7744                error_count,
 7745                warning_count,
 7746            }
 7747        } else {
 7748            DiagnosticSummary::default()
 7749        }
 7750    }
 7751
 7752    pub fn diagnostic_summaries<'a>(
 7753        &'a self,
 7754        include_ignored: bool,
 7755        cx: &'a App,
 7756    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7757        self.worktree_store
 7758            .read(cx)
 7759            .visible_worktrees(cx)
 7760            .filter_map(|worktree| {
 7761                let worktree = worktree.read(cx);
 7762                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7763            })
 7764            .flat_map(move |(worktree, summaries)| {
 7765                let worktree_id = worktree.id();
 7766                summaries
 7767                    .iter()
 7768                    .filter(move |(path, _)| {
 7769                        include_ignored
 7770                            || worktree
 7771                                .entry_for_path(path.as_ref())
 7772                                .is_some_and(|entry| !entry.is_ignored)
 7773                    })
 7774                    .flat_map(move |(path, summaries)| {
 7775                        summaries.iter().map(move |(server_id, summary)| {
 7776                            (
 7777                                ProjectPath {
 7778                                    worktree_id,
 7779                                    path: path.clone(),
 7780                                },
 7781                                *server_id,
 7782                                *summary,
 7783                            )
 7784                        })
 7785                    })
 7786            })
 7787    }
 7788
 7789    pub fn on_buffer_edited(
 7790        &mut self,
 7791        buffer: Entity<Buffer>,
 7792        cx: &mut Context<Self>,
 7793    ) -> Option<()> {
 7794        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7795            Some(
 7796                self.as_local()?
 7797                    .language_servers_for_buffer(buffer, cx)
 7798                    .map(|i| i.1.clone())
 7799                    .collect(),
 7800            )
 7801        })?;
 7802
 7803        let buffer = buffer.read(cx);
 7804        let file = File::from_dyn(buffer.file())?;
 7805        let abs_path = file.as_local()?.abs_path(cx);
 7806        let uri = lsp::Uri::from_file_path(&abs_path)
 7807            .ok()
 7808            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7809            .log_err()?;
 7810        let next_snapshot = buffer.text_snapshot();
 7811        for language_server in language_servers {
 7812            let language_server = language_server.clone();
 7813
 7814            let buffer_snapshots = self
 7815                .as_local_mut()?
 7816                .buffer_snapshots
 7817                .get_mut(&buffer.remote_id())
 7818                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7819            let previous_snapshot = buffer_snapshots.last()?;
 7820
 7821            let build_incremental_change = || {
 7822                buffer
 7823                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7824                        previous_snapshot.snapshot.version(),
 7825                    )
 7826                    .map(|edit| {
 7827                        let edit_start = edit.new.start.0;
 7828                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7829                        let new_text = next_snapshot
 7830                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7831                            .collect();
 7832                        lsp::TextDocumentContentChangeEvent {
 7833                            range: Some(lsp::Range::new(
 7834                                point_to_lsp(edit_start),
 7835                                point_to_lsp(edit_end),
 7836                            )),
 7837                            range_length: None,
 7838                            text: new_text,
 7839                        }
 7840                    })
 7841                    .collect()
 7842            };
 7843
 7844            let document_sync_kind = language_server
 7845                .capabilities()
 7846                .text_document_sync
 7847                .as_ref()
 7848                .and_then(|sync| match sync {
 7849                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7850                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7851                });
 7852
 7853            let content_changes: Vec<_> = match document_sync_kind {
 7854                Some(lsp::TextDocumentSyncKind::FULL) => {
 7855                    vec![lsp::TextDocumentContentChangeEvent {
 7856                        range: None,
 7857                        range_length: None,
 7858                        text: next_snapshot.text(),
 7859                    }]
 7860                }
 7861                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7862                _ => {
 7863                    #[cfg(any(test, feature = "test-support"))]
 7864                    {
 7865                        build_incremental_change()
 7866                    }
 7867
 7868                    #[cfg(not(any(test, feature = "test-support")))]
 7869                    {
 7870                        continue;
 7871                    }
 7872                }
 7873            };
 7874
 7875            let next_version = previous_snapshot.version + 1;
 7876            buffer_snapshots.push(LspBufferSnapshot {
 7877                version: next_version,
 7878                snapshot: next_snapshot.clone(),
 7879            });
 7880
 7881            language_server
 7882                .notify::<lsp::notification::DidChangeTextDocument>(
 7883                    lsp::DidChangeTextDocumentParams {
 7884                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7885                            uri.clone(),
 7886                            next_version,
 7887                        ),
 7888                        content_changes,
 7889                    },
 7890                )
 7891                .ok();
 7892            self.pull_workspace_diagnostics(language_server.server_id());
 7893        }
 7894
 7895        None
 7896    }
 7897
 7898    pub fn on_buffer_saved(
 7899        &mut self,
 7900        buffer: Entity<Buffer>,
 7901        cx: &mut Context<Self>,
 7902    ) -> Option<()> {
 7903        let file = File::from_dyn(buffer.read(cx).file())?;
 7904        let worktree_id = file.worktree_id(cx);
 7905        let abs_path = file.as_local()?.abs_path(cx);
 7906        let text_document = lsp::TextDocumentIdentifier {
 7907            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7908        };
 7909        let local = self.as_local()?;
 7910
 7911        for server in local.language_servers_for_worktree(worktree_id) {
 7912            if let Some(include_text) = include_text(server.as_ref()) {
 7913                let text = if include_text {
 7914                    Some(buffer.read(cx).text())
 7915                } else {
 7916                    None
 7917                };
 7918                server
 7919                    .notify::<lsp::notification::DidSaveTextDocument>(
 7920                        lsp::DidSaveTextDocumentParams {
 7921                            text_document: text_document.clone(),
 7922                            text,
 7923                        },
 7924                    )
 7925                    .ok();
 7926            }
 7927        }
 7928
 7929        let language_servers = buffer.update(cx, |buffer, cx| {
 7930            local.language_server_ids_for_buffer(buffer, cx)
 7931        });
 7932        for language_server_id in language_servers {
 7933            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7934        }
 7935
 7936        None
 7937    }
 7938
 7939    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7940        maybe!(async move {
 7941            let mut refreshed_servers = HashSet::default();
 7942            let servers = lsp_store
 7943                .update(cx, |lsp_store, cx| {
 7944                    let local = lsp_store.as_local()?;
 7945
 7946                    let servers = local
 7947                        .language_server_ids
 7948                        .iter()
 7949                        .filter_map(|(seed, state)| {
 7950                            let worktree = lsp_store
 7951                                .worktree_store
 7952                                .read(cx)
 7953                                .worktree_for_id(seed.worktree_id, cx);
 7954                            let delegate: Arc<dyn LspAdapterDelegate> =
 7955                                worktree.map(|worktree| {
 7956                                    LocalLspAdapterDelegate::new(
 7957                                        local.languages.clone(),
 7958                                        &local.environment,
 7959                                        cx.weak_entity(),
 7960                                        &worktree,
 7961                                        local.http_client.clone(),
 7962                                        local.fs.clone(),
 7963                                        cx,
 7964                                    )
 7965                                })?;
 7966                            let server_id = state.id;
 7967
 7968                            let states = local.language_servers.get(&server_id)?;
 7969
 7970                            match states {
 7971                                LanguageServerState::Starting { .. } => None,
 7972                                LanguageServerState::Running {
 7973                                    adapter, server, ..
 7974                                } => {
 7975                                    let adapter = adapter.clone();
 7976                                    let server = server.clone();
 7977                                    refreshed_servers.insert(server.name());
 7978                                    let toolchain = seed.toolchain.clone();
 7979                                    Some(cx.spawn(async move |_, cx| {
 7980                                        let settings =
 7981                                            LocalLspStore::workspace_configuration_for_adapter(
 7982                                                adapter.adapter.clone(),
 7983                                                &delegate,
 7984                                                toolchain,
 7985                                                None,
 7986                                                cx,
 7987                                            )
 7988                                            .await
 7989                                            .ok()?;
 7990                                        server
 7991                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7992                                                lsp::DidChangeConfigurationParams { settings },
 7993                                            )
 7994                                            .ok()?;
 7995                                        Some(())
 7996                                    }))
 7997                                }
 7998                            }
 7999                        })
 8000                        .collect::<Vec<_>>();
 8001
 8002                    Some(servers)
 8003                })
 8004                .ok()
 8005                .flatten()?;
 8006
 8007            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8008            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8009            // to stop and unregister its language server wrapper.
 8010            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8011            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8012            let _: Vec<Option<()>> = join_all(servers).await;
 8013
 8014            Some(())
 8015        })
 8016        .await;
 8017    }
 8018
 8019    fn maintain_workspace_config(
 8020        external_refresh_requests: watch::Receiver<()>,
 8021        cx: &mut Context<Self>,
 8022    ) -> Task<Result<()>> {
 8023        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8024        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8025
 8026        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8027            *settings_changed_tx.borrow_mut() = ();
 8028        });
 8029
 8030        let mut joint_future =
 8031            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8032        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8033        // - 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).
 8034        // - 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.
 8035        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8036        // - 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,
 8037        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8038        cx.spawn(async move |this, cx| {
 8039            while let Some(()) = joint_future.next().await {
 8040                this.update(cx, |this, cx| {
 8041                    this.refresh_server_tree(cx);
 8042                })
 8043                .ok();
 8044
 8045                Self::refresh_workspace_configurations(&this, cx).await;
 8046            }
 8047
 8048            drop(settings_observation);
 8049            anyhow::Ok(())
 8050        })
 8051    }
 8052
 8053    pub fn language_servers_for_local_buffer<'a>(
 8054        &'a self,
 8055        buffer: &Buffer,
 8056        cx: &mut App,
 8057    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8058        let local = self.as_local();
 8059        let language_server_ids = local
 8060            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8061            .unwrap_or_default();
 8062
 8063        language_server_ids
 8064            .into_iter()
 8065            .filter_map(
 8066                move |server_id| match local?.language_servers.get(&server_id)? {
 8067                    LanguageServerState::Running {
 8068                        adapter, server, ..
 8069                    } => Some((adapter, server)),
 8070                    _ => None,
 8071                },
 8072            )
 8073    }
 8074
 8075    pub fn language_server_for_local_buffer<'a>(
 8076        &'a self,
 8077        buffer: &'a Buffer,
 8078        server_id: LanguageServerId,
 8079        cx: &'a mut App,
 8080    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8081        self.as_local()?
 8082            .language_servers_for_buffer(buffer, cx)
 8083            .find(|(_, s)| s.server_id() == server_id)
 8084    }
 8085
 8086    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8087        self.diagnostic_summaries.remove(&id_to_remove);
 8088        if let Some(local) = self.as_local_mut() {
 8089            let to_remove = local.remove_worktree(id_to_remove, cx);
 8090            for server in to_remove {
 8091                self.language_server_statuses.remove(&server);
 8092            }
 8093        }
 8094    }
 8095
 8096    pub fn shared(
 8097        &mut self,
 8098        project_id: u64,
 8099        downstream_client: AnyProtoClient,
 8100        _: &mut Context<Self>,
 8101    ) {
 8102        self.downstream_client = Some((downstream_client.clone(), project_id));
 8103
 8104        for (server_id, status) in &self.language_server_statuses {
 8105            if let Some(server) = self.language_server_for_id(*server_id) {
 8106                downstream_client
 8107                    .send(proto::StartLanguageServer {
 8108                        project_id,
 8109                        server: Some(proto::LanguageServer {
 8110                            id: server_id.to_proto(),
 8111                            name: status.name.to_string(),
 8112                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8113                        }),
 8114                        capabilities: serde_json::to_string(&server.capabilities())
 8115                            .expect("serializing server LSP capabilities"),
 8116                    })
 8117                    .log_err();
 8118            }
 8119        }
 8120    }
 8121
 8122    pub fn disconnected_from_host(&mut self) {
 8123        self.downstream_client.take();
 8124    }
 8125
 8126    pub fn disconnected_from_ssh_remote(&mut self) {
 8127        if let LspStoreMode::Remote(RemoteLspStore {
 8128            upstream_client, ..
 8129        }) = &mut self.mode
 8130        {
 8131            upstream_client.take();
 8132        }
 8133    }
 8134
 8135    pub(crate) fn set_language_server_statuses_from_proto(
 8136        &mut self,
 8137        project: WeakEntity<Project>,
 8138        language_servers: Vec<proto::LanguageServer>,
 8139        server_capabilities: Vec<String>,
 8140        cx: &mut Context<Self>,
 8141    ) {
 8142        let lsp_logs = cx
 8143            .try_global::<GlobalLogStore>()
 8144            .map(|lsp_store| lsp_store.0.clone());
 8145
 8146        self.language_server_statuses = language_servers
 8147            .into_iter()
 8148            .zip(server_capabilities)
 8149            .map(|(server, server_capabilities)| {
 8150                let server_id = LanguageServerId(server.id as usize);
 8151                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8152                    self.lsp_server_capabilities
 8153                        .insert(server_id, server_capabilities);
 8154                }
 8155
 8156                let name = LanguageServerName::from_proto(server.name);
 8157                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8158
 8159                if let Some(lsp_logs) = &lsp_logs {
 8160                    lsp_logs.update(cx, |lsp_logs, cx| {
 8161                        lsp_logs.add_language_server(
 8162                            // Only remote clients get their language servers set from proto
 8163                            LanguageServerKind::Remote {
 8164                                project: project.clone(),
 8165                            },
 8166                            server_id,
 8167                            Some(name.clone()),
 8168                            worktree,
 8169                            None,
 8170                            cx,
 8171                        );
 8172                    });
 8173                }
 8174
 8175                (
 8176                    server_id,
 8177                    LanguageServerStatus {
 8178                        name,
 8179                        pending_work: Default::default(),
 8180                        has_pending_diagnostic_updates: false,
 8181                        progress_tokens: Default::default(),
 8182                        worktree,
 8183                        binary: None,
 8184                        configuration: None,
 8185                        workspace_folders: BTreeSet::new(),
 8186                    },
 8187                )
 8188            })
 8189            .collect();
 8190    }
 8191
 8192    #[cfg(test)]
 8193    pub fn update_diagnostic_entries(
 8194        &mut self,
 8195        server_id: LanguageServerId,
 8196        abs_path: PathBuf,
 8197        result_id: Option<String>,
 8198        version: Option<i32>,
 8199        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8200        cx: &mut Context<Self>,
 8201    ) -> anyhow::Result<()> {
 8202        self.merge_diagnostic_entries(
 8203            vec![DocumentDiagnosticsUpdate {
 8204                diagnostics: DocumentDiagnostics {
 8205                    diagnostics,
 8206                    document_abs_path: abs_path,
 8207                    version,
 8208                },
 8209                result_id,
 8210                server_id,
 8211                disk_based_sources: Cow::Borrowed(&[]),
 8212            }],
 8213            |_, _, _| false,
 8214            cx,
 8215        )?;
 8216        Ok(())
 8217    }
 8218
 8219    pub fn merge_diagnostic_entries<'a>(
 8220        &mut self,
 8221        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8222        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 8223        cx: &mut Context<Self>,
 8224    ) -> anyhow::Result<()> {
 8225        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8226        let mut updated_diagnostics_paths = HashMap::default();
 8227        for mut update in diagnostic_updates {
 8228            let abs_path = &update.diagnostics.document_abs_path;
 8229            let server_id = update.server_id;
 8230            let Some((worktree, relative_path)) =
 8231                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8232            else {
 8233                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8234                return Ok(());
 8235            };
 8236
 8237            let worktree_id = worktree.read(cx).id();
 8238            let project_path = ProjectPath {
 8239                worktree_id,
 8240                path: relative_path,
 8241            };
 8242
 8243            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8244                let snapshot = buffer_handle.read(cx).snapshot();
 8245                let buffer = buffer_handle.read(cx);
 8246                let reused_diagnostics = buffer
 8247                    .buffer_diagnostics(Some(server_id))
 8248                    .iter()
 8249                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8250                    .map(|v| {
 8251                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8252                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8253                        DiagnosticEntry {
 8254                            range: start..end,
 8255                            diagnostic: v.diagnostic.clone(),
 8256                        }
 8257                    })
 8258                    .collect::<Vec<_>>();
 8259
 8260                self.as_local_mut()
 8261                    .context("cannot merge diagnostics on a remote LspStore")?
 8262                    .update_buffer_diagnostics(
 8263                        &buffer_handle,
 8264                        server_id,
 8265                        update.result_id,
 8266                        update.diagnostics.version,
 8267                        update.diagnostics.diagnostics.clone(),
 8268                        reused_diagnostics.clone(),
 8269                        cx,
 8270                    )?;
 8271
 8272                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8273            }
 8274
 8275            let updated = worktree.update(cx, |worktree, cx| {
 8276                self.update_worktree_diagnostics(
 8277                    worktree.id(),
 8278                    server_id,
 8279                    project_path.path.clone(),
 8280                    update.diagnostics.diagnostics,
 8281                    cx,
 8282                )
 8283            })?;
 8284            match updated {
 8285                ControlFlow::Continue(new_summary) => {
 8286                    if let Some((project_id, new_summary)) = new_summary {
 8287                        match &mut diagnostics_summary {
 8288                            Some(diagnostics_summary) => {
 8289                                diagnostics_summary
 8290                                    .more_summaries
 8291                                    .push(proto::DiagnosticSummary {
 8292                                        path: project_path.path.as_ref().to_proto(),
 8293                                        language_server_id: server_id.0 as u64,
 8294                                        error_count: new_summary.error_count,
 8295                                        warning_count: new_summary.warning_count,
 8296                                    })
 8297                            }
 8298                            None => {
 8299                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8300                                    project_id,
 8301                                    worktree_id: worktree_id.to_proto(),
 8302                                    summary: Some(proto::DiagnosticSummary {
 8303                                        path: project_path.path.as_ref().to_proto(),
 8304                                        language_server_id: server_id.0 as u64,
 8305                                        error_count: new_summary.error_count,
 8306                                        warning_count: new_summary.warning_count,
 8307                                    }),
 8308                                    more_summaries: Vec::new(),
 8309                                })
 8310                            }
 8311                        }
 8312                    }
 8313                    updated_diagnostics_paths
 8314                        .entry(server_id)
 8315                        .or_insert_with(Vec::new)
 8316                        .push(project_path);
 8317                }
 8318                ControlFlow::Break(()) => {}
 8319            }
 8320        }
 8321
 8322        if let Some((diagnostics_summary, (downstream_client, _))) =
 8323            diagnostics_summary.zip(self.downstream_client.as_ref())
 8324        {
 8325            downstream_client.send(diagnostics_summary).log_err();
 8326        }
 8327        for (server_id, paths) in updated_diagnostics_paths {
 8328            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8329        }
 8330        Ok(())
 8331    }
 8332
 8333    fn update_worktree_diagnostics(
 8334        &mut self,
 8335        worktree_id: WorktreeId,
 8336        server_id: LanguageServerId,
 8337        path_in_worktree: Arc<RelPath>,
 8338        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8339        _: &mut Context<Worktree>,
 8340    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8341        let local = match &mut self.mode {
 8342            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8343            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8344        };
 8345
 8346        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8347        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8348        let summaries_by_server_id = summaries_for_tree
 8349            .entry(path_in_worktree.clone())
 8350            .or_default();
 8351
 8352        let old_summary = summaries_by_server_id
 8353            .remove(&server_id)
 8354            .unwrap_or_default();
 8355
 8356        let new_summary = DiagnosticSummary::new(&diagnostics);
 8357        if new_summary.is_empty() {
 8358            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8359            {
 8360                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8361                    diagnostics_by_server_id.remove(ix);
 8362                }
 8363                if diagnostics_by_server_id.is_empty() {
 8364                    diagnostics_for_tree.remove(&path_in_worktree);
 8365                }
 8366            }
 8367        } else {
 8368            summaries_by_server_id.insert(server_id, new_summary);
 8369            let diagnostics_by_server_id = diagnostics_for_tree
 8370                .entry(path_in_worktree.clone())
 8371                .or_default();
 8372            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8373                Ok(ix) => {
 8374                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8375                }
 8376                Err(ix) => {
 8377                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8378                }
 8379            }
 8380        }
 8381
 8382        if !old_summary.is_empty() || !new_summary.is_empty() {
 8383            if let Some((_, project_id)) = &self.downstream_client {
 8384                Ok(ControlFlow::Continue(Some((
 8385                    *project_id,
 8386                    proto::DiagnosticSummary {
 8387                        path: path_in_worktree.to_proto(),
 8388                        language_server_id: server_id.0 as u64,
 8389                        error_count: new_summary.error_count as u32,
 8390                        warning_count: new_summary.warning_count as u32,
 8391                    },
 8392                ))))
 8393            } else {
 8394                Ok(ControlFlow::Continue(None))
 8395            }
 8396        } else {
 8397            Ok(ControlFlow::Break(()))
 8398        }
 8399    }
 8400
 8401    pub fn open_buffer_for_symbol(
 8402        &mut self,
 8403        symbol: &Symbol,
 8404        cx: &mut Context<Self>,
 8405    ) -> Task<Result<Entity<Buffer>>> {
 8406        if let Some((client, project_id)) = self.upstream_client() {
 8407            let request = client.request(proto::OpenBufferForSymbol {
 8408                project_id,
 8409                symbol: Some(Self::serialize_symbol(symbol)),
 8410            });
 8411            cx.spawn(async move |this, cx| {
 8412                let response = request.await?;
 8413                let buffer_id = BufferId::new(response.buffer_id)?;
 8414                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8415                    .await
 8416            })
 8417        } else if let Some(local) = self.as_local() {
 8418            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8419                seed.worktree_id == symbol.source_worktree_id
 8420                    && state.id == symbol.source_language_server_id
 8421                    && symbol.language_server_name == seed.name
 8422            });
 8423            if !is_valid {
 8424                return Task::ready(Err(anyhow!(
 8425                    "language server for worktree and language not found"
 8426                )));
 8427            };
 8428
 8429            let symbol_abs_path = match &symbol.path {
 8430                SymbolLocation::InProject(project_path) => self
 8431                    .worktree_store
 8432                    .read(cx)
 8433                    .absolutize(&project_path, cx)
 8434                    .context("no such worktree"),
 8435                SymbolLocation::OutsideProject {
 8436                    abs_path,
 8437                    signature: _,
 8438                } => Ok(abs_path.to_path_buf()),
 8439            };
 8440            let symbol_abs_path = match symbol_abs_path {
 8441                Ok(abs_path) => abs_path,
 8442                Err(err) => return Task::ready(Err(err)),
 8443            };
 8444            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8445                uri
 8446            } else {
 8447                return Task::ready(Err(anyhow!("invalid symbol path")));
 8448            };
 8449
 8450            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8451        } else {
 8452            Task::ready(Err(anyhow!("no upstream client or local store")))
 8453        }
 8454    }
 8455
 8456    pub(crate) fn open_local_buffer_via_lsp(
 8457        &mut self,
 8458        abs_path: lsp::Uri,
 8459        language_server_id: LanguageServerId,
 8460        cx: &mut Context<Self>,
 8461    ) -> Task<Result<Entity<Buffer>>> {
 8462        cx.spawn(async move |lsp_store, cx| {
 8463            // Escape percent-encoded string.
 8464            let current_scheme = abs_path.scheme().to_owned();
 8465            // Uri is immutable, so we can't modify the scheme
 8466
 8467            let abs_path = abs_path
 8468                .to_file_path()
 8469                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8470            let p = abs_path.clone();
 8471            let yarn_worktree = lsp_store
 8472                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8473                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8474                        cx.spawn(async move |this, cx| {
 8475                            let t = this
 8476                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8477                                .ok()?;
 8478                            t.await
 8479                        })
 8480                    }),
 8481                    None => Task::ready(None),
 8482                })?
 8483                .await;
 8484            let (worktree_root_target, known_relative_path) =
 8485                if let Some((zip_root, relative_path)) = yarn_worktree {
 8486                    (zip_root, Some(relative_path))
 8487                } else {
 8488                    (Arc::<Path>::from(abs_path.as_path()), None)
 8489                };
 8490            let (worktree, relative_path) = if let Some(result) =
 8491                lsp_store.update(cx, |lsp_store, cx| {
 8492                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8493                        worktree_store.find_worktree(&worktree_root_target, cx)
 8494                    })
 8495                })? {
 8496                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8497                (result.0, relative_path)
 8498            } else {
 8499                let worktree = lsp_store
 8500                    .update(cx, |lsp_store, cx| {
 8501                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8502                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8503                        })
 8504                    })?
 8505                    .await?;
 8506                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8507                    lsp_store
 8508                        .update(cx, |lsp_store, cx| {
 8509                            if let Some(local) = lsp_store.as_local_mut() {
 8510                                local.register_language_server_for_invisible_worktree(
 8511                                    &worktree,
 8512                                    language_server_id,
 8513                                    cx,
 8514                                )
 8515                            }
 8516                        })
 8517                        .ok();
 8518                }
 8519                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8520                let relative_path = if let Some(known_path) = known_relative_path {
 8521                    known_path
 8522                } else {
 8523                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8524                        .into_arc()
 8525                };
 8526                (worktree, relative_path)
 8527            };
 8528            let project_path = ProjectPath {
 8529                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8530                path: relative_path,
 8531            };
 8532            lsp_store
 8533                .update(cx, |lsp_store, cx| {
 8534                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8535                        buffer_store.open_buffer(project_path, cx)
 8536                    })
 8537                })?
 8538                .await
 8539        })
 8540    }
 8541
 8542    fn request_multiple_lsp_locally<P, R>(
 8543        &mut self,
 8544        buffer: &Entity<Buffer>,
 8545        position: Option<P>,
 8546        request: R,
 8547        cx: &mut Context<Self>,
 8548    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8549    where
 8550        P: ToOffset,
 8551        R: LspCommand + Clone,
 8552        <R::LspRequest as lsp::request::Request>::Result: Send,
 8553        <R::LspRequest as lsp::request::Request>::Params: Send,
 8554    {
 8555        let Some(local) = self.as_local() else {
 8556            return Task::ready(Vec::new());
 8557        };
 8558
 8559        let snapshot = buffer.read(cx).snapshot();
 8560        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8561
 8562        let server_ids = buffer.update(cx, |buffer, cx| {
 8563            local
 8564                .language_servers_for_buffer(buffer, cx)
 8565                .filter(|(adapter, _)| {
 8566                    scope
 8567                        .as_ref()
 8568                        .map(|scope| scope.language_allowed(&adapter.name))
 8569                        .unwrap_or(true)
 8570                })
 8571                .map(|(_, server)| server.server_id())
 8572                .filter(|server_id| {
 8573                    self.as_local().is_none_or(|local| {
 8574                        local
 8575                            .buffers_opened_in_servers
 8576                            .get(&snapshot.remote_id())
 8577                            .is_some_and(|servers| servers.contains(server_id))
 8578                    })
 8579                })
 8580                .collect::<Vec<_>>()
 8581        });
 8582
 8583        let mut response_results = server_ids
 8584            .into_iter()
 8585            .map(|server_id| {
 8586                let task = self.request_lsp(
 8587                    buffer.clone(),
 8588                    LanguageServerToQuery::Other(server_id),
 8589                    request.clone(),
 8590                    cx,
 8591                );
 8592                async move { (server_id, task.await) }
 8593            })
 8594            .collect::<FuturesUnordered<_>>();
 8595
 8596        cx.background_spawn(async move {
 8597            let mut responses = Vec::with_capacity(response_results.len());
 8598            while let Some((server_id, response_result)) = response_results.next().await {
 8599                match response_result {
 8600                    Ok(response) => responses.push((server_id, response)),
 8601                    // rust-analyzer likes to error with this when its still loading up
 8602                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8603                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8604                }
 8605            }
 8606            responses
 8607        })
 8608    }
 8609
 8610    async fn handle_lsp_get_completions(
 8611        this: Entity<Self>,
 8612        envelope: TypedEnvelope<proto::GetCompletions>,
 8613        mut cx: AsyncApp,
 8614    ) -> Result<proto::GetCompletionsResponse> {
 8615        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8616
 8617        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8618        let buffer_handle = this.update(&mut cx, |this, cx| {
 8619            this.buffer_store.read(cx).get_existing(buffer_id)
 8620        })??;
 8621        let request = GetCompletions::from_proto(
 8622            envelope.payload,
 8623            this.clone(),
 8624            buffer_handle.clone(),
 8625            cx.clone(),
 8626        )
 8627        .await?;
 8628
 8629        let server_to_query = match request.server_id {
 8630            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8631            None => LanguageServerToQuery::FirstCapable,
 8632        };
 8633
 8634        let response = this
 8635            .update(&mut cx, |this, cx| {
 8636                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8637            })?
 8638            .await?;
 8639        this.update(&mut cx, |this, cx| {
 8640            Ok(GetCompletions::response_to_proto(
 8641                response,
 8642                this,
 8643                sender_id,
 8644                &buffer_handle.read(cx).version(),
 8645                cx,
 8646            ))
 8647        })?
 8648    }
 8649
 8650    async fn handle_lsp_command<T: LspCommand>(
 8651        this: Entity<Self>,
 8652        envelope: TypedEnvelope<T::ProtoRequest>,
 8653        mut cx: AsyncApp,
 8654    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8655    where
 8656        <T::LspRequest as lsp::request::Request>::Params: Send,
 8657        <T::LspRequest as lsp::request::Request>::Result: Send,
 8658    {
 8659        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8660        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8661        let buffer_handle = this.update(&mut cx, |this, cx| {
 8662            this.buffer_store.read(cx).get_existing(buffer_id)
 8663        })??;
 8664        let request = T::from_proto(
 8665            envelope.payload,
 8666            this.clone(),
 8667            buffer_handle.clone(),
 8668            cx.clone(),
 8669        )
 8670        .await?;
 8671        let response = this
 8672            .update(&mut cx, |this, cx| {
 8673                this.request_lsp(
 8674                    buffer_handle.clone(),
 8675                    LanguageServerToQuery::FirstCapable,
 8676                    request,
 8677                    cx,
 8678                )
 8679            })?
 8680            .await?;
 8681        this.update(&mut cx, |this, cx| {
 8682            Ok(T::response_to_proto(
 8683                response,
 8684                this,
 8685                sender_id,
 8686                &buffer_handle.read(cx).version(),
 8687                cx,
 8688            ))
 8689        })?
 8690    }
 8691
 8692    async fn handle_lsp_query(
 8693        lsp_store: Entity<Self>,
 8694        envelope: TypedEnvelope<proto::LspQuery>,
 8695        mut cx: AsyncApp,
 8696    ) -> Result<proto::Ack> {
 8697        use proto::lsp_query::Request;
 8698        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8699        let lsp_query = envelope.payload;
 8700        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8701        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8702        match lsp_query.request.context("invalid LSP query request")? {
 8703            Request::GetReferences(get_references) => {
 8704                let position = get_references.position.clone().and_then(deserialize_anchor);
 8705                Self::query_lsp_locally::<GetReferences>(
 8706                    lsp_store,
 8707                    server_id,
 8708                    sender_id,
 8709                    lsp_request_id,
 8710                    get_references,
 8711                    position,
 8712                    &mut cx,
 8713                )
 8714                .await?;
 8715            }
 8716            Request::GetDocumentColor(get_document_color) => {
 8717                Self::query_lsp_locally::<GetDocumentColor>(
 8718                    lsp_store,
 8719                    server_id,
 8720                    sender_id,
 8721                    lsp_request_id,
 8722                    get_document_color,
 8723                    None,
 8724                    &mut cx,
 8725                )
 8726                .await?;
 8727            }
 8728            Request::GetHover(get_hover) => {
 8729                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8730                Self::query_lsp_locally::<GetHover>(
 8731                    lsp_store,
 8732                    server_id,
 8733                    sender_id,
 8734                    lsp_request_id,
 8735                    get_hover,
 8736                    position,
 8737                    &mut cx,
 8738                )
 8739                .await?;
 8740            }
 8741            Request::GetCodeActions(get_code_actions) => {
 8742                Self::query_lsp_locally::<GetCodeActions>(
 8743                    lsp_store,
 8744                    server_id,
 8745                    sender_id,
 8746                    lsp_request_id,
 8747                    get_code_actions,
 8748                    None,
 8749                    &mut cx,
 8750                )
 8751                .await?;
 8752            }
 8753            Request::GetSignatureHelp(get_signature_help) => {
 8754                let position = get_signature_help
 8755                    .position
 8756                    .clone()
 8757                    .and_then(deserialize_anchor);
 8758                Self::query_lsp_locally::<GetSignatureHelp>(
 8759                    lsp_store,
 8760                    server_id,
 8761                    sender_id,
 8762                    lsp_request_id,
 8763                    get_signature_help,
 8764                    position,
 8765                    &mut cx,
 8766                )
 8767                .await?;
 8768            }
 8769            Request::GetCodeLens(get_code_lens) => {
 8770                Self::query_lsp_locally::<GetCodeLens>(
 8771                    lsp_store,
 8772                    server_id,
 8773                    sender_id,
 8774                    lsp_request_id,
 8775                    get_code_lens,
 8776                    None,
 8777                    &mut cx,
 8778                )
 8779                .await?;
 8780            }
 8781            Request::GetDefinition(get_definition) => {
 8782                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8783                Self::query_lsp_locally::<GetDefinitions>(
 8784                    lsp_store,
 8785                    server_id,
 8786                    sender_id,
 8787                    lsp_request_id,
 8788                    get_definition,
 8789                    position,
 8790                    &mut cx,
 8791                )
 8792                .await?;
 8793            }
 8794            Request::GetDeclaration(get_declaration) => {
 8795                let position = get_declaration
 8796                    .position
 8797                    .clone()
 8798                    .and_then(deserialize_anchor);
 8799                Self::query_lsp_locally::<GetDeclarations>(
 8800                    lsp_store,
 8801                    server_id,
 8802                    sender_id,
 8803                    lsp_request_id,
 8804                    get_declaration,
 8805                    position,
 8806                    &mut cx,
 8807                )
 8808                .await?;
 8809            }
 8810            Request::GetTypeDefinition(get_type_definition) => {
 8811                let position = get_type_definition
 8812                    .position
 8813                    .clone()
 8814                    .and_then(deserialize_anchor);
 8815                Self::query_lsp_locally::<GetTypeDefinitions>(
 8816                    lsp_store,
 8817                    server_id,
 8818                    sender_id,
 8819                    lsp_request_id,
 8820                    get_type_definition,
 8821                    position,
 8822                    &mut cx,
 8823                )
 8824                .await?;
 8825            }
 8826            Request::GetImplementation(get_implementation) => {
 8827                let position = get_implementation
 8828                    .position
 8829                    .clone()
 8830                    .and_then(deserialize_anchor);
 8831                Self::query_lsp_locally::<GetImplementations>(
 8832                    lsp_store,
 8833                    server_id,
 8834                    sender_id,
 8835                    lsp_request_id,
 8836                    get_implementation,
 8837                    position,
 8838                    &mut cx,
 8839                )
 8840                .await?;
 8841            }
 8842            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8843                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8844                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8845                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8846                    this.buffer_store.read(cx).get_existing(buffer_id)
 8847                })??;
 8848                buffer
 8849                    .update(&mut cx, |buffer, _| {
 8850                        buffer.wait_for_version(version.clone())
 8851                    })?
 8852                    .await?;
 8853                lsp_store.update(&mut cx, |lsp_store, cx| {
 8854                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8855                    let key = LspKey {
 8856                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8857                        server_queried: server_id,
 8858                    };
 8859                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8860                    ) {
 8861                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8862                            lsp_requests.clear();
 8863                        };
 8864                    }
 8865
 8866                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8867                    existing_queries.insert(
 8868                        lsp_request_id,
 8869                        cx.spawn(async move |lsp_store, cx| {
 8870                            let diagnostics_pull = lsp_store
 8871                                .update(cx, |lsp_store, cx| {
 8872                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8873                                })
 8874                                .ok();
 8875                            if let Some(diagnostics_pull) = diagnostics_pull {
 8876                                match diagnostics_pull.await {
 8877                                    Ok(()) => {}
 8878                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8879                                };
 8880                            }
 8881                        }),
 8882                    );
 8883                })?;
 8884            }
 8885            Request::InlayHints(inlay_hints) => {
 8886                let query_start = inlay_hints
 8887                    .start
 8888                    .clone()
 8889                    .and_then(deserialize_anchor)
 8890                    .context("invalid inlay hints range start")?;
 8891                let query_end = inlay_hints
 8892                    .end
 8893                    .clone()
 8894                    .and_then(deserialize_anchor)
 8895                    .context("invalid inlay hints range end")?;
 8896                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8897                    &lsp_store,
 8898                    server_id,
 8899                    lsp_request_id,
 8900                    &inlay_hints,
 8901                    query_start..query_end,
 8902                    &mut cx,
 8903                )
 8904                .await
 8905                .context("preparing inlay hints request")?;
 8906                Self::query_lsp_locally::<InlayHints>(
 8907                    lsp_store,
 8908                    server_id,
 8909                    sender_id,
 8910                    lsp_request_id,
 8911                    inlay_hints,
 8912                    None,
 8913                    &mut cx,
 8914                )
 8915                .await
 8916                .context("querying for inlay hints")?
 8917            }
 8918        }
 8919        Ok(proto::Ack {})
 8920    }
 8921
 8922    async fn handle_lsp_query_response(
 8923        lsp_store: Entity<Self>,
 8924        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8925        cx: AsyncApp,
 8926    ) -> Result<()> {
 8927        lsp_store.read_with(&cx, |lsp_store, _| {
 8928            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8929                upstream_client.handle_lsp_response(envelope.clone());
 8930            }
 8931        })?;
 8932        Ok(())
 8933    }
 8934
 8935    async fn handle_apply_code_action(
 8936        this: Entity<Self>,
 8937        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8938        mut cx: AsyncApp,
 8939    ) -> Result<proto::ApplyCodeActionResponse> {
 8940        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8941        let action =
 8942            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8943        let apply_code_action = this.update(&mut cx, |this, cx| {
 8944            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8945            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8946            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8947        })??;
 8948
 8949        let project_transaction = apply_code_action.await?;
 8950        let project_transaction = this.update(&mut cx, |this, cx| {
 8951            this.buffer_store.update(cx, |buffer_store, cx| {
 8952                buffer_store.serialize_project_transaction_for_peer(
 8953                    project_transaction,
 8954                    sender_id,
 8955                    cx,
 8956                )
 8957            })
 8958        })?;
 8959        Ok(proto::ApplyCodeActionResponse {
 8960            transaction: Some(project_transaction),
 8961        })
 8962    }
 8963
 8964    async fn handle_register_buffer_with_language_servers(
 8965        this: Entity<Self>,
 8966        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8967        mut cx: AsyncApp,
 8968    ) -> Result<proto::Ack> {
 8969        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8970        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8971        this.update(&mut cx, |this, cx| {
 8972            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8973                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8974                    project_id: upstream_project_id,
 8975                    buffer_id: buffer_id.to_proto(),
 8976                    only_servers: envelope.payload.only_servers,
 8977                });
 8978            }
 8979
 8980            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8981                anyhow::bail!("buffer is not open");
 8982            };
 8983
 8984            let handle = this.register_buffer_with_language_servers(
 8985                &buffer,
 8986                envelope
 8987                    .payload
 8988                    .only_servers
 8989                    .into_iter()
 8990                    .filter_map(|selector| {
 8991                        Some(match selector.selector? {
 8992                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8993                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8994                            }
 8995                            proto::language_server_selector::Selector::Name(name) => {
 8996                                LanguageServerSelector::Name(LanguageServerName(
 8997                                    SharedString::from(name),
 8998                                ))
 8999                            }
 9000                        })
 9001                    })
 9002                    .collect(),
 9003                false,
 9004                cx,
 9005            );
 9006            this.buffer_store().update(cx, |buffer_store, _| {
 9007                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9008            });
 9009
 9010            Ok(())
 9011        })??;
 9012        Ok(proto::Ack {})
 9013    }
 9014
 9015    async fn handle_rename_project_entry(
 9016        this: Entity<Self>,
 9017        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9018        mut cx: AsyncApp,
 9019    ) -> Result<proto::ProjectEntryResponse> {
 9020        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9021        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9022        let new_path =
 9023            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9024
 9025        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9026            .update(&mut cx, |this, cx| {
 9027                let (worktree, entry) = this
 9028                    .worktree_store
 9029                    .read(cx)
 9030                    .worktree_and_entry_for_id(entry_id, cx)?;
 9031                let new_worktree = this
 9032                    .worktree_store
 9033                    .read(cx)
 9034                    .worktree_for_id(new_worktree_id, cx)?;
 9035                Some((
 9036                    this.worktree_store.clone(),
 9037                    worktree,
 9038                    new_worktree,
 9039                    entry.clone(),
 9040                ))
 9041            })?
 9042            .context("worktree not found")?;
 9043        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9044            (worktree.absolutize(&old_entry.path), worktree.id())
 9045        })?;
 9046        let new_abs_path =
 9047            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9048
 9049        let _transaction = Self::will_rename_entry(
 9050            this.downgrade(),
 9051            old_worktree_id,
 9052            &old_abs_path,
 9053            &new_abs_path,
 9054            old_entry.is_dir(),
 9055            cx.clone(),
 9056        )
 9057        .await;
 9058        let response = WorktreeStore::handle_rename_project_entry(
 9059            worktree_store,
 9060            envelope.payload,
 9061            cx.clone(),
 9062        )
 9063        .await;
 9064        this.read_with(&cx, |this, _| {
 9065            this.did_rename_entry(
 9066                old_worktree_id,
 9067                &old_abs_path,
 9068                &new_abs_path,
 9069                old_entry.is_dir(),
 9070            );
 9071        })
 9072        .ok();
 9073        response
 9074    }
 9075
 9076    async fn handle_update_diagnostic_summary(
 9077        this: Entity<Self>,
 9078        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9079        mut cx: AsyncApp,
 9080    ) -> Result<()> {
 9081        this.update(&mut cx, |lsp_store, cx| {
 9082            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9083            let mut updated_diagnostics_paths = HashMap::default();
 9084            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9085            for message_summary in envelope
 9086                .payload
 9087                .summary
 9088                .into_iter()
 9089                .chain(envelope.payload.more_summaries)
 9090            {
 9091                let project_path = ProjectPath {
 9092                    worktree_id,
 9093                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9094                };
 9095                let path = project_path.path.clone();
 9096                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9097                let summary = DiagnosticSummary {
 9098                    error_count: message_summary.error_count as usize,
 9099                    warning_count: message_summary.warning_count as usize,
 9100                };
 9101
 9102                if summary.is_empty() {
 9103                    if let Some(worktree_summaries) =
 9104                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9105                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9106                    {
 9107                        summaries.remove(&server_id);
 9108                        if summaries.is_empty() {
 9109                            worktree_summaries.remove(&path);
 9110                        }
 9111                    }
 9112                } else {
 9113                    lsp_store
 9114                        .diagnostic_summaries
 9115                        .entry(worktree_id)
 9116                        .or_default()
 9117                        .entry(path)
 9118                        .or_default()
 9119                        .insert(server_id, summary);
 9120                }
 9121
 9122                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9123                    match &mut diagnostics_summary {
 9124                        Some(diagnostics_summary) => {
 9125                            diagnostics_summary
 9126                                .more_summaries
 9127                                .push(proto::DiagnosticSummary {
 9128                                    path: project_path.path.as_ref().to_proto(),
 9129                                    language_server_id: server_id.0 as u64,
 9130                                    error_count: summary.error_count as u32,
 9131                                    warning_count: summary.warning_count as u32,
 9132                                })
 9133                        }
 9134                        None => {
 9135                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9136                                project_id: *project_id,
 9137                                worktree_id: worktree_id.to_proto(),
 9138                                summary: Some(proto::DiagnosticSummary {
 9139                                    path: project_path.path.as_ref().to_proto(),
 9140                                    language_server_id: server_id.0 as u64,
 9141                                    error_count: summary.error_count as u32,
 9142                                    warning_count: summary.warning_count as u32,
 9143                                }),
 9144                                more_summaries: Vec::new(),
 9145                            })
 9146                        }
 9147                    }
 9148                }
 9149                updated_diagnostics_paths
 9150                    .entry(server_id)
 9151                    .or_insert_with(Vec::new)
 9152                    .push(project_path);
 9153            }
 9154
 9155            if let Some((diagnostics_summary, (downstream_client, _))) =
 9156                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9157            {
 9158                downstream_client.send(diagnostics_summary).log_err();
 9159            }
 9160            for (server_id, paths) in updated_diagnostics_paths {
 9161                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9162            }
 9163            Ok(())
 9164        })?
 9165    }
 9166
 9167    async fn handle_start_language_server(
 9168        lsp_store: Entity<Self>,
 9169        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9170        mut cx: AsyncApp,
 9171    ) -> Result<()> {
 9172        let server = envelope.payload.server.context("invalid server")?;
 9173        let server_capabilities =
 9174            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9175                .with_context(|| {
 9176                    format!(
 9177                        "incorrect server capabilities {}",
 9178                        envelope.payload.capabilities
 9179                    )
 9180                })?;
 9181        lsp_store.update(&mut cx, |lsp_store, cx| {
 9182            let server_id = LanguageServerId(server.id as usize);
 9183            let server_name = LanguageServerName::from_proto(server.name.clone());
 9184            lsp_store
 9185                .lsp_server_capabilities
 9186                .insert(server_id, server_capabilities);
 9187            lsp_store.language_server_statuses.insert(
 9188                server_id,
 9189                LanguageServerStatus {
 9190                    name: server_name.clone(),
 9191                    pending_work: Default::default(),
 9192                    has_pending_diagnostic_updates: false,
 9193                    progress_tokens: Default::default(),
 9194                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9195                    binary: None,
 9196                    configuration: None,
 9197                    workspace_folders: BTreeSet::new(),
 9198                },
 9199            );
 9200            cx.emit(LspStoreEvent::LanguageServerAdded(
 9201                server_id,
 9202                server_name,
 9203                server.worktree_id.map(WorktreeId::from_proto),
 9204            ));
 9205            cx.notify();
 9206        })?;
 9207        Ok(())
 9208    }
 9209
 9210    async fn handle_update_language_server(
 9211        lsp_store: Entity<Self>,
 9212        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9213        mut cx: AsyncApp,
 9214    ) -> Result<()> {
 9215        lsp_store.update(&mut cx, |lsp_store, cx| {
 9216            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9217
 9218            match envelope.payload.variant.context("invalid variant")? {
 9219                proto::update_language_server::Variant::WorkStart(payload) => {
 9220                    lsp_store.on_lsp_work_start(
 9221                        language_server_id,
 9222                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9223                            .context("invalid progress token value")?,
 9224                        LanguageServerProgress {
 9225                            title: payload.title,
 9226                            is_disk_based_diagnostics_progress: false,
 9227                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9228                            message: payload.message,
 9229                            percentage: payload.percentage.map(|p| p as usize),
 9230                            last_update_at: cx.background_executor().now(),
 9231                        },
 9232                        cx,
 9233                    );
 9234                }
 9235                proto::update_language_server::Variant::WorkProgress(payload) => {
 9236                    lsp_store.on_lsp_work_progress(
 9237                        language_server_id,
 9238                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9239                            .context("invalid progress token value")?,
 9240                        LanguageServerProgress {
 9241                            title: None,
 9242                            is_disk_based_diagnostics_progress: false,
 9243                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9244                            message: payload.message,
 9245                            percentage: payload.percentage.map(|p| p as usize),
 9246                            last_update_at: cx.background_executor().now(),
 9247                        },
 9248                        cx,
 9249                    );
 9250                }
 9251
 9252                proto::update_language_server::Variant::WorkEnd(payload) => {
 9253                    lsp_store.on_lsp_work_end(
 9254                        language_server_id,
 9255                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9256                            .context("invalid progress token value")?,
 9257                        cx,
 9258                    );
 9259                }
 9260
 9261                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9262                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9263                }
 9264
 9265                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9266                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9267                }
 9268
 9269                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9270                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9271                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9272                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9273                        language_server_id,
 9274                        name: envelope
 9275                            .payload
 9276                            .server_name
 9277                            .map(SharedString::new)
 9278                            .map(LanguageServerName),
 9279                        message: non_lsp,
 9280                    });
 9281                }
 9282            }
 9283
 9284            Ok(())
 9285        })?
 9286    }
 9287
 9288    async fn handle_language_server_log(
 9289        this: Entity<Self>,
 9290        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9291        mut cx: AsyncApp,
 9292    ) -> Result<()> {
 9293        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9294        let log_type = envelope
 9295            .payload
 9296            .log_type
 9297            .map(LanguageServerLogType::from_proto)
 9298            .context("invalid language server log type")?;
 9299
 9300        let message = envelope.payload.message;
 9301
 9302        this.update(&mut cx, |_, cx| {
 9303            cx.emit(LspStoreEvent::LanguageServerLog(
 9304                language_server_id,
 9305                log_type,
 9306                message,
 9307            ));
 9308        })
 9309    }
 9310
 9311    async fn handle_lsp_ext_cancel_flycheck(
 9312        lsp_store: Entity<Self>,
 9313        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9314        cx: AsyncApp,
 9315    ) -> Result<proto::Ack> {
 9316        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9317        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9318            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9319                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9320            } else {
 9321                None
 9322            }
 9323        })?;
 9324        if let Some(task) = task {
 9325            task.context("handling lsp ext cancel flycheck")?;
 9326        }
 9327
 9328        Ok(proto::Ack {})
 9329    }
 9330
 9331    async fn handle_lsp_ext_run_flycheck(
 9332        lsp_store: Entity<Self>,
 9333        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9334        mut cx: AsyncApp,
 9335    ) -> Result<proto::Ack> {
 9336        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9337        lsp_store.update(&mut cx, |lsp_store, cx| {
 9338            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9339                let text_document = if envelope.payload.current_file_only {
 9340                    let buffer_id = envelope
 9341                        .payload
 9342                        .buffer_id
 9343                        .map(|id| BufferId::new(id))
 9344                        .transpose()?;
 9345                    buffer_id
 9346                        .and_then(|buffer_id| {
 9347                            lsp_store
 9348                                .buffer_store()
 9349                                .read(cx)
 9350                                .get(buffer_id)
 9351                                .and_then(|buffer| {
 9352                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9353                                })
 9354                                .map(|path| make_text_document_identifier(&path))
 9355                        })
 9356                        .transpose()?
 9357                } else {
 9358                    None
 9359                };
 9360                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9361                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9362                )?;
 9363            }
 9364            anyhow::Ok(())
 9365        })??;
 9366
 9367        Ok(proto::Ack {})
 9368    }
 9369
 9370    async fn handle_lsp_ext_clear_flycheck(
 9371        lsp_store: Entity<Self>,
 9372        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9373        cx: AsyncApp,
 9374    ) -> Result<proto::Ack> {
 9375        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9376        lsp_store
 9377            .read_with(&cx, |lsp_store, _| {
 9378                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9379                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9380                } else {
 9381                    None
 9382                }
 9383            })
 9384            .context("handling lsp ext clear flycheck")?;
 9385
 9386        Ok(proto::Ack {})
 9387    }
 9388
 9389    pub fn disk_based_diagnostics_started(
 9390        &mut self,
 9391        language_server_id: LanguageServerId,
 9392        cx: &mut Context<Self>,
 9393    ) {
 9394        if let Some(language_server_status) =
 9395            self.language_server_statuses.get_mut(&language_server_id)
 9396        {
 9397            language_server_status.has_pending_diagnostic_updates = true;
 9398        }
 9399
 9400        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9401        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9402            language_server_id,
 9403            name: self
 9404                .language_server_adapter_for_id(language_server_id)
 9405                .map(|adapter| adapter.name()),
 9406            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9407                Default::default(),
 9408            ),
 9409        })
 9410    }
 9411
 9412    pub fn disk_based_diagnostics_finished(
 9413        &mut self,
 9414        language_server_id: LanguageServerId,
 9415        cx: &mut Context<Self>,
 9416    ) {
 9417        if let Some(language_server_status) =
 9418            self.language_server_statuses.get_mut(&language_server_id)
 9419        {
 9420            language_server_status.has_pending_diagnostic_updates = false;
 9421        }
 9422
 9423        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9424        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9425            language_server_id,
 9426            name: self
 9427                .language_server_adapter_for_id(language_server_id)
 9428                .map(|adapter| adapter.name()),
 9429            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9430                Default::default(),
 9431            ),
 9432        })
 9433    }
 9434
 9435    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9436    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9437    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9438    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9439    // the language server might take some time to publish diagnostics.
 9440    fn simulate_disk_based_diagnostics_events_if_needed(
 9441        &mut self,
 9442        language_server_id: LanguageServerId,
 9443        cx: &mut Context<Self>,
 9444    ) {
 9445        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9446
 9447        let Some(LanguageServerState::Running {
 9448            simulate_disk_based_diagnostics_completion,
 9449            adapter,
 9450            ..
 9451        }) = self
 9452            .as_local_mut()
 9453            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9454        else {
 9455            return;
 9456        };
 9457
 9458        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9459            return;
 9460        }
 9461
 9462        let prev_task =
 9463            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9464                cx.background_executor()
 9465                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9466                    .await;
 9467
 9468                this.update(cx, |this, cx| {
 9469                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9470
 9471                    if let Some(LanguageServerState::Running {
 9472                        simulate_disk_based_diagnostics_completion,
 9473                        ..
 9474                    }) = this.as_local_mut().and_then(|local_store| {
 9475                        local_store.language_servers.get_mut(&language_server_id)
 9476                    }) {
 9477                        *simulate_disk_based_diagnostics_completion = None;
 9478                    }
 9479                })
 9480                .ok();
 9481            }));
 9482
 9483        if prev_task.is_none() {
 9484            self.disk_based_diagnostics_started(language_server_id, cx);
 9485        }
 9486    }
 9487
 9488    pub fn language_server_statuses(
 9489        &self,
 9490    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9491        self.language_server_statuses
 9492            .iter()
 9493            .map(|(key, value)| (*key, value))
 9494    }
 9495
 9496    pub(super) fn did_rename_entry(
 9497        &self,
 9498        worktree_id: WorktreeId,
 9499        old_path: &Path,
 9500        new_path: &Path,
 9501        is_dir: bool,
 9502    ) {
 9503        maybe!({
 9504            let local_store = self.as_local()?;
 9505
 9506            let old_uri = lsp::Uri::from_file_path(old_path)
 9507                .ok()
 9508                .map(|uri| uri.to_string())?;
 9509            let new_uri = lsp::Uri::from_file_path(new_path)
 9510                .ok()
 9511                .map(|uri| uri.to_string())?;
 9512
 9513            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9514                let Some(filter) = local_store
 9515                    .language_server_paths_watched_for_rename
 9516                    .get(&language_server.server_id())
 9517                else {
 9518                    continue;
 9519                };
 9520
 9521                if filter.should_send_did_rename(&old_uri, is_dir) {
 9522                    language_server
 9523                        .notify::<DidRenameFiles>(RenameFilesParams {
 9524                            files: vec![FileRename {
 9525                                old_uri: old_uri.clone(),
 9526                                new_uri: new_uri.clone(),
 9527                            }],
 9528                        })
 9529                        .ok();
 9530                }
 9531            }
 9532            Some(())
 9533        });
 9534    }
 9535
 9536    pub(super) fn will_rename_entry(
 9537        this: WeakEntity<Self>,
 9538        worktree_id: WorktreeId,
 9539        old_path: &Path,
 9540        new_path: &Path,
 9541        is_dir: bool,
 9542        cx: AsyncApp,
 9543    ) -> Task<ProjectTransaction> {
 9544        let old_uri = lsp::Uri::from_file_path(old_path)
 9545            .ok()
 9546            .map(|uri| uri.to_string());
 9547        let new_uri = lsp::Uri::from_file_path(new_path)
 9548            .ok()
 9549            .map(|uri| uri.to_string());
 9550        cx.spawn(async move |cx| {
 9551            let mut tasks = vec![];
 9552            this.update(cx, |this, cx| {
 9553                let local_store = this.as_local()?;
 9554                let old_uri = old_uri?;
 9555                let new_uri = new_uri?;
 9556                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9557                    let Some(filter) = local_store
 9558                        .language_server_paths_watched_for_rename
 9559                        .get(&language_server.server_id())
 9560                    else {
 9561                        continue;
 9562                    };
 9563
 9564                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9565                        let apply_edit = cx.spawn({
 9566                            let old_uri = old_uri.clone();
 9567                            let new_uri = new_uri.clone();
 9568                            let language_server = language_server.clone();
 9569                            async move |this, cx| {
 9570                                let edit = language_server
 9571                                    .request::<WillRenameFiles>(RenameFilesParams {
 9572                                        files: vec![FileRename { old_uri, new_uri }],
 9573                                    })
 9574                                    .await
 9575                                    .into_response()
 9576                                    .context("will rename files")
 9577                                    .log_err()
 9578                                    .flatten()?;
 9579
 9580                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9581                                    this.upgrade()?,
 9582                                    edit,
 9583                                    false,
 9584                                    language_server.clone(),
 9585                                    cx,
 9586                                )
 9587                                .await
 9588                                .ok()?;
 9589                                Some(transaction)
 9590                            }
 9591                        });
 9592                        tasks.push(apply_edit);
 9593                    }
 9594                }
 9595                Some(())
 9596            })
 9597            .ok()
 9598            .flatten();
 9599            let mut merged_transaction = ProjectTransaction::default();
 9600            for task in tasks {
 9601                // Await on tasks sequentially so that the order of application of edits is deterministic
 9602                // (at least with regards to the order of registration of language servers)
 9603                if let Some(transaction) = task.await {
 9604                    for (buffer, buffer_transaction) in transaction.0 {
 9605                        merged_transaction.0.insert(buffer, buffer_transaction);
 9606                    }
 9607                }
 9608            }
 9609            merged_transaction
 9610        })
 9611    }
 9612
 9613    fn lsp_notify_abs_paths_changed(
 9614        &mut self,
 9615        server_id: LanguageServerId,
 9616        changes: Vec<PathEvent>,
 9617    ) {
 9618        maybe!({
 9619            let server = self.language_server_for_id(server_id)?;
 9620            let changes = changes
 9621                .into_iter()
 9622                .filter_map(|event| {
 9623                    let typ = match event.kind? {
 9624                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9625                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9626                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9627                    };
 9628                    Some(lsp::FileEvent {
 9629                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9630                        typ,
 9631                    })
 9632                })
 9633                .collect::<Vec<_>>();
 9634            if !changes.is_empty() {
 9635                server
 9636                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9637                        lsp::DidChangeWatchedFilesParams { changes },
 9638                    )
 9639                    .ok();
 9640            }
 9641            Some(())
 9642        });
 9643    }
 9644
 9645    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9646        self.as_local()?.language_server_for_id(id)
 9647    }
 9648
 9649    fn on_lsp_progress(
 9650        &mut self,
 9651        progress_params: lsp::ProgressParams,
 9652        language_server_id: LanguageServerId,
 9653        disk_based_diagnostics_progress_token: Option<String>,
 9654        cx: &mut Context<Self>,
 9655    ) {
 9656        match progress_params.value {
 9657            lsp::ProgressParamsValue::WorkDone(progress) => {
 9658                self.handle_work_done_progress(
 9659                    progress,
 9660                    language_server_id,
 9661                    disk_based_diagnostics_progress_token,
 9662                    ProgressToken::from_lsp(progress_params.token),
 9663                    cx,
 9664                );
 9665            }
 9666            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9667                let identifier = match progress_params.token {
 9668                    lsp::NumberOrString::Number(_) => None,
 9669                    lsp::NumberOrString::String(token) => token
 9670                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9671                        .map(|(_, id)| id.to_owned()),
 9672                };
 9673                if let Some(LanguageServerState::Running {
 9674                    workspace_diagnostics_refresh_tasks,
 9675                    ..
 9676                }) = self
 9677                    .as_local_mut()
 9678                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9679                    && let Some(workspace_diagnostics) =
 9680                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9681                {
 9682                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9683                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9684                }
 9685            }
 9686        }
 9687    }
 9688
 9689    fn handle_work_done_progress(
 9690        &mut self,
 9691        progress: lsp::WorkDoneProgress,
 9692        language_server_id: LanguageServerId,
 9693        disk_based_diagnostics_progress_token: Option<String>,
 9694        token: ProgressToken,
 9695        cx: &mut Context<Self>,
 9696    ) {
 9697        let language_server_status =
 9698            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9699                status
 9700            } else {
 9701                return;
 9702            };
 9703
 9704        if !language_server_status.progress_tokens.contains(&token) {
 9705            return;
 9706        }
 9707
 9708        let is_disk_based_diagnostics_progress =
 9709            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9710                (&disk_based_diagnostics_progress_token, &token)
 9711            {
 9712                token.starts_with(disk_based_token)
 9713            } else {
 9714                false
 9715            };
 9716
 9717        match progress {
 9718            lsp::WorkDoneProgress::Begin(report) => {
 9719                if is_disk_based_diagnostics_progress {
 9720                    self.disk_based_diagnostics_started(language_server_id, cx);
 9721                }
 9722                self.on_lsp_work_start(
 9723                    language_server_id,
 9724                    token.clone(),
 9725                    LanguageServerProgress {
 9726                        title: Some(report.title),
 9727                        is_disk_based_diagnostics_progress,
 9728                        is_cancellable: report.cancellable.unwrap_or(false),
 9729                        message: report.message.clone(),
 9730                        percentage: report.percentage.map(|p| p as usize),
 9731                        last_update_at: cx.background_executor().now(),
 9732                    },
 9733                    cx,
 9734                );
 9735            }
 9736            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9737                language_server_id,
 9738                token,
 9739                LanguageServerProgress {
 9740                    title: None,
 9741                    is_disk_based_diagnostics_progress,
 9742                    is_cancellable: report.cancellable.unwrap_or(false),
 9743                    message: report.message,
 9744                    percentage: report.percentage.map(|p| p as usize),
 9745                    last_update_at: cx.background_executor().now(),
 9746                },
 9747                cx,
 9748            ),
 9749            lsp::WorkDoneProgress::End(_) => {
 9750                language_server_status.progress_tokens.remove(&token);
 9751                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9752                if is_disk_based_diagnostics_progress {
 9753                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9754                }
 9755            }
 9756        }
 9757    }
 9758
 9759    fn on_lsp_work_start(
 9760        &mut self,
 9761        language_server_id: LanguageServerId,
 9762        token: ProgressToken,
 9763        progress: LanguageServerProgress,
 9764        cx: &mut Context<Self>,
 9765    ) {
 9766        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9767            status.pending_work.insert(token.clone(), progress.clone());
 9768            cx.notify();
 9769        }
 9770        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9771            language_server_id,
 9772            name: self
 9773                .language_server_adapter_for_id(language_server_id)
 9774                .map(|adapter| adapter.name()),
 9775            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9776                token: Some(token.to_proto()),
 9777                title: progress.title,
 9778                message: progress.message,
 9779                percentage: progress.percentage.map(|p| p as u32),
 9780                is_cancellable: Some(progress.is_cancellable),
 9781            }),
 9782        })
 9783    }
 9784
 9785    fn on_lsp_work_progress(
 9786        &mut self,
 9787        language_server_id: LanguageServerId,
 9788        token: ProgressToken,
 9789        progress: LanguageServerProgress,
 9790        cx: &mut Context<Self>,
 9791    ) {
 9792        let mut did_update = false;
 9793        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9794            match status.pending_work.entry(token.clone()) {
 9795                btree_map::Entry::Vacant(entry) => {
 9796                    entry.insert(progress.clone());
 9797                    did_update = true;
 9798                }
 9799                btree_map::Entry::Occupied(mut entry) => {
 9800                    let entry = entry.get_mut();
 9801                    if (progress.last_update_at - entry.last_update_at)
 9802                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9803                    {
 9804                        entry.last_update_at = progress.last_update_at;
 9805                        if progress.message.is_some() {
 9806                            entry.message = progress.message.clone();
 9807                        }
 9808                        if progress.percentage.is_some() {
 9809                            entry.percentage = progress.percentage;
 9810                        }
 9811                        if progress.is_cancellable != entry.is_cancellable {
 9812                            entry.is_cancellable = progress.is_cancellable;
 9813                        }
 9814                        did_update = true;
 9815                    }
 9816                }
 9817            }
 9818        }
 9819
 9820        if did_update {
 9821            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9822                language_server_id,
 9823                name: self
 9824                    .language_server_adapter_for_id(language_server_id)
 9825                    .map(|adapter| adapter.name()),
 9826                message: proto::update_language_server::Variant::WorkProgress(
 9827                    proto::LspWorkProgress {
 9828                        token: Some(token.to_proto()),
 9829                        message: progress.message,
 9830                        percentage: progress.percentage.map(|p| p as u32),
 9831                        is_cancellable: Some(progress.is_cancellable),
 9832                    },
 9833                ),
 9834            })
 9835        }
 9836    }
 9837
 9838    fn on_lsp_work_end(
 9839        &mut self,
 9840        language_server_id: LanguageServerId,
 9841        token: ProgressToken,
 9842        cx: &mut Context<Self>,
 9843    ) {
 9844        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9845            if let Some(work) = status.pending_work.remove(&token)
 9846                && !work.is_disk_based_diagnostics_progress
 9847            {
 9848                cx.emit(LspStoreEvent::RefreshInlayHints {
 9849                    server_id: language_server_id,
 9850                    request_id: None,
 9851                });
 9852            }
 9853            cx.notify();
 9854        }
 9855
 9856        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9857            language_server_id,
 9858            name: self
 9859                .language_server_adapter_for_id(language_server_id)
 9860                .map(|adapter| adapter.name()),
 9861            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9862                token: Some(token.to_proto()),
 9863            }),
 9864        })
 9865    }
 9866
 9867    pub async fn handle_resolve_completion_documentation(
 9868        this: Entity<Self>,
 9869        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9870        mut cx: AsyncApp,
 9871    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9872        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9873
 9874        let completion = this
 9875            .read_with(&cx, |this, cx| {
 9876                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9877                let server = this
 9878                    .language_server_for_id(id)
 9879                    .with_context(|| format!("No language server {id}"))?;
 9880
 9881                anyhow::Ok(cx.background_spawn(async move {
 9882                    let can_resolve = server
 9883                        .capabilities()
 9884                        .completion_provider
 9885                        .as_ref()
 9886                        .and_then(|options| options.resolve_provider)
 9887                        .unwrap_or(false);
 9888                    if can_resolve {
 9889                        server
 9890                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9891                            .await
 9892                            .into_response()
 9893                            .context("resolve completion item")
 9894                    } else {
 9895                        anyhow::Ok(lsp_completion)
 9896                    }
 9897                }))
 9898            })??
 9899            .await?;
 9900
 9901        let mut documentation_is_markdown = false;
 9902        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9903        let documentation = match completion.documentation {
 9904            Some(lsp::Documentation::String(text)) => text,
 9905
 9906            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9907                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9908                value
 9909            }
 9910
 9911            _ => String::new(),
 9912        };
 9913
 9914        // If we have a new buffer_id, that means we're talking to a new client
 9915        // and want to check for new text_edits in the completion too.
 9916        let mut old_replace_start = None;
 9917        let mut old_replace_end = None;
 9918        let mut old_insert_start = None;
 9919        let mut old_insert_end = None;
 9920        let mut new_text = String::default();
 9921        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9922            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9923                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9924                anyhow::Ok(buffer.read(cx).snapshot())
 9925            })??;
 9926
 9927            if let Some(text_edit) = completion.text_edit.as_ref() {
 9928                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9929
 9930                if let Some(mut edit) = edit {
 9931                    LineEnding::normalize(&mut edit.new_text);
 9932
 9933                    new_text = edit.new_text;
 9934                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9935                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9936                    if let Some(insert_range) = edit.insert_range {
 9937                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9938                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9939                    }
 9940                }
 9941            }
 9942        }
 9943
 9944        Ok(proto::ResolveCompletionDocumentationResponse {
 9945            documentation,
 9946            documentation_is_markdown,
 9947            old_replace_start,
 9948            old_replace_end,
 9949            new_text,
 9950            lsp_completion,
 9951            old_insert_start,
 9952            old_insert_end,
 9953        })
 9954    }
 9955
 9956    async fn handle_on_type_formatting(
 9957        this: Entity<Self>,
 9958        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9959        mut cx: AsyncApp,
 9960    ) -> Result<proto::OnTypeFormattingResponse> {
 9961        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9962            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9963            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9964            let position = envelope
 9965                .payload
 9966                .position
 9967                .and_then(deserialize_anchor)
 9968                .context("invalid position")?;
 9969            anyhow::Ok(this.apply_on_type_formatting(
 9970                buffer,
 9971                position,
 9972                envelope.payload.trigger.clone(),
 9973                cx,
 9974            ))
 9975        })??;
 9976
 9977        let transaction = on_type_formatting
 9978            .await?
 9979            .as_ref()
 9980            .map(language::proto::serialize_transaction);
 9981        Ok(proto::OnTypeFormattingResponse { transaction })
 9982    }
 9983
 9984    async fn handle_refresh_inlay_hints(
 9985        lsp_store: Entity<Self>,
 9986        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9987        mut cx: AsyncApp,
 9988    ) -> Result<proto::Ack> {
 9989        lsp_store.update(&mut cx, |_, cx| {
 9990            cx.emit(LspStoreEvent::RefreshInlayHints {
 9991                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
 9992                request_id: envelope.payload.request_id.map(|id| id as usize),
 9993            });
 9994        })?;
 9995        Ok(proto::Ack {})
 9996    }
 9997
 9998    async fn handle_pull_workspace_diagnostics(
 9999        lsp_store: Entity<Self>,
10000        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10001        mut cx: AsyncApp,
10002    ) -> Result<proto::Ack> {
10003        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10004        lsp_store.update(&mut cx, |lsp_store, _| {
10005            lsp_store.pull_workspace_diagnostics(server_id);
10006        })?;
10007        Ok(proto::Ack {})
10008    }
10009
10010    async fn handle_get_color_presentation(
10011        lsp_store: Entity<Self>,
10012        envelope: TypedEnvelope<proto::GetColorPresentation>,
10013        mut cx: AsyncApp,
10014    ) -> Result<proto::GetColorPresentationResponse> {
10015        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10016        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10017            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10018        })??;
10019
10020        let color = envelope
10021            .payload
10022            .color
10023            .context("invalid color resolve request")?;
10024        let start = color
10025            .lsp_range_start
10026            .context("invalid color resolve request")?;
10027        let end = color
10028            .lsp_range_end
10029            .context("invalid color resolve request")?;
10030
10031        let color = DocumentColor {
10032            lsp_range: lsp::Range {
10033                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10034                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10035            },
10036            color: lsp::Color {
10037                red: color.red,
10038                green: color.green,
10039                blue: color.blue,
10040                alpha: color.alpha,
10041            },
10042            resolved: false,
10043            color_presentations: Vec::new(),
10044        };
10045        let resolved_color = lsp_store
10046            .update(&mut cx, |lsp_store, cx| {
10047                lsp_store.resolve_color_presentation(
10048                    color,
10049                    buffer.clone(),
10050                    LanguageServerId(envelope.payload.server_id as usize),
10051                    cx,
10052                )
10053            })?
10054            .await
10055            .context("resolving color presentation")?;
10056
10057        Ok(proto::GetColorPresentationResponse {
10058            presentations: resolved_color
10059                .color_presentations
10060                .into_iter()
10061                .map(|presentation| proto::ColorPresentation {
10062                    label: presentation.label.to_string(),
10063                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10064                    additional_text_edits: presentation
10065                        .additional_text_edits
10066                        .into_iter()
10067                        .map(serialize_lsp_edit)
10068                        .collect(),
10069                })
10070                .collect(),
10071        })
10072    }
10073
10074    async fn handle_resolve_inlay_hint(
10075        lsp_store: Entity<Self>,
10076        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10077        mut cx: AsyncApp,
10078    ) -> Result<proto::ResolveInlayHintResponse> {
10079        let proto_hint = envelope
10080            .payload
10081            .hint
10082            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10083        let hint = InlayHints::proto_to_project_hint(proto_hint)
10084            .context("resolved proto inlay hint conversion")?;
10085        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10086            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10087            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10088        })??;
10089        let response_hint = lsp_store
10090            .update(&mut cx, |lsp_store, cx| {
10091                lsp_store.resolve_inlay_hint(
10092                    hint,
10093                    buffer,
10094                    LanguageServerId(envelope.payload.language_server_id as usize),
10095                    cx,
10096                )
10097            })?
10098            .await
10099            .context("inlay hints fetch")?;
10100        Ok(proto::ResolveInlayHintResponse {
10101            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10102        })
10103    }
10104
10105    async fn handle_refresh_code_lens(
10106        this: Entity<Self>,
10107        _: TypedEnvelope<proto::RefreshCodeLens>,
10108        mut cx: AsyncApp,
10109    ) -> Result<proto::Ack> {
10110        this.update(&mut cx, |_, cx| {
10111            cx.emit(LspStoreEvent::RefreshCodeLens);
10112        })?;
10113        Ok(proto::Ack {})
10114    }
10115
10116    async fn handle_open_buffer_for_symbol(
10117        this: Entity<Self>,
10118        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10119        mut cx: AsyncApp,
10120    ) -> Result<proto::OpenBufferForSymbolResponse> {
10121        let peer_id = envelope.original_sender_id().unwrap_or_default();
10122        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10123        let symbol = Self::deserialize_symbol(symbol)?;
10124        this.read_with(&cx, |this, _| {
10125            if let SymbolLocation::OutsideProject {
10126                abs_path,
10127                signature,
10128            } = &symbol.path
10129            {
10130                let new_signature = this.symbol_signature(&abs_path);
10131                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10132            }
10133            Ok(())
10134        })??;
10135        let buffer = this
10136            .update(&mut cx, |this, cx| {
10137                this.open_buffer_for_symbol(
10138                    &Symbol {
10139                        language_server_name: symbol.language_server_name,
10140                        source_worktree_id: symbol.source_worktree_id,
10141                        source_language_server_id: symbol.source_language_server_id,
10142                        path: symbol.path,
10143                        name: symbol.name,
10144                        kind: symbol.kind,
10145                        range: symbol.range,
10146                        label: CodeLabel::default(),
10147                    },
10148                    cx,
10149                )
10150            })?
10151            .await?;
10152
10153        this.update(&mut cx, |this, cx| {
10154            let is_private = buffer
10155                .read(cx)
10156                .file()
10157                .map(|f| f.is_private())
10158                .unwrap_or_default();
10159            if is_private {
10160                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10161            } else {
10162                this.buffer_store
10163                    .update(cx, |buffer_store, cx| {
10164                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10165                    })
10166                    .detach_and_log_err(cx);
10167                let buffer_id = buffer.read(cx).remote_id().to_proto();
10168                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10169            }
10170        })?
10171    }
10172
10173    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10174        let mut hasher = Sha256::new();
10175        hasher.update(abs_path.to_string_lossy().as_bytes());
10176        hasher.update(self.nonce.to_be_bytes());
10177        hasher.finalize().as_slice().try_into().unwrap()
10178    }
10179
10180    pub async fn handle_get_project_symbols(
10181        this: Entity<Self>,
10182        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10183        mut cx: AsyncApp,
10184    ) -> Result<proto::GetProjectSymbolsResponse> {
10185        let symbols = this
10186            .update(&mut cx, |this, cx| {
10187                this.symbols(&envelope.payload.query, cx)
10188            })?
10189            .await?;
10190
10191        Ok(proto::GetProjectSymbolsResponse {
10192            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10193        })
10194    }
10195
10196    pub async fn handle_restart_language_servers(
10197        this: Entity<Self>,
10198        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10199        mut cx: AsyncApp,
10200    ) -> Result<proto::Ack> {
10201        this.update(&mut cx, |lsp_store, cx| {
10202            let buffers =
10203                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10204            lsp_store.restart_language_servers_for_buffers(
10205                buffers,
10206                envelope
10207                    .payload
10208                    .only_servers
10209                    .into_iter()
10210                    .filter_map(|selector| {
10211                        Some(match selector.selector? {
10212                            proto::language_server_selector::Selector::ServerId(server_id) => {
10213                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10214                            }
10215                            proto::language_server_selector::Selector::Name(name) => {
10216                                LanguageServerSelector::Name(LanguageServerName(
10217                                    SharedString::from(name),
10218                                ))
10219                            }
10220                        })
10221                    })
10222                    .collect(),
10223                cx,
10224            );
10225        })?;
10226
10227        Ok(proto::Ack {})
10228    }
10229
10230    pub async fn handle_stop_language_servers(
10231        lsp_store: Entity<Self>,
10232        envelope: TypedEnvelope<proto::StopLanguageServers>,
10233        mut cx: AsyncApp,
10234    ) -> Result<proto::Ack> {
10235        lsp_store.update(&mut cx, |lsp_store, cx| {
10236            if envelope.payload.all
10237                && envelope.payload.also_servers.is_empty()
10238                && envelope.payload.buffer_ids.is_empty()
10239            {
10240                lsp_store.stop_all_language_servers(cx);
10241            } else {
10242                let buffers =
10243                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10244                lsp_store
10245                    .stop_language_servers_for_buffers(
10246                        buffers,
10247                        envelope
10248                            .payload
10249                            .also_servers
10250                            .into_iter()
10251                            .filter_map(|selector| {
10252                                Some(match selector.selector? {
10253                                    proto::language_server_selector::Selector::ServerId(
10254                                        server_id,
10255                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10256                                        server_id,
10257                                    )),
10258                                    proto::language_server_selector::Selector::Name(name) => {
10259                                        LanguageServerSelector::Name(LanguageServerName(
10260                                            SharedString::from(name),
10261                                        ))
10262                                    }
10263                                })
10264                            })
10265                            .collect(),
10266                        cx,
10267                    )
10268                    .detach_and_log_err(cx);
10269            }
10270        })?;
10271
10272        Ok(proto::Ack {})
10273    }
10274
10275    pub async fn handle_cancel_language_server_work(
10276        lsp_store: Entity<Self>,
10277        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10278        mut cx: AsyncApp,
10279    ) -> Result<proto::Ack> {
10280        lsp_store.update(&mut cx, |lsp_store, cx| {
10281            if let Some(work) = envelope.payload.work {
10282                match work {
10283                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10284                        let buffers =
10285                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10286                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10287                    }
10288                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10289                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10290                        let token = work
10291                            .token
10292                            .map(|token| {
10293                                ProgressToken::from_proto(token)
10294                                    .context("invalid work progress token")
10295                            })
10296                            .transpose()?;
10297                        lsp_store.cancel_language_server_work(server_id, token, cx);
10298                    }
10299                }
10300            }
10301            anyhow::Ok(())
10302        })??;
10303
10304        Ok(proto::Ack {})
10305    }
10306
10307    fn buffer_ids_to_buffers(
10308        &mut self,
10309        buffer_ids: impl Iterator<Item = u64>,
10310        cx: &mut Context<Self>,
10311    ) -> Vec<Entity<Buffer>> {
10312        buffer_ids
10313            .into_iter()
10314            .flat_map(|buffer_id| {
10315                self.buffer_store
10316                    .read(cx)
10317                    .get(BufferId::new(buffer_id).log_err()?)
10318            })
10319            .collect::<Vec<_>>()
10320    }
10321
10322    async fn handle_apply_additional_edits_for_completion(
10323        this: Entity<Self>,
10324        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10325        mut cx: AsyncApp,
10326    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10327        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10328            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10329            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10330            let completion = Self::deserialize_completion(
10331                envelope.payload.completion.context("invalid completion")?,
10332            )?;
10333            anyhow::Ok((buffer, completion))
10334        })??;
10335
10336        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10337            this.apply_additional_edits_for_completion(
10338                buffer,
10339                Rc::new(RefCell::new(Box::new([Completion {
10340                    replace_range: completion.replace_range,
10341                    new_text: completion.new_text,
10342                    source: completion.source,
10343                    documentation: None,
10344                    label: CodeLabel::default(),
10345                    match_start: None,
10346                    snippet_deduplication_key: None,
10347                    insert_text_mode: None,
10348                    icon_path: None,
10349                    confirm: None,
10350                }]))),
10351                0,
10352                false,
10353                cx,
10354            )
10355        })?;
10356
10357        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10358            transaction: apply_additional_edits
10359                .await?
10360                .as_ref()
10361                .map(language::proto::serialize_transaction),
10362        })
10363    }
10364
10365    pub fn last_formatting_failure(&self) -> Option<&str> {
10366        self.last_formatting_failure.as_deref()
10367    }
10368
10369    pub fn reset_last_formatting_failure(&mut self) {
10370        self.last_formatting_failure = None;
10371    }
10372
10373    pub fn environment_for_buffer(
10374        &self,
10375        buffer: &Entity<Buffer>,
10376        cx: &mut Context<Self>,
10377    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10378        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10379            environment.update(cx, |env, cx| {
10380                env.buffer_environment(buffer, &self.worktree_store, cx)
10381            })
10382        } else {
10383            Task::ready(None).shared()
10384        }
10385    }
10386
10387    pub fn format(
10388        &mut self,
10389        buffers: HashSet<Entity<Buffer>>,
10390        target: LspFormatTarget,
10391        push_to_history: bool,
10392        trigger: FormatTrigger,
10393        cx: &mut Context<Self>,
10394    ) -> Task<anyhow::Result<ProjectTransaction>> {
10395        let logger = zlog::scoped!("format");
10396        if self.as_local().is_some() {
10397            zlog::trace!(logger => "Formatting locally");
10398            let logger = zlog::scoped!(logger => "local");
10399            let buffers = buffers
10400                .into_iter()
10401                .map(|buffer_handle| {
10402                    let buffer = buffer_handle.read(cx);
10403                    let buffer_abs_path = File::from_dyn(buffer.file())
10404                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10405
10406                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10407                })
10408                .collect::<Vec<_>>();
10409
10410            cx.spawn(async move |lsp_store, cx| {
10411                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10412
10413                for (handle, abs_path, id) in buffers {
10414                    let env = lsp_store
10415                        .update(cx, |lsp_store, cx| {
10416                            lsp_store.environment_for_buffer(&handle, cx)
10417                        })?
10418                        .await;
10419
10420                    let ranges = match &target {
10421                        LspFormatTarget::Buffers => None,
10422                        LspFormatTarget::Ranges(ranges) => {
10423                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10424                        }
10425                    };
10426
10427                    formattable_buffers.push(FormattableBuffer {
10428                        handle,
10429                        abs_path,
10430                        env,
10431                        ranges,
10432                    });
10433                }
10434                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10435
10436                let format_timer = zlog::time!(logger => "Formatting buffers");
10437                let result = LocalLspStore::format_locally(
10438                    lsp_store.clone(),
10439                    formattable_buffers,
10440                    push_to_history,
10441                    trigger,
10442                    logger,
10443                    cx,
10444                )
10445                .await;
10446                format_timer.end();
10447
10448                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10449
10450                lsp_store.update(cx, |lsp_store, _| {
10451                    lsp_store.update_last_formatting_failure(&result);
10452                })?;
10453
10454                result
10455            })
10456        } else if let Some((client, project_id)) = self.upstream_client() {
10457            zlog::trace!(logger => "Formatting remotely");
10458            let logger = zlog::scoped!(logger => "remote");
10459            // Don't support formatting ranges via remote
10460            match target {
10461                LspFormatTarget::Buffers => {}
10462                LspFormatTarget::Ranges(_) => {
10463                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10464                    return Task::ready(Ok(ProjectTransaction::default()));
10465                }
10466            }
10467
10468            let buffer_store = self.buffer_store();
10469            cx.spawn(async move |lsp_store, cx| {
10470                zlog::trace!(logger => "Sending remote format request");
10471                let request_timer = zlog::time!(logger => "remote format request");
10472                let result = client
10473                    .request(proto::FormatBuffers {
10474                        project_id,
10475                        trigger: trigger as i32,
10476                        buffer_ids: buffers
10477                            .iter()
10478                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10479                            .collect::<Result<_>>()?,
10480                    })
10481                    .await
10482                    .and_then(|result| result.transaction.context("missing transaction"));
10483                request_timer.end();
10484
10485                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10486
10487                lsp_store.update(cx, |lsp_store, _| {
10488                    lsp_store.update_last_formatting_failure(&result);
10489                })?;
10490
10491                let transaction_response = result?;
10492                let _timer = zlog::time!(logger => "deserializing project transaction");
10493                buffer_store
10494                    .update(cx, |buffer_store, cx| {
10495                        buffer_store.deserialize_project_transaction(
10496                            transaction_response,
10497                            push_to_history,
10498                            cx,
10499                        )
10500                    })?
10501                    .await
10502            })
10503        } else {
10504            zlog::trace!(logger => "Not formatting");
10505            Task::ready(Ok(ProjectTransaction::default()))
10506        }
10507    }
10508
10509    async fn handle_format_buffers(
10510        this: Entity<Self>,
10511        envelope: TypedEnvelope<proto::FormatBuffers>,
10512        mut cx: AsyncApp,
10513    ) -> Result<proto::FormatBuffersResponse> {
10514        let sender_id = envelope.original_sender_id().unwrap_or_default();
10515        let format = this.update(&mut cx, |this, cx| {
10516            let mut buffers = HashSet::default();
10517            for buffer_id in &envelope.payload.buffer_ids {
10518                let buffer_id = BufferId::new(*buffer_id)?;
10519                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10520            }
10521            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10522            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10523        })??;
10524
10525        let project_transaction = format.await?;
10526        let project_transaction = this.update(&mut cx, |this, cx| {
10527            this.buffer_store.update(cx, |buffer_store, cx| {
10528                buffer_store.serialize_project_transaction_for_peer(
10529                    project_transaction,
10530                    sender_id,
10531                    cx,
10532                )
10533            })
10534        })?;
10535        Ok(proto::FormatBuffersResponse {
10536            transaction: Some(project_transaction),
10537        })
10538    }
10539
10540    async fn handle_apply_code_action_kind(
10541        this: Entity<Self>,
10542        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10543        mut cx: AsyncApp,
10544    ) -> Result<proto::ApplyCodeActionKindResponse> {
10545        let sender_id = envelope.original_sender_id().unwrap_or_default();
10546        let format = this.update(&mut cx, |this, cx| {
10547            let mut buffers = HashSet::default();
10548            for buffer_id in &envelope.payload.buffer_ids {
10549                let buffer_id = BufferId::new(*buffer_id)?;
10550                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10551            }
10552            let kind = match envelope.payload.kind.as_str() {
10553                "" => CodeActionKind::EMPTY,
10554                "quickfix" => CodeActionKind::QUICKFIX,
10555                "refactor" => CodeActionKind::REFACTOR,
10556                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10557                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10558                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10559                "source" => CodeActionKind::SOURCE,
10560                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10561                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10562                _ => anyhow::bail!(
10563                    "Invalid code action kind {}",
10564                    envelope.payload.kind.as_str()
10565                ),
10566            };
10567            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10568        })??;
10569
10570        let project_transaction = format.await?;
10571        let project_transaction = this.update(&mut cx, |this, cx| {
10572            this.buffer_store.update(cx, |buffer_store, cx| {
10573                buffer_store.serialize_project_transaction_for_peer(
10574                    project_transaction,
10575                    sender_id,
10576                    cx,
10577                )
10578            })
10579        })?;
10580        Ok(proto::ApplyCodeActionKindResponse {
10581            transaction: Some(project_transaction),
10582        })
10583    }
10584
10585    async fn shutdown_language_server(
10586        server_state: Option<LanguageServerState>,
10587        name: LanguageServerName,
10588        cx: &mut AsyncApp,
10589    ) {
10590        let server = match server_state {
10591            Some(LanguageServerState::Starting { startup, .. }) => {
10592                let mut timer = cx
10593                    .background_executor()
10594                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10595                    .fuse();
10596
10597                select! {
10598                    server = startup.fuse() => server,
10599                    () = timer => {
10600                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10601                        None
10602                    },
10603                }
10604            }
10605
10606            Some(LanguageServerState::Running { server, .. }) => Some(server),
10607
10608            None => None,
10609        };
10610
10611        if let Some(server) = server
10612            && let Some(shutdown) = server.shutdown()
10613        {
10614            shutdown.await;
10615        }
10616    }
10617
10618    // Returns a list of all of the worktrees which no longer have a language server and the root path
10619    // for the stopped server
10620    fn stop_local_language_server(
10621        &mut self,
10622        server_id: LanguageServerId,
10623        cx: &mut Context<Self>,
10624    ) -> Task<()> {
10625        let local = match &mut self.mode {
10626            LspStoreMode::Local(local) => local,
10627            _ => {
10628                return Task::ready(());
10629            }
10630        };
10631
10632        // Remove this server ID from all entries in the given worktree.
10633        local
10634            .language_server_ids
10635            .retain(|_, state| state.id != server_id);
10636        self.buffer_store.update(cx, |buffer_store, cx| {
10637            for buffer in buffer_store.buffers() {
10638                buffer.update(cx, |buffer, cx| {
10639                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10640                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10641                });
10642            }
10643        });
10644
10645        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10646            summaries.retain(|path, summaries_by_server_id| {
10647                if summaries_by_server_id.remove(&server_id).is_some() {
10648                    if let Some((client, project_id)) = self.downstream_client.clone() {
10649                        client
10650                            .send(proto::UpdateDiagnosticSummary {
10651                                project_id,
10652                                worktree_id: worktree_id.to_proto(),
10653                                summary: Some(proto::DiagnosticSummary {
10654                                    path: path.as_ref().to_proto(),
10655                                    language_server_id: server_id.0 as u64,
10656                                    error_count: 0,
10657                                    warning_count: 0,
10658                                }),
10659                                more_summaries: Vec::new(),
10660                            })
10661                            .log_err();
10662                    }
10663                    !summaries_by_server_id.is_empty()
10664                } else {
10665                    true
10666                }
10667            });
10668        }
10669
10670        let local = self.as_local_mut().unwrap();
10671        for diagnostics in local.diagnostics.values_mut() {
10672            diagnostics.retain(|_, diagnostics_by_server_id| {
10673                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10674                    diagnostics_by_server_id.remove(ix);
10675                    !diagnostics_by_server_id.is_empty()
10676                } else {
10677                    true
10678                }
10679            });
10680        }
10681        local.language_server_watched_paths.remove(&server_id);
10682
10683        let server_state = local.language_servers.remove(&server_id);
10684        self.cleanup_lsp_data(server_id);
10685        let name = self
10686            .language_server_statuses
10687            .remove(&server_id)
10688            .map(|status| status.name)
10689            .or_else(|| {
10690                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10691                    Some(adapter.name())
10692                } else {
10693                    None
10694                }
10695            });
10696
10697        if let Some(name) = name {
10698            log::info!("stopping language server {name}");
10699            self.languages
10700                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10701            cx.notify();
10702
10703            return cx.spawn(async move |lsp_store, cx| {
10704                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10705                lsp_store
10706                    .update(cx, |lsp_store, cx| {
10707                        lsp_store
10708                            .languages
10709                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10710                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10711                        cx.notify();
10712                    })
10713                    .ok();
10714            });
10715        }
10716
10717        if server_state.is_some() {
10718            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10719        }
10720        Task::ready(())
10721    }
10722
10723    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10724        if let Some((client, project_id)) = self.upstream_client() {
10725            let request = client.request(proto::StopLanguageServers {
10726                project_id,
10727                buffer_ids: Vec::new(),
10728                also_servers: Vec::new(),
10729                all: true,
10730            });
10731            cx.background_spawn(request).detach_and_log_err(cx);
10732        } else {
10733            let Some(local) = self.as_local_mut() else {
10734                return;
10735            };
10736            let language_servers_to_stop = local
10737                .language_server_ids
10738                .values()
10739                .map(|state| state.id)
10740                .collect();
10741            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10742            let tasks = language_servers_to_stop
10743                .into_iter()
10744                .map(|server| self.stop_local_language_server(server, cx))
10745                .collect::<Vec<_>>();
10746            cx.background_spawn(async move {
10747                futures::future::join_all(tasks).await;
10748            })
10749            .detach();
10750        }
10751    }
10752
10753    pub fn restart_language_servers_for_buffers(
10754        &mut self,
10755        buffers: Vec<Entity<Buffer>>,
10756        only_restart_servers: HashSet<LanguageServerSelector>,
10757        cx: &mut Context<Self>,
10758    ) {
10759        if let Some((client, project_id)) = self.upstream_client() {
10760            let request = client.request(proto::RestartLanguageServers {
10761                project_id,
10762                buffer_ids: buffers
10763                    .into_iter()
10764                    .map(|b| b.read(cx).remote_id().to_proto())
10765                    .collect(),
10766                only_servers: only_restart_servers
10767                    .into_iter()
10768                    .map(|selector| {
10769                        let selector = match selector {
10770                            LanguageServerSelector::Id(language_server_id) => {
10771                                proto::language_server_selector::Selector::ServerId(
10772                                    language_server_id.to_proto(),
10773                                )
10774                            }
10775                            LanguageServerSelector::Name(language_server_name) => {
10776                                proto::language_server_selector::Selector::Name(
10777                                    language_server_name.to_string(),
10778                                )
10779                            }
10780                        };
10781                        proto::LanguageServerSelector {
10782                            selector: Some(selector),
10783                        }
10784                    })
10785                    .collect(),
10786                all: false,
10787            });
10788            cx.background_spawn(request).detach_and_log_err(cx);
10789        } else {
10790            let stop_task = if only_restart_servers.is_empty() {
10791                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10792            } else {
10793                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10794            };
10795            cx.spawn(async move |lsp_store, cx| {
10796                stop_task.await;
10797                lsp_store
10798                    .update(cx, |lsp_store, cx| {
10799                        for buffer in buffers {
10800                            lsp_store.register_buffer_with_language_servers(
10801                                &buffer,
10802                                only_restart_servers.clone(),
10803                                true,
10804                                cx,
10805                            );
10806                        }
10807                    })
10808                    .ok()
10809            })
10810            .detach();
10811        }
10812    }
10813
10814    pub fn stop_language_servers_for_buffers(
10815        &mut self,
10816        buffers: Vec<Entity<Buffer>>,
10817        also_stop_servers: HashSet<LanguageServerSelector>,
10818        cx: &mut Context<Self>,
10819    ) -> Task<Result<()>> {
10820        if let Some((client, project_id)) = self.upstream_client() {
10821            let request = client.request(proto::StopLanguageServers {
10822                project_id,
10823                buffer_ids: buffers
10824                    .into_iter()
10825                    .map(|b| b.read(cx).remote_id().to_proto())
10826                    .collect(),
10827                also_servers: also_stop_servers
10828                    .into_iter()
10829                    .map(|selector| {
10830                        let selector = match selector {
10831                            LanguageServerSelector::Id(language_server_id) => {
10832                                proto::language_server_selector::Selector::ServerId(
10833                                    language_server_id.to_proto(),
10834                                )
10835                            }
10836                            LanguageServerSelector::Name(language_server_name) => {
10837                                proto::language_server_selector::Selector::Name(
10838                                    language_server_name.to_string(),
10839                                )
10840                            }
10841                        };
10842                        proto::LanguageServerSelector {
10843                            selector: Some(selector),
10844                        }
10845                    })
10846                    .collect(),
10847                all: false,
10848            });
10849            cx.background_spawn(async move {
10850                let _ = request.await?;
10851                Ok(())
10852            })
10853        } else {
10854            let task =
10855                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10856            cx.background_spawn(async move {
10857                task.await;
10858                Ok(())
10859            })
10860        }
10861    }
10862
10863    fn stop_local_language_servers_for_buffers(
10864        &mut self,
10865        buffers: &[Entity<Buffer>],
10866        also_stop_servers: HashSet<LanguageServerSelector>,
10867        cx: &mut Context<Self>,
10868    ) -> Task<()> {
10869        let Some(local) = self.as_local_mut() else {
10870            return Task::ready(());
10871        };
10872        let mut language_server_names_to_stop = BTreeSet::default();
10873        let mut language_servers_to_stop = also_stop_servers
10874            .into_iter()
10875            .flat_map(|selector| match selector {
10876                LanguageServerSelector::Id(id) => Some(id),
10877                LanguageServerSelector::Name(name) => {
10878                    language_server_names_to_stop.insert(name);
10879                    None
10880                }
10881            })
10882            .collect::<BTreeSet<_>>();
10883
10884        let mut covered_worktrees = HashSet::default();
10885        for buffer in buffers {
10886            buffer.update(cx, |buffer, cx| {
10887                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10888                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10889                    && covered_worktrees.insert(worktree_id)
10890                {
10891                    language_server_names_to_stop.retain(|name| {
10892                        let old_ids_count = language_servers_to_stop.len();
10893                        let all_language_servers_with_this_name = local
10894                            .language_server_ids
10895                            .iter()
10896                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10897                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10898                        old_ids_count == language_servers_to_stop.len()
10899                    });
10900                }
10901            });
10902        }
10903        for name in language_server_names_to_stop {
10904            language_servers_to_stop.extend(
10905                local
10906                    .language_server_ids
10907                    .iter()
10908                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10909            );
10910        }
10911
10912        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10913        let tasks = language_servers_to_stop
10914            .into_iter()
10915            .map(|server| self.stop_local_language_server(server, cx))
10916            .collect::<Vec<_>>();
10917
10918        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10919    }
10920
10921    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10922        let (worktree, relative_path) =
10923            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10924
10925        let project_path = ProjectPath {
10926            worktree_id: worktree.read(cx).id(),
10927            path: relative_path,
10928        };
10929
10930        Some(
10931            self.buffer_store()
10932                .read(cx)
10933                .get_by_path(&project_path)?
10934                .read(cx),
10935        )
10936    }
10937
10938    #[cfg(any(test, feature = "test-support"))]
10939    pub fn update_diagnostics(
10940        &mut self,
10941        server_id: LanguageServerId,
10942        diagnostics: lsp::PublishDiagnosticsParams,
10943        result_id: Option<String>,
10944        source_kind: DiagnosticSourceKind,
10945        disk_based_sources: &[String],
10946        cx: &mut Context<Self>,
10947    ) -> Result<()> {
10948        self.merge_lsp_diagnostics(
10949            source_kind,
10950            vec![DocumentDiagnosticsUpdate {
10951                diagnostics,
10952                result_id,
10953                server_id,
10954                disk_based_sources: Cow::Borrowed(disk_based_sources),
10955            }],
10956            |_, _, _| false,
10957            cx,
10958        )
10959    }
10960
10961    pub fn merge_lsp_diagnostics(
10962        &mut self,
10963        source_kind: DiagnosticSourceKind,
10964        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10965        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10966        cx: &mut Context<Self>,
10967    ) -> Result<()> {
10968        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10969        let updates = lsp_diagnostics
10970            .into_iter()
10971            .filter_map(|update| {
10972                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10973                Some(DocumentDiagnosticsUpdate {
10974                    diagnostics: self.lsp_to_document_diagnostics(
10975                        abs_path,
10976                        source_kind,
10977                        update.server_id,
10978                        update.diagnostics,
10979                        &update.disk_based_sources,
10980                    ),
10981                    result_id: update.result_id,
10982                    server_id: update.server_id,
10983                    disk_based_sources: update.disk_based_sources,
10984                })
10985            })
10986            .collect();
10987        self.merge_diagnostic_entries(updates, merge, cx)?;
10988        Ok(())
10989    }
10990
10991    fn lsp_to_document_diagnostics(
10992        &mut self,
10993        document_abs_path: PathBuf,
10994        source_kind: DiagnosticSourceKind,
10995        server_id: LanguageServerId,
10996        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10997        disk_based_sources: &[String],
10998    ) -> DocumentDiagnostics {
10999        let mut diagnostics = Vec::default();
11000        let mut primary_diagnostic_group_ids = HashMap::default();
11001        let mut sources_by_group_id = HashMap::default();
11002        let mut supporting_diagnostics = HashMap::default();
11003
11004        let adapter = self.language_server_adapter_for_id(server_id);
11005
11006        // Ensure that primary diagnostics are always the most severe
11007        lsp_diagnostics
11008            .diagnostics
11009            .sort_by_key(|item| item.severity);
11010
11011        for diagnostic in &lsp_diagnostics.diagnostics {
11012            let source = diagnostic.source.as_ref();
11013            let range = range_from_lsp(diagnostic.range);
11014            let is_supporting = diagnostic
11015                .related_information
11016                .as_ref()
11017                .is_some_and(|infos| {
11018                    infos.iter().any(|info| {
11019                        primary_diagnostic_group_ids.contains_key(&(
11020                            source,
11021                            diagnostic.code.clone(),
11022                            range_from_lsp(info.location.range),
11023                        ))
11024                    })
11025                });
11026
11027            let is_unnecessary = diagnostic
11028                .tags
11029                .as_ref()
11030                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11031
11032            let underline = self
11033                .language_server_adapter_for_id(server_id)
11034                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11035
11036            if is_supporting {
11037                supporting_diagnostics.insert(
11038                    (source, diagnostic.code.clone(), range),
11039                    (diagnostic.severity, is_unnecessary),
11040                );
11041            } else {
11042                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11043                let is_disk_based =
11044                    source.is_some_and(|source| disk_based_sources.contains(source));
11045
11046                sources_by_group_id.insert(group_id, source);
11047                primary_diagnostic_group_ids
11048                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11049
11050                diagnostics.push(DiagnosticEntry {
11051                    range,
11052                    diagnostic: Diagnostic {
11053                        source: diagnostic.source.clone(),
11054                        source_kind,
11055                        code: diagnostic.code.clone(),
11056                        code_description: diagnostic
11057                            .code_description
11058                            .as_ref()
11059                            .and_then(|d| d.href.clone()),
11060                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11061                        markdown: adapter.as_ref().and_then(|adapter| {
11062                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11063                        }),
11064                        message: diagnostic.message.trim().to_string(),
11065                        group_id,
11066                        is_primary: true,
11067                        is_disk_based,
11068                        is_unnecessary,
11069                        underline,
11070                        data: diagnostic.data.clone(),
11071                    },
11072                });
11073                if let Some(infos) = &diagnostic.related_information {
11074                    for info in infos {
11075                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11076                            let range = range_from_lsp(info.location.range);
11077                            diagnostics.push(DiagnosticEntry {
11078                                range,
11079                                diagnostic: Diagnostic {
11080                                    source: diagnostic.source.clone(),
11081                                    source_kind,
11082                                    code: diagnostic.code.clone(),
11083                                    code_description: diagnostic
11084                                        .code_description
11085                                        .as_ref()
11086                                        .and_then(|d| d.href.clone()),
11087                                    severity: DiagnosticSeverity::INFORMATION,
11088                                    markdown: adapter.as_ref().and_then(|adapter| {
11089                                        adapter.diagnostic_message_to_markdown(&info.message)
11090                                    }),
11091                                    message: info.message.trim().to_string(),
11092                                    group_id,
11093                                    is_primary: false,
11094                                    is_disk_based,
11095                                    is_unnecessary: false,
11096                                    underline,
11097                                    data: diagnostic.data.clone(),
11098                                },
11099                            });
11100                        }
11101                    }
11102                }
11103            }
11104        }
11105
11106        for entry in &mut diagnostics {
11107            let diagnostic = &mut entry.diagnostic;
11108            if !diagnostic.is_primary {
11109                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11110                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11111                    source,
11112                    diagnostic.code.clone(),
11113                    entry.range.clone(),
11114                )) {
11115                    if let Some(severity) = severity {
11116                        diagnostic.severity = severity;
11117                    }
11118                    diagnostic.is_unnecessary = is_unnecessary;
11119                }
11120            }
11121        }
11122
11123        DocumentDiagnostics {
11124            diagnostics,
11125            document_abs_path,
11126            version: lsp_diagnostics.version,
11127        }
11128    }
11129
11130    fn insert_newly_running_language_server(
11131        &mut self,
11132        adapter: Arc<CachedLspAdapter>,
11133        language_server: Arc<LanguageServer>,
11134        server_id: LanguageServerId,
11135        key: LanguageServerSeed,
11136        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11137        cx: &mut Context<Self>,
11138    ) {
11139        let Some(local) = self.as_local_mut() else {
11140            return;
11141        };
11142        // If the language server for this key doesn't match the server id, don't store the
11143        // server. Which will cause it to be dropped, killing the process
11144        if local
11145            .language_server_ids
11146            .get(&key)
11147            .map(|state| state.id != server_id)
11148            .unwrap_or(false)
11149        {
11150            return;
11151        }
11152
11153        // Update language_servers collection with Running variant of LanguageServerState
11154        // indicating that the server is up and running and ready
11155        let workspace_folders = workspace_folders.lock().clone();
11156        language_server.set_workspace_folders(workspace_folders);
11157
11158        let workspace_diagnostics_refresh_tasks = language_server
11159            .capabilities()
11160            .diagnostic_provider
11161            .and_then(|provider| {
11162                local
11163                    .language_server_dynamic_registrations
11164                    .entry(server_id)
11165                    .or_default()
11166                    .diagnostics
11167                    .entry(None)
11168                    .or_insert(provider.clone());
11169                let workspace_refresher =
11170                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11171
11172                Some((None, workspace_refresher))
11173            })
11174            .into_iter()
11175            .collect();
11176        local.language_servers.insert(
11177            server_id,
11178            LanguageServerState::Running {
11179                workspace_diagnostics_refresh_tasks,
11180                adapter: adapter.clone(),
11181                server: language_server.clone(),
11182                simulate_disk_based_diagnostics_completion: None,
11183            },
11184        );
11185        local
11186            .languages
11187            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11188        if let Some(file_ops_caps) = language_server
11189            .capabilities()
11190            .workspace
11191            .as_ref()
11192            .and_then(|ws| ws.file_operations.as_ref())
11193        {
11194            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11195            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11196            if did_rename_caps.or(will_rename_caps).is_some() {
11197                let watcher = RenamePathsWatchedForServer::default()
11198                    .with_did_rename_patterns(did_rename_caps)
11199                    .with_will_rename_patterns(will_rename_caps);
11200                local
11201                    .language_server_paths_watched_for_rename
11202                    .insert(server_id, watcher);
11203            }
11204        }
11205
11206        self.language_server_statuses.insert(
11207            server_id,
11208            LanguageServerStatus {
11209                name: language_server.name(),
11210                pending_work: Default::default(),
11211                has_pending_diagnostic_updates: false,
11212                progress_tokens: Default::default(),
11213                worktree: Some(key.worktree_id),
11214                binary: Some(language_server.binary().clone()),
11215                configuration: Some(language_server.configuration().clone()),
11216                workspace_folders: language_server.workspace_folders(),
11217            },
11218        );
11219
11220        cx.emit(LspStoreEvent::LanguageServerAdded(
11221            server_id,
11222            language_server.name(),
11223            Some(key.worktree_id),
11224        ));
11225
11226        let server_capabilities = language_server.capabilities();
11227        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11228            downstream_client
11229                .send(proto::StartLanguageServer {
11230                    project_id: *project_id,
11231                    server: Some(proto::LanguageServer {
11232                        id: server_id.to_proto(),
11233                        name: language_server.name().to_string(),
11234                        worktree_id: Some(key.worktree_id.to_proto()),
11235                    }),
11236                    capabilities: serde_json::to_string(&server_capabilities)
11237                        .expect("serializing server LSP capabilities"),
11238                })
11239                .log_err();
11240        }
11241        self.lsp_server_capabilities
11242            .insert(server_id, server_capabilities);
11243
11244        // Tell the language server about every open buffer in the worktree that matches the language.
11245        // Also check for buffers in worktrees that reused this server
11246        let mut worktrees_using_server = vec![key.worktree_id];
11247        if let Some(local) = self.as_local() {
11248            // Find all worktrees that have this server in their language server tree
11249            for (worktree_id, servers) in &local.lsp_tree.instances {
11250                if *worktree_id != key.worktree_id {
11251                    for server_map in servers.roots.values() {
11252                        if server_map
11253                            .values()
11254                            .any(|(node, _)| node.id() == Some(server_id))
11255                        {
11256                            worktrees_using_server.push(*worktree_id);
11257                        }
11258                    }
11259                }
11260            }
11261        }
11262
11263        let mut buffer_paths_registered = Vec::new();
11264        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11265            let mut lsp_adapters = HashMap::default();
11266            for buffer_handle in buffer_store.buffers() {
11267                let buffer = buffer_handle.read(cx);
11268                let file = match File::from_dyn(buffer.file()) {
11269                    Some(file) => file,
11270                    None => continue,
11271                };
11272                let language = match buffer.language() {
11273                    Some(language) => language,
11274                    None => continue,
11275                };
11276
11277                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11278                    || !lsp_adapters
11279                        .entry(language.name())
11280                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11281                        .iter()
11282                        .any(|a| a.name == key.name)
11283                {
11284                    continue;
11285                }
11286                // didOpen
11287                let file = match file.as_local() {
11288                    Some(file) => file,
11289                    None => continue,
11290                };
11291
11292                let local = self.as_local_mut().unwrap();
11293
11294                let buffer_id = buffer.remote_id();
11295                if local.registered_buffers.contains_key(&buffer_id) {
11296                    let versions = local
11297                        .buffer_snapshots
11298                        .entry(buffer_id)
11299                        .or_default()
11300                        .entry(server_id)
11301                        .and_modify(|_| {
11302                            assert!(
11303                            false,
11304                            "There should not be an existing snapshot for a newly inserted buffer"
11305                        )
11306                        })
11307                        .or_insert_with(|| {
11308                            vec![LspBufferSnapshot {
11309                                version: 0,
11310                                snapshot: buffer.text_snapshot(),
11311                            }]
11312                        });
11313
11314                    let snapshot = versions.last().unwrap();
11315                    let version = snapshot.version;
11316                    let initial_snapshot = &snapshot.snapshot;
11317                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11318                    language_server.register_buffer(
11319                        uri,
11320                        adapter.language_id(&language.name()),
11321                        version,
11322                        initial_snapshot.text(),
11323                    );
11324                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11325                    local
11326                        .buffers_opened_in_servers
11327                        .entry(buffer_id)
11328                        .or_default()
11329                        .insert(server_id);
11330                }
11331                buffer_handle.update(cx, |buffer, cx| {
11332                    buffer.set_completion_triggers(
11333                        server_id,
11334                        language_server
11335                            .capabilities()
11336                            .completion_provider
11337                            .as_ref()
11338                            .and_then(|provider| {
11339                                provider
11340                                    .trigger_characters
11341                                    .as_ref()
11342                                    .map(|characters| characters.iter().cloned().collect())
11343                            })
11344                            .unwrap_or_default(),
11345                        cx,
11346                    )
11347                });
11348            }
11349        });
11350
11351        for (buffer_id, abs_path) in buffer_paths_registered {
11352            cx.emit(LspStoreEvent::LanguageServerUpdate {
11353                language_server_id: server_id,
11354                name: Some(adapter.name()),
11355                message: proto::update_language_server::Variant::RegisteredForBuffer(
11356                    proto::RegisteredForBuffer {
11357                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11358                        buffer_id: buffer_id.to_proto(),
11359                    },
11360                ),
11361            });
11362        }
11363
11364        cx.notify();
11365    }
11366
11367    pub fn language_servers_running_disk_based_diagnostics(
11368        &self,
11369    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11370        self.language_server_statuses
11371            .iter()
11372            .filter_map(|(id, status)| {
11373                if status.has_pending_diagnostic_updates {
11374                    Some(*id)
11375                } else {
11376                    None
11377                }
11378            })
11379    }
11380
11381    pub(crate) fn cancel_language_server_work_for_buffers(
11382        &mut self,
11383        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11384        cx: &mut Context<Self>,
11385    ) {
11386        if let Some((client, project_id)) = self.upstream_client() {
11387            let request = client.request(proto::CancelLanguageServerWork {
11388                project_id,
11389                work: Some(proto::cancel_language_server_work::Work::Buffers(
11390                    proto::cancel_language_server_work::Buffers {
11391                        buffer_ids: buffers
11392                            .into_iter()
11393                            .map(|b| b.read(cx).remote_id().to_proto())
11394                            .collect(),
11395                    },
11396                )),
11397            });
11398            cx.background_spawn(request).detach_and_log_err(cx);
11399        } else if let Some(local) = self.as_local() {
11400            let servers = buffers
11401                .into_iter()
11402                .flat_map(|buffer| {
11403                    buffer.update(cx, |buffer, cx| {
11404                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11405                    })
11406                })
11407                .collect::<HashSet<_>>();
11408            for server_id in servers {
11409                self.cancel_language_server_work(server_id, None, cx);
11410            }
11411        }
11412    }
11413
11414    pub(crate) fn cancel_language_server_work(
11415        &mut self,
11416        server_id: LanguageServerId,
11417        token_to_cancel: Option<ProgressToken>,
11418        cx: &mut Context<Self>,
11419    ) {
11420        if let Some(local) = self.as_local() {
11421            let status = self.language_server_statuses.get(&server_id);
11422            let server = local.language_servers.get(&server_id);
11423            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11424            {
11425                for (token, progress) in &status.pending_work {
11426                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11427                        && token != token_to_cancel
11428                    {
11429                        continue;
11430                    }
11431                    if progress.is_cancellable {
11432                        server
11433                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11434                                WorkDoneProgressCancelParams {
11435                                    token: token.to_lsp(),
11436                                },
11437                            )
11438                            .ok();
11439                    }
11440                }
11441            }
11442        } else if let Some((client, project_id)) = self.upstream_client() {
11443            let request = client.request(proto::CancelLanguageServerWork {
11444                project_id,
11445                work: Some(
11446                    proto::cancel_language_server_work::Work::LanguageServerWork(
11447                        proto::cancel_language_server_work::LanguageServerWork {
11448                            language_server_id: server_id.to_proto(),
11449                            token: token_to_cancel.map(|token| token.to_proto()),
11450                        },
11451                    ),
11452                ),
11453            });
11454            cx.background_spawn(request).detach_and_log_err(cx);
11455        }
11456    }
11457
11458    fn register_supplementary_language_server(
11459        &mut self,
11460        id: LanguageServerId,
11461        name: LanguageServerName,
11462        server: Arc<LanguageServer>,
11463        cx: &mut Context<Self>,
11464    ) {
11465        if let Some(local) = self.as_local_mut() {
11466            local
11467                .supplementary_language_servers
11468                .insert(id, (name.clone(), server));
11469            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11470        }
11471    }
11472
11473    fn unregister_supplementary_language_server(
11474        &mut self,
11475        id: LanguageServerId,
11476        cx: &mut Context<Self>,
11477    ) {
11478        if let Some(local) = self.as_local_mut() {
11479            local.supplementary_language_servers.remove(&id);
11480            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11481        }
11482    }
11483
11484    pub(crate) fn supplementary_language_servers(
11485        &self,
11486    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11487        self.as_local().into_iter().flat_map(|local| {
11488            local
11489                .supplementary_language_servers
11490                .iter()
11491                .map(|(id, (name, _))| (*id, name.clone()))
11492        })
11493    }
11494
11495    pub fn language_server_adapter_for_id(
11496        &self,
11497        id: LanguageServerId,
11498    ) -> Option<Arc<CachedLspAdapter>> {
11499        self.as_local()
11500            .and_then(|local| local.language_servers.get(&id))
11501            .and_then(|language_server_state| match language_server_state {
11502                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11503                _ => None,
11504            })
11505    }
11506
11507    pub(super) fn update_local_worktree_language_servers(
11508        &mut self,
11509        worktree_handle: &Entity<Worktree>,
11510        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11511        cx: &mut Context<Self>,
11512    ) {
11513        if changes.is_empty() {
11514            return;
11515        }
11516
11517        let Some(local) = self.as_local() else { return };
11518
11519        local.prettier_store.update(cx, |prettier_store, cx| {
11520            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11521        });
11522
11523        let worktree_id = worktree_handle.read(cx).id();
11524        let mut language_server_ids = local
11525            .language_server_ids
11526            .iter()
11527            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11528            .collect::<Vec<_>>();
11529        language_server_ids.sort();
11530        language_server_ids.dedup();
11531
11532        // let abs_path = worktree_handle.read(cx).abs_path();
11533        for server_id in &language_server_ids {
11534            if let Some(LanguageServerState::Running { server, .. }) =
11535                local.language_servers.get(server_id)
11536                && let Some(watched_paths) = local
11537                    .language_server_watched_paths
11538                    .get(server_id)
11539                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11540            {
11541                let params = lsp::DidChangeWatchedFilesParams {
11542                    changes: changes
11543                        .iter()
11544                        .filter_map(|(path, _, change)| {
11545                            if !watched_paths.is_match(path.as_std_path()) {
11546                                return None;
11547                            }
11548                            let typ = match change {
11549                                PathChange::Loaded => return None,
11550                                PathChange::Added => lsp::FileChangeType::CREATED,
11551                                PathChange::Removed => lsp::FileChangeType::DELETED,
11552                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11553                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11554                            };
11555                            let uri = lsp::Uri::from_file_path(
11556                                worktree_handle.read(cx).absolutize(&path),
11557                            )
11558                            .ok()?;
11559                            Some(lsp::FileEvent { uri, typ })
11560                        })
11561                        .collect(),
11562                };
11563                if !params.changes.is_empty() {
11564                    server
11565                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11566                        .ok();
11567                }
11568            }
11569        }
11570        for (path, _, _) in changes {
11571            if let Some(file_name) = path.file_name()
11572                && local.watched_manifest_filenames.contains(file_name)
11573            {
11574                self.request_workspace_config_refresh();
11575                break;
11576            }
11577        }
11578    }
11579
11580    pub fn wait_for_remote_buffer(
11581        &mut self,
11582        id: BufferId,
11583        cx: &mut Context<Self>,
11584    ) -> Task<Result<Entity<Buffer>>> {
11585        self.buffer_store.update(cx, |buffer_store, cx| {
11586            buffer_store.wait_for_remote_buffer(id, cx)
11587        })
11588    }
11589
11590    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11591        let mut result = proto::Symbol {
11592            language_server_name: symbol.language_server_name.0.to_string(),
11593            source_worktree_id: symbol.source_worktree_id.to_proto(),
11594            language_server_id: symbol.source_language_server_id.to_proto(),
11595            name: symbol.name.clone(),
11596            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11597            start: Some(proto::PointUtf16 {
11598                row: symbol.range.start.0.row,
11599                column: symbol.range.start.0.column,
11600            }),
11601            end: Some(proto::PointUtf16 {
11602                row: symbol.range.end.0.row,
11603                column: symbol.range.end.0.column,
11604            }),
11605            worktree_id: Default::default(),
11606            path: Default::default(),
11607            signature: Default::default(),
11608        };
11609        match &symbol.path {
11610            SymbolLocation::InProject(path) => {
11611                result.worktree_id = path.worktree_id.to_proto();
11612                result.path = path.path.to_proto();
11613            }
11614            SymbolLocation::OutsideProject {
11615                abs_path,
11616                signature,
11617            } => {
11618                result.path = abs_path.to_string_lossy().into_owned();
11619                result.signature = signature.to_vec();
11620            }
11621        }
11622        result
11623    }
11624
11625    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11626        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11627        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11628        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11629
11630        let path = if serialized_symbol.signature.is_empty() {
11631            SymbolLocation::InProject(ProjectPath {
11632                worktree_id,
11633                path: RelPath::from_proto(&serialized_symbol.path)
11634                    .context("invalid symbol path")?,
11635            })
11636        } else {
11637            SymbolLocation::OutsideProject {
11638                abs_path: Path::new(&serialized_symbol.path).into(),
11639                signature: serialized_symbol
11640                    .signature
11641                    .try_into()
11642                    .map_err(|_| anyhow!("invalid signature"))?,
11643            }
11644        };
11645
11646        let start = serialized_symbol.start.context("invalid start")?;
11647        let end = serialized_symbol.end.context("invalid end")?;
11648        Ok(CoreSymbol {
11649            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11650            source_worktree_id,
11651            source_language_server_id: LanguageServerId::from_proto(
11652                serialized_symbol.language_server_id,
11653            ),
11654            path,
11655            name: serialized_symbol.name,
11656            range: Unclipped(PointUtf16::new(start.row, start.column))
11657                ..Unclipped(PointUtf16::new(end.row, end.column)),
11658            kind,
11659        })
11660    }
11661
11662    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11663        let mut serialized_completion = proto::Completion {
11664            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11665            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11666            new_text: completion.new_text.clone(),
11667            ..proto::Completion::default()
11668        };
11669        match &completion.source {
11670            CompletionSource::Lsp {
11671                insert_range,
11672                server_id,
11673                lsp_completion,
11674                lsp_defaults,
11675                resolved,
11676            } => {
11677                let (old_insert_start, old_insert_end) = insert_range
11678                    .as_ref()
11679                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11680                    .unzip();
11681
11682                serialized_completion.old_insert_start = old_insert_start;
11683                serialized_completion.old_insert_end = old_insert_end;
11684                serialized_completion.source = proto::completion::Source::Lsp as i32;
11685                serialized_completion.server_id = server_id.0 as u64;
11686                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11687                serialized_completion.lsp_defaults = lsp_defaults
11688                    .as_deref()
11689                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11690                serialized_completion.resolved = *resolved;
11691            }
11692            CompletionSource::BufferWord {
11693                word_range,
11694                resolved,
11695            } => {
11696                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11697                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11698                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11699                serialized_completion.resolved = *resolved;
11700            }
11701            CompletionSource::Custom => {
11702                serialized_completion.source = proto::completion::Source::Custom as i32;
11703                serialized_completion.resolved = true;
11704            }
11705            CompletionSource::Dap { sort_text } => {
11706                serialized_completion.source = proto::completion::Source::Dap as i32;
11707                serialized_completion.sort_text = Some(sort_text.clone());
11708            }
11709        }
11710
11711        serialized_completion
11712    }
11713
11714    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11715        let old_replace_start = completion
11716            .old_replace_start
11717            .and_then(deserialize_anchor)
11718            .context("invalid old start")?;
11719        let old_replace_end = completion
11720            .old_replace_end
11721            .and_then(deserialize_anchor)
11722            .context("invalid old end")?;
11723        let insert_range = {
11724            match completion.old_insert_start.zip(completion.old_insert_end) {
11725                Some((start, end)) => {
11726                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11727                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11728                    Some(start..end)
11729                }
11730                None => None,
11731            }
11732        };
11733        Ok(CoreCompletion {
11734            replace_range: old_replace_start..old_replace_end,
11735            new_text: completion.new_text,
11736            source: match proto::completion::Source::from_i32(completion.source) {
11737                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11738                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11739                    insert_range,
11740                    server_id: LanguageServerId::from_proto(completion.server_id),
11741                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11742                    lsp_defaults: completion
11743                        .lsp_defaults
11744                        .as_deref()
11745                        .map(serde_json::from_slice)
11746                        .transpose()?,
11747                    resolved: completion.resolved,
11748                },
11749                Some(proto::completion::Source::BufferWord) => {
11750                    let word_range = completion
11751                        .buffer_word_start
11752                        .and_then(deserialize_anchor)
11753                        .context("invalid buffer word start")?
11754                        ..completion
11755                            .buffer_word_end
11756                            .and_then(deserialize_anchor)
11757                            .context("invalid buffer word end")?;
11758                    CompletionSource::BufferWord {
11759                        word_range,
11760                        resolved: completion.resolved,
11761                    }
11762                }
11763                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11764                    sort_text: completion
11765                        .sort_text
11766                        .context("expected sort text to exist")?,
11767                },
11768                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11769            },
11770        })
11771    }
11772
11773    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11774        let (kind, lsp_action) = match &action.lsp_action {
11775            LspAction::Action(code_action) => (
11776                proto::code_action::Kind::Action as i32,
11777                serde_json::to_vec(code_action).unwrap(),
11778            ),
11779            LspAction::Command(command) => (
11780                proto::code_action::Kind::Command as i32,
11781                serde_json::to_vec(command).unwrap(),
11782            ),
11783            LspAction::CodeLens(code_lens) => (
11784                proto::code_action::Kind::CodeLens as i32,
11785                serde_json::to_vec(code_lens).unwrap(),
11786            ),
11787        };
11788
11789        proto::CodeAction {
11790            server_id: action.server_id.0 as u64,
11791            start: Some(serialize_anchor(&action.range.start)),
11792            end: Some(serialize_anchor(&action.range.end)),
11793            lsp_action,
11794            kind,
11795            resolved: action.resolved,
11796        }
11797    }
11798
11799    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11800        let start = action
11801            .start
11802            .and_then(deserialize_anchor)
11803            .context("invalid start")?;
11804        let end = action
11805            .end
11806            .and_then(deserialize_anchor)
11807            .context("invalid end")?;
11808        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11809            Some(proto::code_action::Kind::Action) => {
11810                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11811            }
11812            Some(proto::code_action::Kind::Command) => {
11813                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11814            }
11815            Some(proto::code_action::Kind::CodeLens) => {
11816                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11817            }
11818            None => anyhow::bail!("Unknown action kind {}", action.kind),
11819        };
11820        Ok(CodeAction {
11821            server_id: LanguageServerId(action.server_id as usize),
11822            range: start..end,
11823            resolved: action.resolved,
11824            lsp_action,
11825        })
11826    }
11827
11828    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11829        match &formatting_result {
11830            Ok(_) => self.last_formatting_failure = None,
11831            Err(error) => {
11832                let error_string = format!("{error:#}");
11833                log::error!("Formatting failed: {error_string}");
11834                self.last_formatting_failure
11835                    .replace(error_string.lines().join(" "));
11836            }
11837        }
11838    }
11839
11840    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11841        self.lsp_server_capabilities.remove(&for_server);
11842        for lsp_data in self.lsp_data.values_mut() {
11843            lsp_data.remove_server_data(for_server);
11844        }
11845        if let Some(local) = self.as_local_mut() {
11846            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11847            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11848                buffer_servers.remove(&for_server);
11849            }
11850        }
11851    }
11852
11853    pub fn result_id(
11854        &self,
11855        server_id: LanguageServerId,
11856        buffer_id: BufferId,
11857        cx: &App,
11858    ) -> Option<String> {
11859        let abs_path = self
11860            .buffer_store
11861            .read(cx)
11862            .get(buffer_id)
11863            .and_then(|b| File::from_dyn(b.read(cx).file()))
11864            .map(|f| f.abs_path(cx))?;
11865        self.as_local()?
11866            .buffer_pull_diagnostics_result_ids
11867            .get(&server_id)?
11868            .get(&abs_path)?
11869            .clone()
11870    }
11871
11872    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11873        let Some(local) = self.as_local() else {
11874            return HashMap::default();
11875        };
11876        local
11877            .buffer_pull_diagnostics_result_ids
11878            .get(&server_id)
11879            .into_iter()
11880            .flatten()
11881            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11882            .collect()
11883    }
11884
11885    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11886        if let Some(LanguageServerState::Running {
11887            workspace_diagnostics_refresh_tasks,
11888            ..
11889        }) = self
11890            .as_local_mut()
11891            .and_then(|local| local.language_servers.get_mut(&server_id))
11892        {
11893            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11894                diagnostics.refresh_tx.try_send(()).ok();
11895            }
11896        }
11897    }
11898
11899    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11900        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11901            return;
11902        };
11903        let Some(local) = self.as_local_mut() else {
11904            return;
11905        };
11906
11907        for server_id in buffer.update(cx, |buffer, cx| {
11908            local.language_server_ids_for_buffer(buffer, cx)
11909        }) {
11910            if let Some(LanguageServerState::Running {
11911                workspace_diagnostics_refresh_tasks,
11912                ..
11913            }) = local.language_servers.get_mut(&server_id)
11914            {
11915                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11916                    diagnostics.refresh_tx.try_send(()).ok();
11917                }
11918            }
11919        }
11920    }
11921
11922    fn apply_workspace_diagnostic_report(
11923        &mut self,
11924        server_id: LanguageServerId,
11925        report: lsp::WorkspaceDiagnosticReportResult,
11926        cx: &mut Context<Self>,
11927    ) {
11928        let workspace_diagnostics =
11929            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11930        let mut unchanged_buffers = HashSet::default();
11931        let mut changed_buffers = HashSet::default();
11932        let workspace_diagnostics_updates = workspace_diagnostics
11933            .into_iter()
11934            .filter_map(
11935                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11936                    LspPullDiagnostics::Response {
11937                        server_id,
11938                        uri,
11939                        diagnostics,
11940                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11941                    LspPullDiagnostics::Default => None,
11942                },
11943            )
11944            .fold(
11945                HashMap::default(),
11946                |mut acc, (server_id, uri, diagnostics, version)| {
11947                    let (result_id, diagnostics) = match diagnostics {
11948                        PulledDiagnostics::Unchanged { result_id } => {
11949                            unchanged_buffers.insert(uri.clone());
11950                            (Some(result_id), Vec::new())
11951                        }
11952                        PulledDiagnostics::Changed {
11953                            result_id,
11954                            diagnostics,
11955                        } => {
11956                            changed_buffers.insert(uri.clone());
11957                            (result_id, diagnostics)
11958                        }
11959                    };
11960                    let disk_based_sources = Cow::Owned(
11961                        self.language_server_adapter_for_id(server_id)
11962                            .as_ref()
11963                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11964                            .unwrap_or(&[])
11965                            .to_vec(),
11966                    );
11967                    acc.entry(server_id)
11968                        .or_insert_with(Vec::new)
11969                        .push(DocumentDiagnosticsUpdate {
11970                            server_id,
11971                            diagnostics: lsp::PublishDiagnosticsParams {
11972                                uri,
11973                                diagnostics,
11974                                version,
11975                            },
11976                            result_id,
11977                            disk_based_sources,
11978                        });
11979                    acc
11980                },
11981            );
11982
11983        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11984            self.merge_lsp_diagnostics(
11985                DiagnosticSourceKind::Pulled,
11986                diagnostic_updates,
11987                |buffer, old_diagnostic, cx| {
11988                    File::from_dyn(buffer.file())
11989                        .and_then(|file| {
11990                            let abs_path = file.as_local()?.abs_path(cx);
11991                            lsp::Uri::from_file_path(abs_path).ok()
11992                        })
11993                        .is_none_or(|buffer_uri| {
11994                            unchanged_buffers.contains(&buffer_uri)
11995                                || match old_diagnostic.source_kind {
11996                                    DiagnosticSourceKind::Pulled => {
11997                                        !changed_buffers.contains(&buffer_uri)
11998                                    }
11999                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
12000                                        true
12001                                    }
12002                                }
12003                        })
12004                },
12005                cx,
12006            )
12007            .log_err();
12008        }
12009    }
12010
12011    fn register_server_capabilities(
12012        &mut self,
12013        server_id: LanguageServerId,
12014        params: lsp::RegistrationParams,
12015        cx: &mut Context<Self>,
12016    ) -> anyhow::Result<()> {
12017        let server = self
12018            .language_server_for_id(server_id)
12019            .with_context(|| format!("no server {server_id} found"))?;
12020        for reg in params.registrations {
12021            match reg.method.as_str() {
12022                "workspace/didChangeWatchedFiles" => {
12023                    if let Some(options) = reg.register_options {
12024                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12025                            let caps = serde_json::from_value(options)?;
12026                            local_lsp_store
12027                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12028                            true
12029                        } else {
12030                            false
12031                        };
12032                        if notify {
12033                            notify_server_capabilities_updated(&server, cx);
12034                        }
12035                    }
12036                }
12037                "workspace/didChangeConfiguration" => {
12038                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12039                }
12040                "workspace/didChangeWorkspaceFolders" => {
12041                    // In this case register options is an empty object, we can ignore it
12042                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12043                        supported: Some(true),
12044                        change_notifications: Some(OneOf::Right(reg.id)),
12045                    };
12046                    server.update_capabilities(|capabilities| {
12047                        capabilities
12048                            .workspace
12049                            .get_or_insert_default()
12050                            .workspace_folders = Some(caps);
12051                    });
12052                    notify_server_capabilities_updated(&server, cx);
12053                }
12054                "workspace/symbol" => {
12055                    let options = parse_register_capabilities(reg)?;
12056                    server.update_capabilities(|capabilities| {
12057                        capabilities.workspace_symbol_provider = Some(options);
12058                    });
12059                    notify_server_capabilities_updated(&server, cx);
12060                }
12061                "workspace/fileOperations" => {
12062                    if let Some(options) = reg.register_options {
12063                        let caps = serde_json::from_value(options)?;
12064                        server.update_capabilities(|capabilities| {
12065                            capabilities
12066                                .workspace
12067                                .get_or_insert_default()
12068                                .file_operations = Some(caps);
12069                        });
12070                        notify_server_capabilities_updated(&server, cx);
12071                    }
12072                }
12073                "workspace/executeCommand" => {
12074                    if let Some(options) = reg.register_options {
12075                        let options = serde_json::from_value(options)?;
12076                        server.update_capabilities(|capabilities| {
12077                            capabilities.execute_command_provider = Some(options);
12078                        });
12079                        notify_server_capabilities_updated(&server, cx);
12080                    }
12081                }
12082                "textDocument/rangeFormatting" => {
12083                    let options = parse_register_capabilities(reg)?;
12084                    server.update_capabilities(|capabilities| {
12085                        capabilities.document_range_formatting_provider = Some(options);
12086                    });
12087                    notify_server_capabilities_updated(&server, cx);
12088                }
12089                "textDocument/onTypeFormatting" => {
12090                    if let Some(options) = reg
12091                        .register_options
12092                        .map(serde_json::from_value)
12093                        .transpose()?
12094                    {
12095                        server.update_capabilities(|capabilities| {
12096                            capabilities.document_on_type_formatting_provider = Some(options);
12097                        });
12098                        notify_server_capabilities_updated(&server, cx);
12099                    }
12100                }
12101                "textDocument/formatting" => {
12102                    let options = parse_register_capabilities(reg)?;
12103                    server.update_capabilities(|capabilities| {
12104                        capabilities.document_formatting_provider = Some(options);
12105                    });
12106                    notify_server_capabilities_updated(&server, cx);
12107                }
12108                "textDocument/rename" => {
12109                    let options = parse_register_capabilities(reg)?;
12110                    server.update_capabilities(|capabilities| {
12111                        capabilities.rename_provider = Some(options);
12112                    });
12113                    notify_server_capabilities_updated(&server, cx);
12114                }
12115                "textDocument/inlayHint" => {
12116                    let options = parse_register_capabilities(reg)?;
12117                    server.update_capabilities(|capabilities| {
12118                        capabilities.inlay_hint_provider = Some(options);
12119                    });
12120                    notify_server_capabilities_updated(&server, cx);
12121                }
12122                "textDocument/documentSymbol" => {
12123                    let options = parse_register_capabilities(reg)?;
12124                    server.update_capabilities(|capabilities| {
12125                        capabilities.document_symbol_provider = Some(options);
12126                    });
12127                    notify_server_capabilities_updated(&server, cx);
12128                }
12129                "textDocument/codeAction" => {
12130                    let options = parse_register_capabilities(reg)?;
12131                    let provider = match options {
12132                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12133                        OneOf::Right(caps) => caps,
12134                    };
12135                    server.update_capabilities(|capabilities| {
12136                        capabilities.code_action_provider = Some(provider);
12137                    });
12138                    notify_server_capabilities_updated(&server, cx);
12139                }
12140                "textDocument/definition" => {
12141                    let options = parse_register_capabilities(reg)?;
12142                    server.update_capabilities(|capabilities| {
12143                        capabilities.definition_provider = Some(options);
12144                    });
12145                    notify_server_capabilities_updated(&server, cx);
12146                }
12147                "textDocument/completion" => {
12148                    if let Some(caps) = reg
12149                        .register_options
12150                        .map(serde_json::from_value::<CompletionOptions>)
12151                        .transpose()?
12152                    {
12153                        server.update_capabilities(|capabilities| {
12154                            capabilities.completion_provider = Some(caps.clone());
12155                        });
12156
12157                        if let Some(local) = self.as_local() {
12158                            let mut buffers_with_language_server = Vec::new();
12159                            for handle in self.buffer_store.read(cx).buffers() {
12160                                let buffer_id = handle.read(cx).remote_id();
12161                                if local
12162                                    .buffers_opened_in_servers
12163                                    .get(&buffer_id)
12164                                    .filter(|s| s.contains(&server_id))
12165                                    .is_some()
12166                                {
12167                                    buffers_with_language_server.push(handle);
12168                                }
12169                            }
12170                            let triggers = caps
12171                                .trigger_characters
12172                                .unwrap_or_default()
12173                                .into_iter()
12174                                .collect::<BTreeSet<_>>();
12175                            for handle in buffers_with_language_server {
12176                                let triggers = triggers.clone();
12177                                let _ = handle.update(cx, move |buffer, cx| {
12178                                    buffer.set_completion_triggers(server_id, triggers, cx);
12179                                });
12180                            }
12181                        }
12182                        notify_server_capabilities_updated(&server, cx);
12183                    }
12184                }
12185                "textDocument/hover" => {
12186                    let options = parse_register_capabilities(reg)?;
12187                    let provider = match options {
12188                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12189                        OneOf::Right(caps) => caps,
12190                    };
12191                    server.update_capabilities(|capabilities| {
12192                        capabilities.hover_provider = Some(provider);
12193                    });
12194                    notify_server_capabilities_updated(&server, cx);
12195                }
12196                "textDocument/signatureHelp" => {
12197                    if let Some(caps) = reg
12198                        .register_options
12199                        .map(serde_json::from_value)
12200                        .transpose()?
12201                    {
12202                        server.update_capabilities(|capabilities| {
12203                            capabilities.signature_help_provider = Some(caps);
12204                        });
12205                        notify_server_capabilities_updated(&server, cx);
12206                    }
12207                }
12208                "textDocument/didChange" => {
12209                    if let Some(sync_kind) = reg
12210                        .register_options
12211                        .and_then(|opts| opts.get("syncKind").cloned())
12212                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12213                        .transpose()?
12214                    {
12215                        server.update_capabilities(|capabilities| {
12216                            let mut sync_options =
12217                                Self::take_text_document_sync_options(capabilities);
12218                            sync_options.change = Some(sync_kind);
12219                            capabilities.text_document_sync =
12220                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12221                        });
12222                        notify_server_capabilities_updated(&server, cx);
12223                    }
12224                }
12225                "textDocument/didSave" => {
12226                    if let Some(include_text) = reg
12227                        .register_options
12228                        .map(|opts| {
12229                            let transpose = opts
12230                                .get("includeText")
12231                                .cloned()
12232                                .map(serde_json::from_value::<Option<bool>>)
12233                                .transpose();
12234                            match transpose {
12235                                Ok(value) => Ok(value.flatten()),
12236                                Err(e) => Err(e),
12237                            }
12238                        })
12239                        .transpose()?
12240                    {
12241                        server.update_capabilities(|capabilities| {
12242                            let mut sync_options =
12243                                Self::take_text_document_sync_options(capabilities);
12244                            sync_options.save =
12245                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12246                                    include_text,
12247                                }));
12248                            capabilities.text_document_sync =
12249                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12250                        });
12251                        notify_server_capabilities_updated(&server, cx);
12252                    }
12253                }
12254                "textDocument/codeLens" => {
12255                    if let Some(caps) = reg
12256                        .register_options
12257                        .map(serde_json::from_value)
12258                        .transpose()?
12259                    {
12260                        server.update_capabilities(|capabilities| {
12261                            capabilities.code_lens_provider = Some(caps);
12262                        });
12263                        notify_server_capabilities_updated(&server, cx);
12264                    }
12265                }
12266                "textDocument/diagnostic" => {
12267                    if let Some(caps) = reg
12268                        .register_options
12269                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12270                        .transpose()?
12271                    {
12272                        let local = self
12273                            .as_local_mut()
12274                            .context("Expected LSP Store to be local")?;
12275                        let state = local
12276                            .language_servers
12277                            .get_mut(&server_id)
12278                            .context("Could not obtain Language Servers state")?;
12279                        local
12280                            .language_server_dynamic_registrations
12281                            .entry(server_id)
12282                            .or_default()
12283                            .diagnostics
12284                            .insert(Some(reg.id.clone()), caps.clone());
12285
12286                        if let LanguageServerState::Running {
12287                            workspace_diagnostics_refresh_tasks,
12288                            ..
12289                        } = state
12290                            && let Some(task) = lsp_workspace_diagnostics_refresh(
12291                                Some(reg.id.clone()),
12292                                caps.clone(),
12293                                server.clone(),
12294                                cx,
12295                            )
12296                        {
12297                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12298                        }
12299
12300                        let mut did_update_caps = false;
12301                        server.update_capabilities(|capabilities| {
12302                            if capabilities.diagnostic_provider.as_ref().is_none_or(
12303                                |current_caps| {
12304                                    let supports_workspace_diagnostics =
12305                                        |capabilities: &DiagnosticServerCapabilities| {
12306                                            match capabilities {
12307                                            DiagnosticServerCapabilities::Options(
12308                                                diagnostic_options,
12309                                            ) => diagnostic_options.workspace_diagnostics,
12310                                            DiagnosticServerCapabilities::RegistrationOptions(
12311                                                diagnostic_registration_options,
12312                                            ) => {
12313                                                diagnostic_registration_options
12314                                                    .diagnostic_options
12315                                                    .workspace_diagnostics
12316                                            }
12317                                        }
12318                                        };
12319                                    // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
12320                                    // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
12321                                    // as it'll think that they're not supported.
12322                                    // If we did not support any workspace diagnostics up to this point but now do, let's update.
12323                                    !supports_workspace_diagnostics(current_caps)
12324                                        & supports_workspace_diagnostics(&caps)
12325                                },
12326                            ) {
12327                                did_update_caps = true;
12328                                capabilities.diagnostic_provider = Some(caps);
12329                            }
12330                        });
12331                        if did_update_caps {
12332                            notify_server_capabilities_updated(&server, cx);
12333                        }
12334                    }
12335                }
12336                "textDocument/documentColor" => {
12337                    let options = parse_register_capabilities(reg)?;
12338                    let provider = match options {
12339                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12340                        OneOf::Right(caps) => caps,
12341                    };
12342                    server.update_capabilities(|capabilities| {
12343                        capabilities.color_provider = Some(provider);
12344                    });
12345                    notify_server_capabilities_updated(&server, cx);
12346                }
12347                _ => log::warn!("unhandled capability registration: {reg:?}"),
12348            }
12349        }
12350
12351        Ok(())
12352    }
12353
12354    fn unregister_server_capabilities(
12355        &mut self,
12356        server_id: LanguageServerId,
12357        params: lsp::UnregistrationParams,
12358        cx: &mut Context<Self>,
12359    ) -> anyhow::Result<()> {
12360        let server = self
12361            .language_server_for_id(server_id)
12362            .with_context(|| format!("no server {server_id} found"))?;
12363        for unreg in params.unregisterations.iter() {
12364            match unreg.method.as_str() {
12365                "workspace/didChangeWatchedFiles" => {
12366                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12367                        local_lsp_store
12368                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12369                        true
12370                    } else {
12371                        false
12372                    };
12373                    if notify {
12374                        notify_server_capabilities_updated(&server, cx);
12375                    }
12376                }
12377                "workspace/didChangeConfiguration" => {
12378                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12379                }
12380                "workspace/didChangeWorkspaceFolders" => {
12381                    server.update_capabilities(|capabilities| {
12382                        capabilities
12383                            .workspace
12384                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12385                                workspace_folders: None,
12386                                file_operations: None,
12387                            })
12388                            .workspace_folders = None;
12389                    });
12390                    notify_server_capabilities_updated(&server, cx);
12391                }
12392                "workspace/symbol" => {
12393                    server.update_capabilities(|capabilities| {
12394                        capabilities.workspace_symbol_provider = None
12395                    });
12396                    notify_server_capabilities_updated(&server, cx);
12397                }
12398                "workspace/fileOperations" => {
12399                    server.update_capabilities(|capabilities| {
12400                        capabilities
12401                            .workspace
12402                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12403                                workspace_folders: None,
12404                                file_operations: None,
12405                            })
12406                            .file_operations = None;
12407                    });
12408                    notify_server_capabilities_updated(&server, cx);
12409                }
12410                "workspace/executeCommand" => {
12411                    server.update_capabilities(|capabilities| {
12412                        capabilities.execute_command_provider = None;
12413                    });
12414                    notify_server_capabilities_updated(&server, cx);
12415                }
12416                "textDocument/rangeFormatting" => {
12417                    server.update_capabilities(|capabilities| {
12418                        capabilities.document_range_formatting_provider = None
12419                    });
12420                    notify_server_capabilities_updated(&server, cx);
12421                }
12422                "textDocument/onTypeFormatting" => {
12423                    server.update_capabilities(|capabilities| {
12424                        capabilities.document_on_type_formatting_provider = None;
12425                    });
12426                    notify_server_capabilities_updated(&server, cx);
12427                }
12428                "textDocument/formatting" => {
12429                    server.update_capabilities(|capabilities| {
12430                        capabilities.document_formatting_provider = None;
12431                    });
12432                    notify_server_capabilities_updated(&server, cx);
12433                }
12434                "textDocument/rename" => {
12435                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12436                    notify_server_capabilities_updated(&server, cx);
12437                }
12438                "textDocument/codeAction" => {
12439                    server.update_capabilities(|capabilities| {
12440                        capabilities.code_action_provider = None;
12441                    });
12442                    notify_server_capabilities_updated(&server, cx);
12443                }
12444                "textDocument/definition" => {
12445                    server.update_capabilities(|capabilities| {
12446                        capabilities.definition_provider = None;
12447                    });
12448                    notify_server_capabilities_updated(&server, cx);
12449                }
12450                "textDocument/completion" => {
12451                    server.update_capabilities(|capabilities| {
12452                        capabilities.completion_provider = None;
12453                    });
12454                    notify_server_capabilities_updated(&server, cx);
12455                }
12456                "textDocument/hover" => {
12457                    server.update_capabilities(|capabilities| {
12458                        capabilities.hover_provider = None;
12459                    });
12460                    notify_server_capabilities_updated(&server, cx);
12461                }
12462                "textDocument/signatureHelp" => {
12463                    server.update_capabilities(|capabilities| {
12464                        capabilities.signature_help_provider = None;
12465                    });
12466                    notify_server_capabilities_updated(&server, cx);
12467                }
12468                "textDocument/didChange" => {
12469                    server.update_capabilities(|capabilities| {
12470                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12471                        sync_options.change = None;
12472                        capabilities.text_document_sync =
12473                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12474                    });
12475                    notify_server_capabilities_updated(&server, cx);
12476                }
12477                "textDocument/didSave" => {
12478                    server.update_capabilities(|capabilities| {
12479                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12480                        sync_options.save = None;
12481                        capabilities.text_document_sync =
12482                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12483                    });
12484                    notify_server_capabilities_updated(&server, cx);
12485                }
12486                "textDocument/codeLens" => {
12487                    server.update_capabilities(|capabilities| {
12488                        capabilities.code_lens_provider = None;
12489                    });
12490                    notify_server_capabilities_updated(&server, cx);
12491                }
12492                "textDocument/diagnostic" => {
12493                    let local = self
12494                        .as_local_mut()
12495                        .context("Expected LSP Store to be local")?;
12496
12497                    let state = local
12498                        .language_servers
12499                        .get_mut(&server_id)
12500                        .context("Could not obtain Language Servers state")?;
12501                    let options = local
12502                        .language_server_dynamic_registrations
12503                        .get_mut(&server_id)
12504                        .with_context(|| {
12505                            format!("Expected dynamic registration to exist for server {server_id}")
12506                        })?.diagnostics
12507                        .remove(&Some(unreg.id.clone()))
12508                        .with_context(|| format!(
12509                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12510                            unreg.id)
12511                        )?;
12512
12513                    let mut has_any_diagnostic_providers_still = true;
12514                    if let Some(identifier) = diagnostic_identifier(&options)
12515                        && let LanguageServerState::Running {
12516                            workspace_diagnostics_refresh_tasks,
12517                            ..
12518                        } = state
12519                    {
12520                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12521                        has_any_diagnostic_providers_still =
12522                            !workspace_diagnostics_refresh_tasks.is_empty();
12523                    }
12524
12525                    if !has_any_diagnostic_providers_still {
12526                        server.update_capabilities(|capabilities| {
12527                            debug_assert!(capabilities.diagnostic_provider.is_some());
12528                            capabilities.diagnostic_provider = None;
12529                        });
12530                    }
12531
12532                    notify_server_capabilities_updated(&server, cx);
12533                }
12534                "textDocument/documentColor" => {
12535                    server.update_capabilities(|capabilities| {
12536                        capabilities.color_provider = None;
12537                    });
12538                    notify_server_capabilities_updated(&server, cx);
12539                }
12540                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12541            }
12542        }
12543
12544        Ok(())
12545    }
12546
12547    async fn deduplicate_range_based_lsp_requests<T>(
12548        lsp_store: &Entity<Self>,
12549        server_id: Option<LanguageServerId>,
12550        lsp_request_id: LspRequestId,
12551        proto_request: &T::ProtoRequest,
12552        range: Range<Anchor>,
12553        cx: &mut AsyncApp,
12554    ) -> Result<()>
12555    where
12556        T: LspCommand,
12557        T::ProtoRequest: proto::LspRequestMessage,
12558    {
12559        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12560        let version = deserialize_version(proto_request.buffer_version());
12561        let buffer = lsp_store.update(cx, |this, cx| {
12562            this.buffer_store.read(cx).get_existing(buffer_id)
12563        })??;
12564        buffer
12565            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12566            .await?;
12567        lsp_store.update(cx, |lsp_store, cx| {
12568            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12569            let chunks_queried_for = lsp_data
12570                .inlay_hints
12571                .applicable_chunks(&[range])
12572                .collect::<Vec<_>>();
12573            match chunks_queried_for.as_slice() {
12574                &[chunk] => {
12575                    let key = LspKey {
12576                        request_type: TypeId::of::<T>(),
12577                        server_queried: server_id,
12578                    };
12579                    let previous_request = lsp_data
12580                        .chunk_lsp_requests
12581                        .entry(key)
12582                        .or_default()
12583                        .insert(chunk, lsp_request_id);
12584                    if let Some((previous_request, running_requests)) =
12585                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12586                    {
12587                        running_requests.remove(&previous_request);
12588                    }
12589                }
12590                _ambiguous_chunks => {
12591                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12592                    // there, a buffer version-based check will be performed and outdated requests discarded.
12593                }
12594            }
12595            anyhow::Ok(())
12596        })??;
12597
12598        Ok(())
12599    }
12600
12601    async fn query_lsp_locally<T>(
12602        lsp_store: Entity<Self>,
12603        for_server_id: Option<LanguageServerId>,
12604        sender_id: proto::PeerId,
12605        lsp_request_id: LspRequestId,
12606        proto_request: T::ProtoRequest,
12607        position: Option<Anchor>,
12608        cx: &mut AsyncApp,
12609    ) -> Result<()>
12610    where
12611        T: LspCommand + Clone,
12612        T::ProtoRequest: proto::LspRequestMessage,
12613        <T::ProtoRequest as proto::RequestMessage>::Response:
12614            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12615    {
12616        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12617        let version = deserialize_version(proto_request.buffer_version());
12618        let buffer = lsp_store.update(cx, |this, cx| {
12619            this.buffer_store.read(cx).get_existing(buffer_id)
12620        })??;
12621        buffer
12622            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12623            .await?;
12624        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12625        let request =
12626            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12627        let key = LspKey {
12628            request_type: TypeId::of::<T>(),
12629            server_queried: for_server_id,
12630        };
12631        lsp_store.update(cx, |lsp_store, cx| {
12632            let request_task = match for_server_id {
12633                Some(server_id) => {
12634                    let server_task = lsp_store.request_lsp(
12635                        buffer.clone(),
12636                        LanguageServerToQuery::Other(server_id),
12637                        request.clone(),
12638                        cx,
12639                    );
12640                    cx.background_spawn(async move {
12641                        let mut responses = Vec::new();
12642                        match server_task.await {
12643                            Ok(response) => responses.push((server_id, response)),
12644                            // rust-analyzer likes to error with this when its still loading up
12645                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12646                            Err(e) => log::error!(
12647                                "Error handling response for request {request:?}: {e:#}"
12648                            ),
12649                        }
12650                        responses
12651                    })
12652                }
12653                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12654            };
12655            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12656            if T::ProtoRequest::stop_previous_requests() {
12657                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12658                    lsp_requests.clear();
12659                }
12660            }
12661            lsp_data.lsp_requests.entry(key).or_default().insert(
12662                lsp_request_id,
12663                cx.spawn(async move |lsp_store, cx| {
12664                    let response = request_task.await;
12665                    lsp_store
12666                        .update(cx, |lsp_store, cx| {
12667                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12668                            {
12669                                let response = response
12670                                    .into_iter()
12671                                    .map(|(server_id, response)| {
12672                                        (
12673                                            server_id.to_proto(),
12674                                            T::response_to_proto(
12675                                                response,
12676                                                lsp_store,
12677                                                sender_id,
12678                                                &buffer_version,
12679                                                cx,
12680                                            )
12681                                            .into(),
12682                                        )
12683                                    })
12684                                    .collect::<HashMap<_, _>>();
12685                                match client.send_lsp_response::<T::ProtoRequest>(
12686                                    project_id,
12687                                    lsp_request_id,
12688                                    response,
12689                                ) {
12690                                    Ok(()) => {}
12691                                    Err(e) => {
12692                                        log::error!("Failed to send LSP response: {e:#}",)
12693                                    }
12694                                }
12695                            }
12696                        })
12697                        .ok();
12698                }),
12699            );
12700        })?;
12701        Ok(())
12702    }
12703
12704    fn take_text_document_sync_options(
12705        capabilities: &mut lsp::ServerCapabilities,
12706    ) -> lsp::TextDocumentSyncOptions {
12707        match capabilities.text_document_sync.take() {
12708            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12709            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12710                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12711                sync_options.change = Some(sync_kind);
12712                sync_options
12713            }
12714            None => lsp::TextDocumentSyncOptions::default(),
12715        }
12716    }
12717
12718    #[cfg(any(test, feature = "test-support"))]
12719    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12720        Some(
12721            self.lsp_data
12722                .get_mut(&buffer_id)?
12723                .code_lens
12724                .take()?
12725                .update
12726                .take()?
12727                .1,
12728        )
12729    }
12730
12731    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12732        self.downstream_client.clone()
12733    }
12734
12735    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12736        self.worktree_store.clone()
12737    }
12738
12739    /// Gets what's stored in the LSP data for the given buffer.
12740    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12741        self.lsp_data.get_mut(&buffer_id)
12742    }
12743
12744    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12745    /// new [`BufferLspData`] will be created to replace the previous state.
12746    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12747        let (buffer_id, buffer_version) =
12748            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12749        let lsp_data = self
12750            .lsp_data
12751            .entry(buffer_id)
12752            .or_insert_with(|| BufferLspData::new(buffer, cx));
12753        if buffer_version.changed_since(&lsp_data.buffer_version) {
12754            *lsp_data = BufferLspData::new(buffer, cx);
12755        }
12756        lsp_data
12757    }
12758}
12759
12760// Registration with registerOptions as null, should fallback to true.
12761// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12762fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12763    reg: lsp::Registration,
12764) -> Result<OneOf<bool, T>> {
12765    Ok(match reg.register_options {
12766        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12767        None => OneOf::Left(true),
12768    })
12769}
12770
12771fn subscribe_to_binary_statuses(
12772    languages: &Arc<LanguageRegistry>,
12773    cx: &mut Context<'_, LspStore>,
12774) -> Task<()> {
12775    let mut server_statuses = languages.language_server_binary_statuses();
12776    cx.spawn(async move |lsp_store, cx| {
12777        while let Some((server_name, binary_status)) = server_statuses.next().await {
12778            if lsp_store
12779                .update(cx, |_, cx| {
12780                    let mut message = None;
12781                    let binary_status = match binary_status {
12782                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12783                        BinaryStatus::CheckingForUpdate => {
12784                            proto::ServerBinaryStatus::CheckingForUpdate
12785                        }
12786                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12787                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12788                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12789                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12790                        BinaryStatus::Failed { error } => {
12791                            message = Some(error);
12792                            proto::ServerBinaryStatus::Failed
12793                        }
12794                    };
12795                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12796                        // Binary updates are about the binary that might not have any language server id at that point.
12797                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12798                        language_server_id: LanguageServerId(0),
12799                        name: Some(server_name),
12800                        message: proto::update_language_server::Variant::StatusUpdate(
12801                            proto::StatusUpdate {
12802                                message,
12803                                status: Some(proto::status_update::Status::Binary(
12804                                    binary_status as i32,
12805                                )),
12806                            },
12807                        ),
12808                    });
12809                })
12810                .is_err()
12811            {
12812                break;
12813            }
12814        }
12815    })
12816}
12817
12818fn lsp_workspace_diagnostics_refresh(
12819    registration_id: Option<String>,
12820    options: DiagnosticServerCapabilities,
12821    server: Arc<LanguageServer>,
12822    cx: &mut Context<'_, LspStore>,
12823) -> Option<WorkspaceRefreshTask> {
12824    let identifier = diagnostic_identifier(&options)?;
12825
12826    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12827    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12828    refresh_tx.try_send(()).ok();
12829
12830    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12831        let mut attempts = 0;
12832        let max_attempts = 50;
12833        let mut requests = 0;
12834
12835        loop {
12836            let Some(()) = refresh_rx.recv().await else {
12837                return;
12838            };
12839
12840            'request: loop {
12841                requests += 1;
12842                if attempts > max_attempts {
12843                    log::error!(
12844                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12845                    );
12846                    return;
12847                }
12848                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12849                cx.background_executor()
12850                    .timer(Duration::from_millis(backoff_millis))
12851                    .await;
12852                attempts += 1;
12853
12854                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12855                    lsp_store
12856                        .all_result_ids(server.server_id())
12857                        .into_iter()
12858                        .filter_map(|(abs_path, result_id)| {
12859                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12860                            Some(lsp::PreviousResultId {
12861                                uri,
12862                                value: result_id,
12863                            })
12864                        })
12865                        .collect()
12866                }) else {
12867                    return;
12868                };
12869
12870                let token = if let Some(identifier) = &registration_id {
12871                    format!(
12872                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{identifier}",
12873                        server.server_id(),
12874                    )
12875                } else {
12876                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12877                };
12878
12879                progress_rx.try_recv().ok();
12880                let timer =
12881                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12882                let progress = pin!(progress_rx.recv().fuse());
12883                let response_result = server
12884                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12885                        lsp::WorkspaceDiagnosticParams {
12886                            previous_result_ids,
12887                            identifier: identifier.clone(),
12888                            work_done_progress_params: Default::default(),
12889                            partial_result_params: lsp::PartialResultParams {
12890                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12891                            },
12892                        },
12893                        select(timer, progress).then(|either| match either {
12894                            Either::Left((message, ..)) => ready(message).left_future(),
12895                            Either::Right(..) => pending::<String>().right_future(),
12896                        }),
12897                    )
12898                    .await;
12899
12900                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12901                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12902                match response_result {
12903                    ConnectionResult::Timeout => {
12904                        log::error!("Timeout during workspace diagnostics pull");
12905                        continue 'request;
12906                    }
12907                    ConnectionResult::ConnectionReset => {
12908                        log::error!("Server closed a workspace diagnostics pull request");
12909                        continue 'request;
12910                    }
12911                    ConnectionResult::Result(Err(e)) => {
12912                        log::error!("Error during workspace diagnostics pull: {e:#}");
12913                        break 'request;
12914                    }
12915                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12916                        attempts = 0;
12917                        if lsp_store
12918                            .update(cx, |lsp_store, cx| {
12919                                lsp_store.apply_workspace_diagnostic_report(
12920                                    server.server_id(),
12921                                    pulled_diagnostics,
12922                                    cx,
12923                                )
12924                            })
12925                            .is_err()
12926                        {
12927                            return;
12928                        }
12929                        break 'request;
12930                    }
12931                }
12932            }
12933        }
12934    });
12935
12936    Some(WorkspaceRefreshTask {
12937        refresh_tx,
12938        progress_tx,
12939        task: workspace_query_language_server,
12940    })
12941}
12942
12943fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12944    match &options {
12945        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12946            if !diagnostic_options.workspace_diagnostics {
12947                return None;
12948            }
12949            Some(diagnostic_options.identifier.clone())
12950        }
12951        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12952            let diagnostic_options = &registration_options.diagnostic_options;
12953            if !diagnostic_options.workspace_diagnostics {
12954                return None;
12955            }
12956            Some(diagnostic_options.identifier.clone())
12957        }
12958    }
12959}
12960
12961fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12962    let CompletionSource::BufferWord {
12963        word_range,
12964        resolved,
12965    } = &mut completion.source
12966    else {
12967        return;
12968    };
12969    if *resolved {
12970        return;
12971    }
12972
12973    if completion.new_text
12974        != snapshot
12975            .text_for_range(word_range.clone())
12976            .collect::<String>()
12977    {
12978        return;
12979    }
12980
12981    let mut offset = 0;
12982    for chunk in snapshot.chunks(word_range.clone(), true) {
12983        let end_offset = offset + chunk.text.len();
12984        if let Some(highlight_id) = chunk.syntax_highlight_id {
12985            completion
12986                .label
12987                .runs
12988                .push((offset..end_offset, highlight_id));
12989        }
12990        offset = end_offset;
12991    }
12992    *resolved = true;
12993}
12994
12995impl EventEmitter<LspStoreEvent> for LspStore {}
12996
12997fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12998    hover
12999        .contents
13000        .retain(|hover_block| !hover_block.text.trim().is_empty());
13001    if hover.contents.is_empty() {
13002        None
13003    } else {
13004        Some(hover)
13005    }
13006}
13007
13008async fn populate_labels_for_completions(
13009    new_completions: Vec<CoreCompletion>,
13010    language: Option<Arc<Language>>,
13011    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13012) -> Vec<Completion> {
13013    let lsp_completions = new_completions
13014        .iter()
13015        .filter_map(|new_completion| {
13016            new_completion
13017                .source
13018                .lsp_completion(true)
13019                .map(|lsp_completion| lsp_completion.into_owned())
13020        })
13021        .collect::<Vec<_>>();
13022
13023    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13024        lsp_adapter
13025            .labels_for_completions(&lsp_completions, language)
13026            .await
13027            .log_err()
13028            .unwrap_or_default()
13029    } else {
13030        Vec::new()
13031    }
13032    .into_iter()
13033    .fuse();
13034
13035    let mut completions = Vec::new();
13036    for completion in new_completions {
13037        match completion.source.lsp_completion(true) {
13038            Some(lsp_completion) => {
13039                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13040
13041                let mut label = labels.next().flatten().unwrap_or_else(|| {
13042                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13043                });
13044                ensure_uniform_list_compatible_label(&mut label);
13045                completions.push(Completion {
13046                    label,
13047                    documentation,
13048                    replace_range: completion.replace_range,
13049                    new_text: completion.new_text,
13050                    insert_text_mode: lsp_completion.insert_text_mode,
13051                    source: completion.source,
13052                    icon_path: None,
13053                    confirm: None,
13054                    match_start: None,
13055                    snippet_deduplication_key: None,
13056                });
13057            }
13058            None => {
13059                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13060                ensure_uniform_list_compatible_label(&mut label);
13061                completions.push(Completion {
13062                    label,
13063                    documentation: None,
13064                    replace_range: completion.replace_range,
13065                    new_text: completion.new_text,
13066                    source: completion.source,
13067                    insert_text_mode: None,
13068                    icon_path: None,
13069                    confirm: None,
13070                    match_start: None,
13071                    snippet_deduplication_key: None,
13072                });
13073            }
13074        }
13075    }
13076    completions
13077}
13078
13079#[derive(Debug)]
13080pub enum LanguageServerToQuery {
13081    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13082    FirstCapable,
13083    /// Query a specific language server.
13084    Other(LanguageServerId),
13085}
13086
13087#[derive(Default)]
13088struct RenamePathsWatchedForServer {
13089    did_rename: Vec<RenameActionPredicate>,
13090    will_rename: Vec<RenameActionPredicate>,
13091}
13092
13093impl RenamePathsWatchedForServer {
13094    fn with_did_rename_patterns(
13095        mut self,
13096        did_rename: Option<&FileOperationRegistrationOptions>,
13097    ) -> Self {
13098        if let Some(did_rename) = did_rename {
13099            self.did_rename = did_rename
13100                .filters
13101                .iter()
13102                .filter_map(|filter| filter.try_into().log_err())
13103                .collect();
13104        }
13105        self
13106    }
13107    fn with_will_rename_patterns(
13108        mut self,
13109        will_rename: Option<&FileOperationRegistrationOptions>,
13110    ) -> Self {
13111        if let Some(will_rename) = will_rename {
13112            self.will_rename = will_rename
13113                .filters
13114                .iter()
13115                .filter_map(|filter| filter.try_into().log_err())
13116                .collect();
13117        }
13118        self
13119    }
13120
13121    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13122        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13123    }
13124    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13125        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13126    }
13127}
13128
13129impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13130    type Error = globset::Error;
13131    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13132        Ok(Self {
13133            kind: ops.pattern.matches.clone(),
13134            glob: GlobBuilder::new(&ops.pattern.glob)
13135                .case_insensitive(
13136                    ops.pattern
13137                        .options
13138                        .as_ref()
13139                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13140                )
13141                .build()?
13142                .compile_matcher(),
13143        })
13144    }
13145}
13146struct RenameActionPredicate {
13147    glob: GlobMatcher,
13148    kind: Option<FileOperationPatternKind>,
13149}
13150
13151impl RenameActionPredicate {
13152    // Returns true if language server should be notified
13153    fn eval(&self, path: &str, is_dir: bool) -> bool {
13154        self.kind.as_ref().is_none_or(|kind| {
13155            let expected_kind = if is_dir {
13156                FileOperationPatternKind::Folder
13157            } else {
13158                FileOperationPatternKind::File
13159            };
13160            kind == &expected_kind
13161        }) && self.glob.is_match(path)
13162    }
13163}
13164
13165#[derive(Default)]
13166struct LanguageServerWatchedPaths {
13167    worktree_paths: HashMap<WorktreeId, GlobSet>,
13168    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13169}
13170
13171#[derive(Default)]
13172struct LanguageServerWatchedPathsBuilder {
13173    worktree_paths: HashMap<WorktreeId, GlobSet>,
13174    abs_paths: HashMap<Arc<Path>, GlobSet>,
13175}
13176
13177impl LanguageServerWatchedPathsBuilder {
13178    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13179        self.worktree_paths.insert(worktree_id, glob_set);
13180    }
13181    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13182        self.abs_paths.insert(path, glob_set);
13183    }
13184    fn build(
13185        self,
13186        fs: Arc<dyn Fs>,
13187        language_server_id: LanguageServerId,
13188        cx: &mut Context<LspStore>,
13189    ) -> LanguageServerWatchedPaths {
13190        let lsp_store = cx.weak_entity();
13191
13192        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13193        let abs_paths = self
13194            .abs_paths
13195            .into_iter()
13196            .map(|(abs_path, globset)| {
13197                let task = cx.spawn({
13198                    let abs_path = abs_path.clone();
13199                    let fs = fs.clone();
13200
13201                    let lsp_store = lsp_store.clone();
13202                    async move |_, cx| {
13203                        maybe!(async move {
13204                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13205                            while let Some(update) = push_updates.0.next().await {
13206                                let action = lsp_store
13207                                    .update(cx, |this, _| {
13208                                        let Some(local) = this.as_local() else {
13209                                            return ControlFlow::Break(());
13210                                        };
13211                                        let Some(watcher) = local
13212                                            .language_server_watched_paths
13213                                            .get(&language_server_id)
13214                                        else {
13215                                            return ControlFlow::Break(());
13216                                        };
13217                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13218                                            "Watched abs path is not registered with a watcher",
13219                                        );
13220                                        let matching_entries = update
13221                                            .into_iter()
13222                                            .filter(|event| globs.is_match(&event.path))
13223                                            .collect::<Vec<_>>();
13224                                        this.lsp_notify_abs_paths_changed(
13225                                            language_server_id,
13226                                            matching_entries,
13227                                        );
13228                                        ControlFlow::Continue(())
13229                                    })
13230                                    .ok()?;
13231
13232                                if action.is_break() {
13233                                    break;
13234                                }
13235                            }
13236                            Some(())
13237                        })
13238                        .await;
13239                    }
13240                });
13241                (abs_path, (globset, task))
13242            })
13243            .collect();
13244        LanguageServerWatchedPaths {
13245            worktree_paths: self.worktree_paths,
13246            abs_paths,
13247        }
13248    }
13249}
13250
13251struct LspBufferSnapshot {
13252    version: i32,
13253    snapshot: TextBufferSnapshot,
13254}
13255
13256/// A prompt requested by LSP server.
13257#[derive(Clone, Debug)]
13258pub struct LanguageServerPromptRequest {
13259    pub level: PromptLevel,
13260    pub message: String,
13261    pub actions: Vec<MessageActionItem>,
13262    pub lsp_name: String,
13263    pub(crate) response_channel: Sender<MessageActionItem>,
13264}
13265
13266impl LanguageServerPromptRequest {
13267    pub async fn respond(self, index: usize) -> Option<()> {
13268        if let Some(response) = self.actions.into_iter().nth(index) {
13269            self.response_channel.send(response).await.ok()
13270        } else {
13271            None
13272        }
13273    }
13274}
13275impl PartialEq for LanguageServerPromptRequest {
13276    fn eq(&self, other: &Self) -> bool {
13277        self.message == other.message && self.actions == other.actions
13278    }
13279}
13280
13281#[derive(Clone, Debug, PartialEq)]
13282pub enum LanguageServerLogType {
13283    Log(MessageType),
13284    Trace { verbose_info: Option<String> },
13285    Rpc { received: bool },
13286}
13287
13288impl LanguageServerLogType {
13289    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13290        match self {
13291            Self::Log(log_type) => {
13292                use proto::log_message::LogLevel;
13293                let level = match *log_type {
13294                    MessageType::ERROR => LogLevel::Error,
13295                    MessageType::WARNING => LogLevel::Warning,
13296                    MessageType::INFO => LogLevel::Info,
13297                    MessageType::LOG => LogLevel::Log,
13298                    other => {
13299                        log::warn!("Unknown lsp log message type: {other:?}");
13300                        LogLevel::Log
13301                    }
13302                };
13303                proto::language_server_log::LogType::Log(proto::LogMessage {
13304                    level: level as i32,
13305                })
13306            }
13307            Self::Trace { verbose_info } => {
13308                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13309                    verbose_info: verbose_info.to_owned(),
13310                })
13311            }
13312            Self::Rpc { received } => {
13313                let kind = if *received {
13314                    proto::rpc_message::Kind::Received
13315                } else {
13316                    proto::rpc_message::Kind::Sent
13317                };
13318                let kind = kind as i32;
13319                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13320            }
13321        }
13322    }
13323
13324    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13325        use proto::log_message::LogLevel;
13326        use proto::rpc_message;
13327        match log_type {
13328            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13329                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13330                    LogLevel::Error => MessageType::ERROR,
13331                    LogLevel::Warning => MessageType::WARNING,
13332                    LogLevel::Info => MessageType::INFO,
13333                    LogLevel::Log => MessageType::LOG,
13334                },
13335            ),
13336            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13337                verbose_info: trace_message.verbose_info,
13338            },
13339            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13340                received: match rpc_message::Kind::from_i32(message.kind)
13341                    .unwrap_or(rpc_message::Kind::Received)
13342                {
13343                    rpc_message::Kind::Received => true,
13344                    rpc_message::Kind::Sent => false,
13345                },
13346            },
13347        }
13348    }
13349}
13350
13351pub struct WorkspaceRefreshTask {
13352    refresh_tx: mpsc::Sender<()>,
13353    progress_tx: mpsc::Sender<()>,
13354    #[allow(dead_code)]
13355    task: Task<()>,
13356}
13357
13358pub enum LanguageServerState {
13359    Starting {
13360        startup: Task<Option<Arc<LanguageServer>>>,
13361        /// List of language servers that will be added to the workspace once it's initialization completes.
13362        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13363    },
13364
13365    Running {
13366        adapter: Arc<CachedLspAdapter>,
13367        server: Arc<LanguageServer>,
13368        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13369        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13370    },
13371}
13372
13373impl LanguageServerState {
13374    fn add_workspace_folder(&self, uri: Uri) {
13375        match self {
13376            LanguageServerState::Starting {
13377                pending_workspace_folders,
13378                ..
13379            } => {
13380                pending_workspace_folders.lock().insert(uri);
13381            }
13382            LanguageServerState::Running { server, .. } => {
13383                server.add_workspace_folder(uri);
13384            }
13385        }
13386    }
13387    fn _remove_workspace_folder(&self, uri: Uri) {
13388        match self {
13389            LanguageServerState::Starting {
13390                pending_workspace_folders,
13391                ..
13392            } => {
13393                pending_workspace_folders.lock().remove(&uri);
13394            }
13395            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13396        }
13397    }
13398}
13399
13400impl std::fmt::Debug for LanguageServerState {
13401    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13402        match self {
13403            LanguageServerState::Starting { .. } => {
13404                f.debug_struct("LanguageServerState::Starting").finish()
13405            }
13406            LanguageServerState::Running { .. } => {
13407                f.debug_struct("LanguageServerState::Running").finish()
13408            }
13409        }
13410    }
13411}
13412
13413#[derive(Clone, Debug, Serialize)]
13414pub struct LanguageServerProgress {
13415    pub is_disk_based_diagnostics_progress: bool,
13416    pub is_cancellable: bool,
13417    pub title: Option<String>,
13418    pub message: Option<String>,
13419    pub percentage: Option<usize>,
13420    #[serde(skip_serializing)]
13421    pub last_update_at: Instant,
13422}
13423
13424#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13425pub struct DiagnosticSummary {
13426    pub error_count: usize,
13427    pub warning_count: usize,
13428}
13429
13430impl DiagnosticSummary {
13431    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13432        let mut this = Self {
13433            error_count: 0,
13434            warning_count: 0,
13435        };
13436
13437        for entry in diagnostics {
13438            if entry.diagnostic.is_primary {
13439                match entry.diagnostic.severity {
13440                    DiagnosticSeverity::ERROR => this.error_count += 1,
13441                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13442                    _ => {}
13443                }
13444            }
13445        }
13446
13447        this
13448    }
13449
13450    pub fn is_empty(&self) -> bool {
13451        self.error_count == 0 && self.warning_count == 0
13452    }
13453
13454    pub fn to_proto(
13455        self,
13456        language_server_id: LanguageServerId,
13457        path: &RelPath,
13458    ) -> proto::DiagnosticSummary {
13459        proto::DiagnosticSummary {
13460            path: path.to_proto(),
13461            language_server_id: language_server_id.0 as u64,
13462            error_count: self.error_count as u32,
13463            warning_count: self.warning_count as u32,
13464        }
13465    }
13466}
13467
13468#[derive(Clone, Debug)]
13469pub enum CompletionDocumentation {
13470    /// There is no documentation for this completion.
13471    Undocumented,
13472    /// A single line of documentation.
13473    SingleLine(SharedString),
13474    /// Multiple lines of plain text documentation.
13475    MultiLinePlainText(SharedString),
13476    /// Markdown documentation.
13477    MultiLineMarkdown(SharedString),
13478    /// Both single line and multiple lines of plain text documentation.
13479    SingleLineAndMultiLinePlainText {
13480        single_line: SharedString,
13481        plain_text: Option<SharedString>,
13482    },
13483}
13484
13485impl CompletionDocumentation {
13486    #[cfg(any(test, feature = "test-support"))]
13487    pub fn text(&self) -> SharedString {
13488        match self {
13489            CompletionDocumentation::Undocumented => "".into(),
13490            CompletionDocumentation::SingleLine(s) => s.clone(),
13491            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13492            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13493            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13494                single_line.clone()
13495            }
13496        }
13497    }
13498}
13499
13500impl From<lsp::Documentation> for CompletionDocumentation {
13501    fn from(docs: lsp::Documentation) -> Self {
13502        match docs {
13503            lsp::Documentation::String(text) => {
13504                if text.lines().count() <= 1 {
13505                    CompletionDocumentation::SingleLine(text.into())
13506                } else {
13507                    CompletionDocumentation::MultiLinePlainText(text.into())
13508                }
13509            }
13510
13511            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13512                lsp::MarkupKind::PlainText => {
13513                    if value.lines().count() <= 1 {
13514                        CompletionDocumentation::SingleLine(value.into())
13515                    } else {
13516                        CompletionDocumentation::MultiLinePlainText(value.into())
13517                    }
13518                }
13519
13520                lsp::MarkupKind::Markdown => {
13521                    CompletionDocumentation::MultiLineMarkdown(value.into())
13522                }
13523            },
13524        }
13525    }
13526}
13527
13528pub enum ResolvedHint {
13529    Resolved(InlayHint),
13530    Resolving(Shared<Task<()>>),
13531}
13532
13533fn glob_literal_prefix(glob: &Path) -> PathBuf {
13534    glob.components()
13535        .take_while(|component| match component {
13536            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13537            _ => true,
13538        })
13539        .collect()
13540}
13541
13542pub struct SshLspAdapter {
13543    name: LanguageServerName,
13544    binary: LanguageServerBinary,
13545    initialization_options: Option<String>,
13546    code_action_kinds: Option<Vec<CodeActionKind>>,
13547}
13548
13549impl SshLspAdapter {
13550    pub fn new(
13551        name: LanguageServerName,
13552        binary: LanguageServerBinary,
13553        initialization_options: Option<String>,
13554        code_action_kinds: Option<String>,
13555    ) -> Self {
13556        Self {
13557            name,
13558            binary,
13559            initialization_options,
13560            code_action_kinds: code_action_kinds
13561                .as_ref()
13562                .and_then(|c| serde_json::from_str(c).ok()),
13563        }
13564    }
13565}
13566
13567impl LspInstaller for SshLspAdapter {
13568    type BinaryVersion = ();
13569    async fn check_if_user_installed(
13570        &self,
13571        _: &dyn LspAdapterDelegate,
13572        _: Option<Toolchain>,
13573        _: &AsyncApp,
13574    ) -> Option<LanguageServerBinary> {
13575        Some(self.binary.clone())
13576    }
13577
13578    async fn cached_server_binary(
13579        &self,
13580        _: PathBuf,
13581        _: &dyn LspAdapterDelegate,
13582    ) -> Option<LanguageServerBinary> {
13583        None
13584    }
13585
13586    async fn fetch_latest_server_version(
13587        &self,
13588        _: &dyn LspAdapterDelegate,
13589        _: bool,
13590        _: &mut AsyncApp,
13591    ) -> Result<()> {
13592        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13593    }
13594
13595    async fn fetch_server_binary(
13596        &self,
13597        _: (),
13598        _: PathBuf,
13599        _: &dyn LspAdapterDelegate,
13600    ) -> Result<LanguageServerBinary> {
13601        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13602    }
13603}
13604
13605#[async_trait(?Send)]
13606impl LspAdapter for SshLspAdapter {
13607    fn name(&self) -> LanguageServerName {
13608        self.name.clone()
13609    }
13610
13611    async fn initialization_options(
13612        self: Arc<Self>,
13613        _: &Arc<dyn LspAdapterDelegate>,
13614    ) -> Result<Option<serde_json::Value>> {
13615        let Some(options) = &self.initialization_options else {
13616            return Ok(None);
13617        };
13618        let result = serde_json::from_str(options)?;
13619        Ok(result)
13620    }
13621
13622    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13623        self.code_action_kinds.clone()
13624    }
13625}
13626
13627pub fn language_server_settings<'a>(
13628    delegate: &'a dyn LspAdapterDelegate,
13629    language: &LanguageServerName,
13630    cx: &'a App,
13631) -> Option<&'a LspSettings> {
13632    language_server_settings_for(
13633        SettingsLocation {
13634            worktree_id: delegate.worktree_id(),
13635            path: RelPath::empty(),
13636        },
13637        language,
13638        cx,
13639    )
13640}
13641
13642pub fn language_server_settings_for<'a>(
13643    location: SettingsLocation<'a>,
13644    language: &LanguageServerName,
13645    cx: &'a App,
13646) -> Option<&'a LspSettings> {
13647    ProjectSettings::get(Some(location), cx).lsp.get(language)
13648}
13649
13650pub struct LocalLspAdapterDelegate {
13651    lsp_store: WeakEntity<LspStore>,
13652    worktree: worktree::Snapshot,
13653    fs: Arc<dyn Fs>,
13654    http_client: Arc<dyn HttpClient>,
13655    language_registry: Arc<LanguageRegistry>,
13656    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13657}
13658
13659impl LocalLspAdapterDelegate {
13660    pub fn new(
13661        language_registry: Arc<LanguageRegistry>,
13662        environment: &Entity<ProjectEnvironment>,
13663        lsp_store: WeakEntity<LspStore>,
13664        worktree: &Entity<Worktree>,
13665        http_client: Arc<dyn HttpClient>,
13666        fs: Arc<dyn Fs>,
13667        cx: &mut App,
13668    ) -> Arc<Self> {
13669        let load_shell_env_task =
13670            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13671
13672        Arc::new(Self {
13673            lsp_store,
13674            worktree: worktree.read(cx).snapshot(),
13675            fs,
13676            http_client,
13677            language_registry,
13678            load_shell_env_task,
13679        })
13680    }
13681
13682    fn from_local_lsp(
13683        local: &LocalLspStore,
13684        worktree: &Entity<Worktree>,
13685        cx: &mut App,
13686    ) -> Arc<Self> {
13687        Self::new(
13688            local.languages.clone(),
13689            &local.environment,
13690            local.weak.clone(),
13691            worktree,
13692            local.http_client.clone(),
13693            local.fs.clone(),
13694            cx,
13695        )
13696    }
13697}
13698
13699#[async_trait]
13700impl LspAdapterDelegate for LocalLspAdapterDelegate {
13701    fn show_notification(&self, message: &str, cx: &mut App) {
13702        self.lsp_store
13703            .update(cx, |_, cx| {
13704                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13705            })
13706            .ok();
13707    }
13708
13709    fn http_client(&self) -> Arc<dyn HttpClient> {
13710        self.http_client.clone()
13711    }
13712
13713    fn worktree_id(&self) -> WorktreeId {
13714        self.worktree.id()
13715    }
13716
13717    fn worktree_root_path(&self) -> &Path {
13718        self.worktree.abs_path().as_ref()
13719    }
13720
13721    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13722        self.worktree.resolve_executable_path(path)
13723    }
13724
13725    async fn shell_env(&self) -> HashMap<String, String> {
13726        let task = self.load_shell_env_task.clone();
13727        task.await.unwrap_or_default()
13728    }
13729
13730    async fn npm_package_installed_version(
13731        &self,
13732        package_name: &str,
13733    ) -> Result<Option<(PathBuf, String)>> {
13734        let local_package_directory = self.worktree_root_path();
13735        let node_modules_directory = local_package_directory.join("node_modules");
13736
13737        if let Some(version) =
13738            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13739        {
13740            return Ok(Some((node_modules_directory, version)));
13741        }
13742        let Some(npm) = self.which("npm".as_ref()).await else {
13743            log::warn!(
13744                "Failed to find npm executable for {:?}",
13745                local_package_directory
13746            );
13747            return Ok(None);
13748        };
13749
13750        let env = self.shell_env().await;
13751        let output = util::command::new_smol_command(&npm)
13752            .args(["root", "-g"])
13753            .envs(env)
13754            .current_dir(local_package_directory)
13755            .output()
13756            .await?;
13757        let global_node_modules =
13758            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13759
13760        if let Some(version) =
13761            read_package_installed_version(global_node_modules.clone(), package_name).await?
13762        {
13763            return Ok(Some((global_node_modules, version)));
13764        }
13765        return Ok(None);
13766    }
13767
13768    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13769        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13770        if self.fs.is_file(&worktree_abs_path).await {
13771            worktree_abs_path.pop();
13772        }
13773
13774        let env = self.shell_env().await;
13775
13776        let shell_path = env.get("PATH").cloned();
13777
13778        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13779    }
13780
13781    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13782        let mut working_dir = self.worktree_root_path().to_path_buf();
13783        if self.fs.is_file(&working_dir).await {
13784            working_dir.pop();
13785        }
13786        let output = util::command::new_smol_command(&command.path)
13787            .args(command.arguments)
13788            .envs(command.env.clone().unwrap_or_default())
13789            .current_dir(working_dir)
13790            .output()
13791            .await?;
13792
13793        anyhow::ensure!(
13794            output.status.success(),
13795            "{}, stdout: {:?}, stderr: {:?}",
13796            output.status,
13797            String::from_utf8_lossy(&output.stdout),
13798            String::from_utf8_lossy(&output.stderr)
13799        );
13800        Ok(())
13801    }
13802
13803    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13804        self.language_registry
13805            .update_lsp_binary_status(server_name, status);
13806    }
13807
13808    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13809        self.language_registry
13810            .all_lsp_adapters()
13811            .into_iter()
13812            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13813            .collect()
13814    }
13815
13816    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13817        let dir = self.language_registry.language_server_download_dir(name)?;
13818
13819        if !dir.exists() {
13820            smol::fs::create_dir_all(&dir)
13821                .await
13822                .context("failed to create container directory")
13823                .log_err()?;
13824        }
13825
13826        Some(dir)
13827    }
13828
13829    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13830        let entry = self
13831            .worktree
13832            .entry_for_path(path)
13833            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13834        let abs_path = self.worktree.absolutize(&entry.path);
13835        self.fs.load(&abs_path).await
13836    }
13837}
13838
13839async fn populate_labels_for_symbols(
13840    symbols: Vec<CoreSymbol>,
13841    language_registry: &Arc<LanguageRegistry>,
13842    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13843    output: &mut Vec<Symbol>,
13844) {
13845    #[allow(clippy::mutable_key_type)]
13846    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13847
13848    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13849    for symbol in symbols {
13850        let Some(file_name) = symbol.path.file_name() else {
13851            continue;
13852        };
13853        let language = language_registry
13854            .load_language_for_file_path(Path::new(file_name))
13855            .await
13856            .ok()
13857            .or_else(|| {
13858                unknown_paths.insert(file_name.into());
13859                None
13860            });
13861        symbols_by_language
13862            .entry(language)
13863            .or_default()
13864            .push(symbol);
13865    }
13866
13867    for unknown_path in unknown_paths {
13868        log::info!("no language found for symbol in file {unknown_path:?}");
13869    }
13870
13871    let mut label_params = Vec::new();
13872    for (language, mut symbols) in symbols_by_language {
13873        label_params.clear();
13874        label_params.extend(
13875            symbols
13876                .iter_mut()
13877                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13878        );
13879
13880        let mut labels = Vec::new();
13881        if let Some(language) = language {
13882            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13883                language_registry
13884                    .lsp_adapters(&language.name())
13885                    .first()
13886                    .cloned()
13887            });
13888            if let Some(lsp_adapter) = lsp_adapter {
13889                labels = lsp_adapter
13890                    .labels_for_symbols(&label_params, &language)
13891                    .await
13892                    .log_err()
13893                    .unwrap_or_default();
13894            }
13895        }
13896
13897        for ((symbol, (name, _)), label) in symbols
13898            .into_iter()
13899            .zip(label_params.drain(..))
13900            .zip(labels.into_iter().chain(iter::repeat(None)))
13901        {
13902            output.push(Symbol {
13903                language_server_name: symbol.language_server_name,
13904                source_worktree_id: symbol.source_worktree_id,
13905                source_language_server_id: symbol.source_language_server_id,
13906                path: symbol.path,
13907                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13908                name,
13909                kind: symbol.kind,
13910                range: symbol.range,
13911            });
13912        }
13913    }
13914}
13915
13916fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13917    match server.capabilities().text_document_sync.as_ref()? {
13918        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13919            // Server wants didSave but didn't specify includeText.
13920            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13921            // Server doesn't want didSave at all.
13922            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13923            // Server provided SaveOptions.
13924            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13925                Some(save_options.include_text.unwrap_or(false))
13926            }
13927        },
13928        // We do not have any save info. Kind affects didChange only.
13929        lsp::TextDocumentSyncCapability::Kind(_) => None,
13930    }
13931}
13932
13933/// Completion items are displayed in a `UniformList`.
13934/// Usually, those items are single-line strings, but in LSP responses,
13935/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13936/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13937/// 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,
13938/// breaking the completions menu presentation.
13939///
13940/// 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.
13941fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13942    let mut new_text = String::with_capacity(label.text.len());
13943    let mut offset_map = vec![0; label.text.len() + 1];
13944    let mut last_char_was_space = false;
13945    let mut new_idx = 0;
13946    let chars = label.text.char_indices().fuse();
13947    let mut newlines_removed = false;
13948
13949    for (idx, c) in chars {
13950        offset_map[idx] = new_idx;
13951
13952        match c {
13953            '\n' if last_char_was_space => {
13954                newlines_removed = true;
13955            }
13956            '\t' | ' ' if last_char_was_space => {}
13957            '\n' if !last_char_was_space => {
13958                new_text.push(' ');
13959                new_idx += 1;
13960                last_char_was_space = true;
13961                newlines_removed = true;
13962            }
13963            ' ' | '\t' => {
13964                new_text.push(' ');
13965                new_idx += 1;
13966                last_char_was_space = true;
13967            }
13968            _ => {
13969                new_text.push(c);
13970                new_idx += c.len_utf8();
13971                last_char_was_space = false;
13972            }
13973        }
13974    }
13975    offset_map[label.text.len()] = new_idx;
13976
13977    // Only modify the label if newlines were removed.
13978    if !newlines_removed {
13979        return;
13980    }
13981
13982    let last_index = new_idx;
13983    let mut run_ranges_errors = Vec::new();
13984    label.runs.retain_mut(|(range, _)| {
13985        match offset_map.get(range.start) {
13986            Some(&start) => range.start = start,
13987            None => {
13988                run_ranges_errors.push(range.clone());
13989                return false;
13990            }
13991        }
13992
13993        match offset_map.get(range.end) {
13994            Some(&end) => range.end = end,
13995            None => {
13996                run_ranges_errors.push(range.clone());
13997                range.end = last_index;
13998            }
13999        }
14000        true
14001    });
14002    if !run_ranges_errors.is_empty() {
14003        log::error!(
14004            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14005            label.text
14006        );
14007    }
14008
14009    let mut wrong_filter_range = None;
14010    if label.filter_range == (0..label.text.len()) {
14011        label.filter_range = 0..new_text.len();
14012    } else {
14013        let mut original_filter_range = Some(label.filter_range.clone());
14014        match offset_map.get(label.filter_range.start) {
14015            Some(&start) => label.filter_range.start = start,
14016            None => {
14017                wrong_filter_range = original_filter_range.take();
14018                label.filter_range.start = last_index;
14019            }
14020        }
14021
14022        match offset_map.get(label.filter_range.end) {
14023            Some(&end) => label.filter_range.end = end,
14024            None => {
14025                wrong_filter_range = original_filter_range.take();
14026                label.filter_range.end = last_index;
14027            }
14028        }
14029    }
14030    if let Some(wrong_filter_range) = wrong_filter_range {
14031        log::error!(
14032            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14033            label.text
14034        );
14035    }
14036
14037    label.text = new_text;
14038}
14039
14040#[cfg(test)]
14041mod tests {
14042    use language::HighlightId;
14043
14044    use super::*;
14045
14046    #[test]
14047    fn test_glob_literal_prefix() {
14048        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14049        assert_eq!(
14050            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14051            Path::new("node_modules")
14052        );
14053        assert_eq!(
14054            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14055            Path::new("foo")
14056        );
14057        assert_eq!(
14058            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14059            Path::new("foo/bar/baz.js")
14060        );
14061
14062        #[cfg(target_os = "windows")]
14063        {
14064            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14065            assert_eq!(
14066                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14067                Path::new("node_modules")
14068            );
14069            assert_eq!(
14070                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14071                Path::new("foo")
14072            );
14073            assert_eq!(
14074                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14075                Path::new("foo/bar/baz.js")
14076            );
14077        }
14078    }
14079
14080    #[test]
14081    fn test_multi_len_chars_normalization() {
14082        let mut label = CodeLabel::new(
14083            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14084            0..6,
14085            vec![(0..6, HighlightId(1))],
14086        );
14087        ensure_uniform_list_compatible_label(&mut label);
14088        assert_eq!(
14089            label,
14090            CodeLabel::new(
14091                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14092                0..6,
14093                vec![(0..6, HighlightId(1))],
14094            )
14095        );
14096    }
14097}